2026-07-11 21:21:29 +03:30
"use client" ;
import { type SVGProps , useEffect , useId , useState } from "react" ;
import type { CarouselApi } from "@/components/ui/carousel" ;
import {
Carousel ,
CarouselContent ,
CarouselItem ,
} from "@/components/ui/carousel" ;
import { cn } from "@/lib/utils" ;
const TESTIMONIALS = [
{
id : 1 ,
quote :
2026-07-21 19:25:31 +03:30
"سامانه مدیریت ارتباط با مشتری یکپارچه، مسیریابی لید هوشمند و داشبورد قیف شفاف دارد. درک عمیق از عملیات فروش برای مقیاسدهی درآمد ما حیاتی بوده." ,
2026-07-11 21:21:29 +03:30
author : "علی رحمانی" ,
role : "بنیانگذار، میزبانی ابری" ,
company : "Vercel" ,
logo : "/block-media/shadcnblocks/block/logos/vercel-wordmark.svg" ,
},
{
id : 2 ,
quote :
2026-07-15 20:22:14 +02:00
"اتوماسیون بازاریابی و انتقال یکپارچه به فروش، عملیات درآمد ما را متحول کرد. انعطاف و سرعت پلتفرم به ما امکان داده قیف را کارآمد مقیاس دهیم." ,
2026-07-11 21:21:29 +03:30
author : "مازیار رضایی" ,
2026-07-15 20:22:14 +02:00
role : "مدیر عملیات درآمد، Astro" ,
2026-07-11 21:21:29 +03:30
company : "Astro" ,
logo : "/block-media/shadcnblocks/block/logos/astro-wordmark.svg" ,
},
{
id : 3 ,
quote :
2026-07-21 19:25:31 +03:30
"از انتظارات فراتر رفت؛ یکپارچهسازی سامانه مدیریت ارتباط با مشتری روان و پشتیبانی فروش استثنایی. نمرهدهی لید و گزارش قیف در مسیر رشد ما نقش کلیدی داشته." ,
2026-07-11 21:21:29 +03:30
author : "سارا احمدی" ,
2026-07-15 20:22:14 +02:00
role : "مدیر فروش، طراحی رابط" ,
2026-07-11 21:21:29 +03:30
company : "Figma" ,
logo : "/block-media/shadcnblocks/block/logos/figma-wordmark.svg" ,
},
{
id : 4 ,
quote :
2026-07-15 20:22:14 +02:00
"نحوه مدیریت حسابهای کلیدی و تمدید قرارداد را متحول کرد. دید بلادرنگ از فرصتها، انعطاف ساخت فرایندهای فروش سفارشی را به ما داده." ,
2026-07-11 21:21:29 +03:30
author : "کاوه مرادی" ,
role : "مدیرعامل، پایگاه داده ابری" ,
company : "Supabase" ,
logo : "/block-media/shadcnblocks/block/logos/supabase-wordmark.svg" ,
},
{
id : 5 ,
quote :
2026-07-15 20:22:14 +02:00
"ترکیب اتوماسیون کمپین و داشبورد فروش بلادرنگ، هماهنگی بازاریابی و فروش را متحول کرد. سرعت پاسخ به لید و دقت پیشبینی درآمد بیرقیب است." ,
2026-07-11 21:21:29 +03:30
author : "نیلوفر حسینی" ,
2026-07-15 20:22:14 +02:00
role : "مدیر بازاریابی، ری یو آی" ,
2026-07-11 21:21:29 +03:30
company : "Shadcn/ui" ,
logo : "/block-media/shadcnblocks/block/logos/shadcn-ui-wordmark.svg" ,
},
];
interface Testimonial26Props {
className? : string ;
}
const Testimonial26 = ({ className } : Testimonial26Props ) => {
const [ api , setApi ] = useState < CarouselApi >();
const [ current , setCurrent ] = useState ( 0 );
useEffect (() => {
if ( ! api ) {
return ;
}
api . on ( "select" , () => {
setCurrent ( api . selectedScrollSnap ());
});
}, [ api ]);
return (
< section dir = "rtl" lang = "fa" className = { cn ( "relative py-32" , className )}>
< div className = "container max-w-4xl" >
< Carousel
opts = {{
align : "center" ,
loop : true ,
}}
setApi = { setApi }
>
< CarouselContent >
{ TESTIMONIALS . map (( testimonial ) => (
< CarouselItem
key = { testimonial . id }
className = "flex cursor-grab flex-col gap-6 lg:gap-8"
>
< blockquote className = "font-hubot-sans pointer-events-none text-xl leading-relaxed font-semibold tracking-tight text-balance select-none md:text-3xl lg:text-xl" >
{ testimonial . quote }
</ blockquote >
< div className = "flex items-center gap-4" >
{ testimonial . logo && (
< div className = "relative h-8 w-24" >
< img
src = { testimonial . logo }
alt = { `لوگوی ${ testimonial . company } ` }
className = "object-contain dark:invert"
aria-hidden = "true"
/>
</ div >
)}
< div className = "h-8 w-px bg-border" aria-hidden = "true" />
< div >
< cite className = "font-semibold not-italic" >
{ testimonial . author }
</ cite >
< p className = "text-sm font-medium text-muted-foreground" >
{ testimonial . role }
</ p >
</ div >
</ div >
</ CarouselItem >
))}
</ CarouselContent >
</ Carousel >
< div
className = "mt-10 flex gap-2 lg:mt-16"
role = "group"
aria-label = "ناوبری نظرات"
>
{ TESTIMONIALS . map (( _ , index ) => (
< button
key = { index }
type = "button"
className = { cn (
"size-4 cursor-pointer rounded-full transition-colors duration-300" ,
index === current
? "bg-muted-foreground"
: "bg-muted-foreground/20 hover:bg-muted-foreground/50" ,
)}
onClick = {() => api ? . scrollTo ( index )}
aria-label = { `رفتن به نظر ${ index + 1 } ` }
aria-current = { index === current ? "true" : undefined }
/>
))}
</ div >
</ div >
< div className = "absolute inset-x-0 top-16 isolate z-[-1] h-[300px] md:top-28 lg:top-32" >
< div className = "absolute inset-x-0 bottom-0 z-10 h-40 bg-linear-to-t from-background via-background/40 to-transparent" />
< div className = "absolute inset-x-0 top-0 z-10 h-40 bg-linear-to-b from-background via-background/40 to-transparent" />
< PlusSigns className = "size-full text-foreground/5" />
</ div >
</ section >
);
};
interface PlusSignsProps extends SVGProps < SVGSVGElement > {
className? : string ;
}
const PlusSigns = ({ className , ... props } : PlusSignsProps ) => {
const GAP = 18 ;
const STROKE_WIDTH = 1 ;
const PLUS_SIZE = 4 ;
const id = useId ();
const patternId = `plus-pattern- ${ id } ` ;
return (
< svg width = { GAP * 2 } height = { GAP * 2 } className = { className } { ...props }>
< defs >
< pattern
id = { patternId }
x = "0"
y = "0"
width = { GAP }
height = { GAP }
patternUnits = "userSpaceOnUse"
>
< line
x1 = { GAP / 2 }
y1 = {( GAP - PLUS_SIZE ) / 2 }
x2 = { GAP / 2 }
y2 = {( GAP + PLUS_SIZE ) / 2 }
stroke = "currentColor"
strokeWidth = { STROKE_WIDTH }
/>
< line
x1 = {( GAP - PLUS_SIZE ) / 2 }
y1 = { GAP / 2 }
x2 = {( GAP + PLUS_SIZE ) / 2 }
y2 = { GAP / 2 }
stroke = "currentColor"
strokeWidth = { STROKE_WIDTH }
/>
</ pattern >
</ defs >
< rect width = "100%" height = "100%" fill = { `url(# ${ patternId } )` } />
</ svg >
);
};
export { Testimonial26 };