cambios
This commit is contained in:
1 parent
794a659369
commit
5f99b65611
349 files changed
+32252
-2180
No files matched your search
@@ -0,0 +1,121 @@
|
||||
"use client";
|
||||
import { useState, useEffect } from "react";
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
import Loader from '@/app/(landing)/components/Loader';
|
||||
import { useTestimonials } from '@/app/(landing)/home/services/testimonials';
|
||||
import type { ThemeProps } from '@/app/(landing)/types/ui';
|
||||
|
||||
export const Testimonial = ({ isNavyBg }: ThemeProps) => {
|
||||
const { data, isLoading } = useTestimonials();
|
||||
const [current, setCurrent] = useState(0);
|
||||
|
||||
const testimonials = data ?? [];
|
||||
|
||||
useEffect(() => {
|
||||
if (testimonials.length < 2) return;
|
||||
const t = setInterval(
|
||||
() => setCurrent((i) => (i + 1) % testimonials.length),
|
||||
6000,
|
||||
);
|
||||
return () => clearInterval(t);
|
||||
}, [testimonials.length]);
|
||||
|
||||
const item = testimonials[current];
|
||||
const bg = isNavyBg ? "var(--background)" : "#f9f9f7";
|
||||
const border = isNavyBg ? "rgba(255,255,255,0.08)" : "rgba(0,0,0,0.08)";
|
||||
const sub = isNavyBg ? "rgba(255,255,255,0.45)" : "#6a6866";
|
||||
const text = isNavyBg ? "var(--foreground)" : "#0a0a0a";
|
||||
|
||||
if (!isLoading && testimonials.length === 0) return null; // sección se oculta si no hay testimonios
|
||||
|
||||
return (
|
||||
<section
|
||||
aria-label="Testimonios de clientes"
|
||||
style={{ background: bg }}
|
||||
className="px-8 py-24 md:px-14 transition-colors duration-500"
|
||||
>
|
||||
<div className="mx-auto max-w-4xl">
|
||||
<div
|
||||
aria-hidden="true"
|
||||
className="mx-auto mb-8 flex h-12 w-12 items-center justify-center rounded-full"
|
||||
style={{ background: "rgba(59,130,246,0.1)" }}
|
||||
>
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="#3b82f6">
|
||||
<path d="M3 21c3 0 7-1 7-8V5c0-1.25-.756-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V20c0 1 0 1 1 1z" />
|
||||
<path d="M15 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3c0 1 0 1 1 1z" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
{isLoading ? (
|
||||
<Loader className="py-12" />
|
||||
) : (
|
||||
<>
|
||||
<AnimatePresence mode="wait">
|
||||
<motion.div
|
||||
key={current}
|
||||
initial={{ opacity: 0, y: 16 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
exit={{ opacity: 0, y: -16 }}
|
||||
transition={{ duration: 0.5, ease: [0.22, 1, 0.36, 1] }}
|
||||
className="text-center"
|
||||
>
|
||||
<blockquote>
|
||||
<p
|
||||
className="font-display font-bold leading-snug"
|
||||
style={{
|
||||
fontSize: "clamp(1.25rem, 2.5vw, 1.75rem)",
|
||||
color: text,
|
||||
letterSpacing: "-0.02em",
|
||||
maxWidth: "36ch",
|
||||
margin: "0 auto 2.5rem",
|
||||
}}
|
||||
>
|
||||
"{item.quote}"
|
||||
</p>
|
||||
</blockquote>
|
||||
<div className="flex flex-col items-center gap-1">
|
||||
{item.author && (
|
||||
<p
|
||||
className="font-display font-bold"
|
||||
style={{ color: text, fontSize: "0.95rem" }}
|
||||
>
|
||||
{item.author}
|
||||
</p>
|
||||
)}
|
||||
<p
|
||||
className="text-sm font-semibold"
|
||||
style={{ color: "#3b82f6" }}
|
||||
>
|
||||
{item.company}
|
||||
</p>
|
||||
</div>
|
||||
</motion.div>
|
||||
</AnimatePresence>
|
||||
|
||||
{testimonials.length > 1 && (
|
||||
<div className="flex justify-center gap-2 mt-10">
|
||||
{testimonials.map((_, i) => (
|
||||
<button
|
||||
key={i}
|
||||
onClick={() => setCurrent(i)}
|
||||
style={{
|
||||
width: i === current ? 24 : 8,
|
||||
height: 8,
|
||||
borderRadius: 20,
|
||||
background: i === current ? "#3b82f6" : sub,
|
||||
border: "none",
|
||||
cursor: "pointer",
|
||||
padding: 0,
|
||||
transition: "width 300ms, background 300ms",
|
||||
}}
|
||||
aria-label={`Testimonio ${i + 1}`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
Reference in new issue
Block a user