This commit is contained in:
mr.sabri
2026-07-27 12:56:06 +03:30
parent d5488386ff
commit 1cea5b78cb
45 changed files with 1406 additions and 936 deletions
+3 -3
View File
@@ -39,7 +39,7 @@ export const defaultEntries: ChangelogEntry[] = [
"فیلتر بهتر بر اساس مرحله قیف، مالک و منبع", "فیلتر بهتر بر اساس مرحله قیف، مالک و منبع",
], ],
image: image:
"/block-media/shadcnblocks/block/placeholder-aspect-video-1.svg", "/block-media/shadcnblocks/block/placeholder-1.svg",
button: { button: {
url: "https://ShadcnBlocks", url: "https://ShadcnBlocks",
text: "مشاهده جزئیات", text: "مشاهده جزئیات",
@@ -71,7 +71,7 @@ export const defaultEntries: ChangelogEntry[] = [
"افزودن قابلیت وارد کردن داده‌ها", "افزودن قابلیت وارد کردن داده‌ها",
], ],
image: image:
"/block-media/shadcnblocks/block/placeholder-aspect-video-1.svg", "/block-media/shadcnblocks/block/placeholder-1.svg",
}, },
{ {
version: "نسخه ۱۰.۰", version: "نسخه ۱۰.۰",
@@ -80,7 +80,7 @@ export const defaultEntries: ChangelogEntry[] = [
description: description:
"اولین نسخه پلتفرم با امکانات مدیریت پروژه، همکاری تیمی و پیگیری وظایف منتشر شد و از این پس به‌صورت مستمر توسعه خواهد یافت.", "اولین نسخه پلتفرم با امکانات مدیریت پروژه، همکاری تیمی و پیگیری وظایف منتشر شد و از این پس به‌صورت مستمر توسعه خواهد یافت.",
image: image:
"/block-media/shadcnblocks/block/placeholder-aspect-video-1.svg", "/block-media/shadcnblocks/block/placeholder-1.svg",
button: { button: {
url: "https://ShadcnBlocks", url: "https://ShadcnBlocks",
text: "مشاهده جزئیات", text: "مشاهده جزئیات",
+2 -2
View File
@@ -215,7 +215,7 @@ export const defaultChangelogData: ChangelogEntry[] = [
"فیلتر بهتر بر اساس مرحله قیف، مالک و منبع", "فیلتر بهتر بر اساس مرحله قیف، مالک و منبع",
], ],
image: image:
"/block-media/shadcnblocks/block/placeholder-aspect-video-1.svg", "/block-media/shadcnblocks/block/placeholder-1.svg",
}, },
{ {
version: "نسخه ۱۲۵", version: "نسخه ۱۲۵",
@@ -230,6 +230,6 @@ export const defaultChangelogData: ChangelogEntry[] = [
"احراز هویت بیومتریک برای امنیت بیشتر", "احراز هویت بیومتریک برای امنیت بیشتر",
], ],
image: image:
"/block-media/shadcnblocks/block/placeholder-aspect-video-1.svg", "/block-media/shadcnblocks/block/placeholder-1.svg",
}, },
]; ];
+2 -2
View File
@@ -44,7 +44,7 @@ const Feature101 = ({ className }: Feature101Props) => {
</p> </p>
</div> </div>
<img <img
src="/block-media/shadcnblocks/block/placeholder-aspect-video-1.svg" src="/block-media/shadcnblocks/block/placeholder-1.svg"
alt="دستیار هوش مصنوعی" alt="دستیار هوش مصنوعی"
className="ms-auto max-h-80 w-full rounded-lg object-cover transition-transform duration-300 hover:-translate-y-3 sm:w-11/12" className="ms-auto max-h-80 w-full rounded-lg object-cover transition-transform duration-300 hover:-translate-y-3 sm:w-11/12"
/> />
@@ -69,7 +69,7 @@ const Feature101 = ({ className }: Feature101Props) => {
</p> </p>
</div> </div>
<img <img
src="/block-media/shadcnblocks/block/placeholder-aspect-video-1.svg" src="/block-media/shadcnblocks/block/placeholder-1.svg"
alt="پیشنهادهای هوشمند" alt="پیشنهادهای هوشمند"
className="h-full min-h-0 rounded-lg object-cover transition-transform duration-300 hover:-translate-y-3" className="h-full min-h-0 rounded-lg object-cover transition-transform duration-300 hover:-translate-y-3"
/> />
+56 -33
View File
@@ -7,8 +7,6 @@ const steps = [
"برنامه تیم را هماهنگ کنید و تداخل وظایف را کاهش دهید.", "برنامه تیم را هماهنگ کنید و تداخل وظایف را کاهش دهید.",
image: "/block-media/shadcnblocks/block/placeholder-1.svg", image: "/block-media/shadcnblocks/block/placeholder-1.svg",
alt: "تقویم تیم", alt: "تقویم تیم",
imageClassName:
"z-10 aspect-video w-full rounded-xl border object-cover min-[960px]:max-h-56 min-[960px]:w-auto",
}, },
{ {
title: "چک‌لیست تحویل", title: "چک‌لیست تحویل",
@@ -16,8 +14,6 @@ const steps = [
"نسخه درست فایل همیشه در دسترس همه اعضا باشد.", "نسخه درست فایل همیشه در دسترس همه اعضا باشد.",
image: "/block-media/shadcnblocks/block/placeholder-2.svg", image: "/block-media/shadcnblocks/block/placeholder-2.svg",
alt: "فضای همکاری تیمی", alt: "فضای همکاری تیمی",
imageClassName:
"z-10 max-h-56 w-full rounded-xl border object-cover min-[960px]:aspect-video min-[960px]:w-auto",
}, },
{ {
title: "گزارش پیشرفت", title: "گزارش پیشرفت",
@@ -25,19 +21,23 @@ const steps = [
"بحث را کنار هر تسک نگه دارید تا تصمیم‌ها گم نشود.", "بحث را کنار هر تسک نگه دارید تا تصمیم‌ها گم نشود.",
image: "/block-media/shadcnblocks/block/placeholder-3.svg", image: "/block-media/shadcnblocks/block/placeholder-3.svg",
alt: "برد مدیریت پروژه", alt: "برد مدیریت پروژه",
imageClassName:
"z-10 max-h-56 w-full rounded-xl border object-cover min-[960px]:aspect-video min-[960px]:w-auto",
}, },
]; ];
function StepConnector({ index }: { index: number }) { function StepNumber({ index }: { index: number }) {
if (index === 0) {
return ( return (
<div className="flex flex-col items-center justify-between gap-1"> <span className="relative z-10 flex size-10 shrink-0 items-center justify-center rounded-full border bg-background font-mono text-lg">
<span className="h-20 shrink-0" />
<span className="flex size-10 shrink-0 items-center justify-center rounded-full border bg-muted/50 font-mono text-lg">
{(index + 1).toLocaleString("fa-IR")} {(index + 1).toLocaleString("fa-IR")}
</span> </span>
);
}
function DesktopStepConnector({ index }: { index: number }) {
if (index === 0) {
return (
<div className="hidden flex-col items-center justify-between gap-1 min-[960px]:flex">
<span className="h-20 shrink-0" />
<StepNumber index={index} />
<span className="h-20 w-[3px] shrink-0 bg-linear-to-b from-transparent to-primary opacity-70" /> <span className="h-20 w-[3px] shrink-0 bg-linear-to-b from-transparent to-primary opacity-70" />
</div> </div>
); );
@@ -45,24 +45,20 @@ function StepConnector({ index }: { index: number }) {
if (index === steps.length - 1) { if (index === steps.length - 1) {
return ( return (
<div className="flex flex-col items-center justify-between gap-1"> <div className="hidden flex-col items-center justify-between gap-1 min-[960px]:flex">
<span className="h-20 w-[3px] shrink-0 bg-linear-to-t from-transparent to-primary opacity-70" /> <span className="h-20 w-[3px] shrink-0 bg-linear-to-t from-transparent to-primary opacity-70" />
<span className="flex size-10 shrink-0 items-center justify-center rounded-full border bg-muted/50 font-mono text-lg"> <StepNumber index={index} />
{(index + 1).toLocaleString("fa-IR")}
</span>
<span className="h-20 shrink-0" /> <span className="h-20 shrink-0" />
</div> </div>
); );
} }
return ( return (
<div className="relative flex flex-col items-center justify-between gap-1"> <div className="relative hidden flex-col items-center justify-between gap-1 min-[960px]:flex">
<span className="absolute -top-8 mx-auto h-8 w-[3px] shrink-0 bg-primary opacity-70" /> <span className="absolute -top-8 mx-auto h-8 w-[3px] shrink-0 bg-primary opacity-70" />
<span className="absolute -bottom-8 mx-auto h-8 w-[3px] shrink-0 bg-primary opacity-70" /> <span className="absolute -bottom-8 mx-auto h-8 w-[3px] shrink-0 bg-primary opacity-70" />
<span className="h-20 w-[3px] shrink-0 bg-primary opacity-70" /> <span className="h-20 w-[3px] shrink-0 bg-primary opacity-70" />
<span className="flex size-10 shrink-0 items-center justify-center rounded-full border bg-muted/50 font-mono text-lg"> <StepNumber index={index} />
{(index + 1).toLocaleString("fa-IR")}
</span>
<span className="h-20 w-[3px] shrink-0 bg-primary opacity-70" /> <span className="h-20 w-[3px] shrink-0 bg-primary opacity-70" />
</div> </div>
); );
@@ -74,35 +70,62 @@ interface Feature102Props {
const Feature102 = ({ className }: Feature102Props) => { const Feature102 = ({ className }: Feature102Props) => {
return ( return (
<section dir="rtl" lang="fa" className={cn("py-32", className)}> <section
<div className="container"> dir="rtl"
<div className="mx-auto flex max-w-3xl flex-col justify-center gap-7 md:text-center"> lang="fa"
<h2 className="text-xl md:text-xl">همکاری از راه دور را ساده کنید</h2> className={cn(
<p className="text-sm text-muted-foreground md:text-base"> "relative w-full max-w-full overflow-hidden py-32",
className,
)}
>
<div className="container min-w-0 max-w-full">
<div className="mx-auto flex w-full min-w-0 max-w-3xl flex-col justify-center gap-7 md:text-center">
<h2 className="max-w-full text-xl text-balance break-words md:text-xl">
همکاری از راه دور را ساده کنید
</h2>
<p className="max-w-full text-sm text-pretty break-words text-muted-foreground md:text-base">
هر عضو بداند چه زمانی چه کاری دارد هر عضو بداند چه زمانی چه کاری دارد
</p> </p>
</div> </div>
<div className="mx-auto mt-14 flex max-w-5xl flex-col gap-4 lg:px-16">
<div className="mx-auto mt-14 flex w-full min-w-0 max-w-5xl flex-col gap-10 min-[960px]:gap-4 lg:px-16">
{steps.map((step, index) => ( {steps.map((step, index) => (
<div <div
key={step.title} key={step.title}
className="flex flex-col items-center justify-between min-[960px]:flex-row min-[960px]:gap-10" className="relative flex w-full min-w-0 gap-4 min-[960px]:items-center min-[960px]:gap-10"
> >
<div className="flex gap-4 min-[960px]:max-w-md"> {index < steps.length - 1 ? (
<StepConnector index={index} /> <span
<div className="flex flex-col justify-center gap-5 px-0 min-[960px]:gap-6 min-[960px]:px-4 min-[960px]:py-4"> aria-hidden
<h3 className="text-xl min-[960px]:text-xl">{step.title}</h3> className="absolute top-10 bottom-[-2.5rem] start-0 flex w-10 justify-center min-[960px]:hidden"
<p className="text-sm text-muted-foreground min-[960px]:text-base"> >
<span className="w-[3px] bg-primary/70" />
</span>
) : null}
<div className="relative z-10 flex shrink-0 flex-col items-center">
<div className="min-[960px]:hidden">
<StepNumber index={index} />
</div>
<DesktopStepConnector index={index} />
</div>
<div className="flex min-w-0 flex-1 flex-col gap-5 min-[960px]:flex-row min-[960px]:items-center min-[960px]:justify-between min-[960px]:gap-10">
<div className="flex min-w-0 flex-col justify-center gap-5 min-[960px]:max-w-md min-[960px]:gap-6 min-[960px]:px-4 min-[960px]:py-4">
<h3 className="text-xl break-words min-[960px]:text-xl">
{step.title}
</h3>
<p className="text-sm text-pretty break-words text-muted-foreground min-[960px]:text-base">
{step.description} {step.description}
</p> </p>
</div> </div>
</div>
<img <img
src={step.image} src={step.image}
alt={step.alt} alt={step.alt}
className={step.imageClassName} className="relative z-10 aspect-video w-full max-w-full rounded-xl border object-cover min-[960px]:max-h-56 min-[960px]:w-auto min-[960px]:shrink-0"
/> />
</div> </div>
</div>
))} ))}
</div> </div>
</div> </div>
+29 -19
View File
@@ -60,55 +60,65 @@ interface Feature105Props {
const Feature105 = ({ className }: Feature105Props) => { const Feature105 = ({ className }: Feature105Props) => {
return ( return (
<section dir="rtl" lang="fa" className={cn("py-32", className)}> <section
<div className="container"> dir="rtl"
<div className="mx-auto flex max-w-3xl flex-col items-center gap-4"> lang="fa"
className={cn(
"relative w-full max-w-full overflow-hidden py-32",
className,
)}
>
<div className="container min-w-0 max-w-full">
<div className="mx-auto flex w-full min-w-0 max-w-3xl flex-col items-center gap-4">
<Badge <Badge
variant="outline" variant="outline"
className="flex items-center gap-1 px-2.5 py-1.5 text-sm" className="flex items-center gap-1 px-2.5 py-1.5 text-sm"
> >
<Flag className="h-auto w-4" /> <Flag className="size-4 shrink-0" />
ERP ERP
</Badge> </Badge>
<h2 className="text-center text-3xl font-semibold tracking-tight text-balance lg:text-xl"> <h2 className="max-w-full text-center text-3xl font-semibold tracking-tight text-balance break-words lg:text-xl">
عملیات سازمان را یکپارچه کنید عملیات سازمان را یکپارچه کنید
</h2> </h2>
<p className="text-center text-pretty text-muted-foreground lg:text-lg"> <p className="max-w-full text-center text-pretty break-words text-muted-foreground lg:text-lg">
گزارش‌های یکپارچه نشان می‌دهد کدام بخش بیشترین تأثیر را روی سودآوری دارد. گزارش‌های یکپارچه نشان می‌دهد کدام بخش بیشترین تأثیر را روی سودآوری
دارد.
</p> </p>
</div> </div>
<div className="mx-auto mt-14 max-w-7xl"> <div className="mx-auto mt-14 w-full min-w-0 max-w-7xl">
<Tabs defaultValue={DEFAULT_TAB}> <Tabs defaultValue={DEFAULT_TAB} className="w-full min-w-0">
<div className="max-w-[100vw-4rem] overflow-x-auto overflow-y-hidden"> <div className="w-full min-w-0 max-w-full overflow-x-auto overflow-y-hidden">
<TabsList <TabsList
variant="line" variant="line"
className="!h-auto w-full justify-start gap-0 rounded-none border-b border-border bg-transparent p-0" className="!h-auto w-max min-w-full justify-start gap-0 rounded-none border-b border-border bg-transparent p-0"
> >
{TABS.map(({ icon: Icon, label }, index) => ( {TABS.map(({ icon: Icon, label }, index) => (
<TabsTrigger <TabsTrigger
key={label} key={`${label}-${index}`}
value={index.toString()} value={index.toString()}
className="group -mb-px flex flex-col items-center justify-start gap-1.5 rounded-none border-0 bg-transparent px-1 pb-3.5 shadow-none ring-0 data-[state=active]:after:opacity-100" className="group -mb-px flex shrink-0 flex-col items-center justify-start gap-1.5 rounded-none border-0 bg-transparent px-1 pb-3.5 shadow-none ring-0 data-[state=active]:after:opacity-100"
> >
<span className="flex size-12 items-center justify-center rounded-md bg-muted transition-colors duration-300 group-data-[state=active]:bg-primary group-data-[state=active]:text-primary-foreground"> <span className="flex size-12 shrink-0 items-center justify-center rounded-md bg-muted transition-colors duration-300 group-data-[state=active]:bg-primary group-data-[state=active]:text-primary-foreground">
<Icon className="size-6" /> <Icon className="size-6" />
</span> </span>
<p className="text-sm text-muted-foreground">{label}</p> <p className="text-sm whitespace-nowrap text-muted-foreground">
{label}
</p>
</TabsTrigger> </TabsTrigger>
))} ))}
</TabsList> </TabsList>
</div> </div>
<div className="mt-5"> <div className="mt-5 w-full min-w-0">
{TABS.map(({ image, label }, index) => ( {TABS.map(({ image, label }, index) => (
<TabsContent <TabsContent
key={label} key={`${label}-${index}`}
value={index.toString()} value={index.toString()}
className="aspect-video" className="aspect-video w-full min-w-0"
> >
<img <img
src={image} src={image}
alt={`نمای ${label}`} alt={`نمای ${label}`}
className="h-full w-full rounded-xl border object-cover" className="size-full max-w-full rounded-xl border object-cover"
/> />
</TabsContent> </TabsContent>
))} ))}
+57 -32
View File
@@ -51,7 +51,8 @@ const features: {
}, },
{ {
title: "ردیابی زمان", title: "ردیابی زمان",
description: "وضعیت هر کار را در یک نما ببینید و گلوگاه‌ها را زودتر پیدا کنید.", description:
"وضعیت هر کار را در یک نما ببینید و گلوگاه‌ها را زودتر پیدا کنید.",
icon: PenTool, icon: PenTool,
}, },
{ {
@@ -71,7 +72,8 @@ const features: {
}, },
{ {
title: "برد Kanban", title: "برد Kanban",
description: "وضعیت هر کار را در یک نما ببینید و گلوگاه‌ها را زودتر پیدا کنید.", description:
"وضعیت هر کار را در یک نما ببینید و گلوگاه‌ها را زودتر پیدا کنید.",
icon: Users, icon: Users,
}, },
]; ];
@@ -83,10 +85,19 @@ function FeatureCard({
className, className,
}: (typeof features)[number] & { className?: string }) { }: (typeof features)[number] & { className?: string }) {
return ( return (
<div className={cn("flex flex-col rounded-xl border p-5 md:p-7", className)}> <div
<Icon className="h-auto w-8 md:w-12" /> className={cn(
<h3 className="mt-5 mb-2.5 font-semibold md:text-xl">{title}</h3> "flex min-w-0 flex-col rounded-xl border p-5 md:p-7",
<p className="text-sm text-muted-foreground md:text-base">{description}</p> className,
)}
>
<Icon className="h-auto w-8 shrink-0 md:w-12" />
<h3 className="mt-5 mb-2.5 font-semibold break-words md:text-xl">
{title}
</h3>
<p className="text-sm text-pretty break-words text-muted-foreground md:text-base">
{description}
</p>
</div> </div>
); );
} }
@@ -100,10 +111,17 @@ const Feature114 = ({ className }: Feature114Props) => {
const secondHalf = features.slice(features.length / 2); const secondHalf = features.slice(features.length / 2);
return ( return (
<section dir="rtl" lang="fa" className={cn("py-32", className)}> <section
<div className="container"> dir="rtl"
<div className="grid items-center gap-20 md:grid-cols-2"> lang="fa"
<div className="flex flex-col items-center gap-5 text-center md:items-start md:text-start"> className={cn(
"relative w-full max-w-full overflow-hidden py-32",
className,
)}
>
<div className="container min-w-0 max-w-full">
<div className="grid w-full min-w-0 items-center gap-12 md:grid-cols-2 md:gap-12 lg:gap-20">
<div className="flex min-w-0 flex-col items-center gap-5 text-center md:items-start md:text-start">
<span className="inline-flex items-center -space-x-4 rtl:space-x-reverse"> <span className="inline-flex items-center -space-x-4 rtl:space-x-reverse">
{avatars.map((src, index) => ( {avatars.map((src, index) => (
<Avatar key={src} className="size-11 border lg:size-16"> <Avatar key={src} className="size-11 border lg:size-16">
@@ -114,34 +132,41 @@ const Feature114 = ({ className }: Feature114Props) => {
</Avatar> </Avatar>
))} ))}
</span> </span>
<h1 className="text-3xl font-semibold md:text-2xll"> <h1 className="max-w-full text-3xl font-semibold text-balance break-words md:text-2xll">
همکاری از راه دور را ساده کنید همکاری از راه دور را ساده کنید
</h1> </h1>
<p className="text-muted-foreground md:text-lg"> <p className="max-w-full text-pretty break-words text-muted-foreground md:text-lg">
هر عضو بداند چه زمانی چه کاری دارد هر عضو بداند چه زمانی چه کاری دارد
</p> </p>
<Button size="lg" className="w-fit gap-2"> <p className="max-w-full text-sm text-pretty break-words text-muted-foreground md:text-base">
اعلان‌های هوشمند فقط اطلاعات ضروری را می‌رسانند و حواس‌پرتی را کم می‌کنند. اعلان‌های هوشمند فقط اطلاعات ضروری را می‌رسانند و حواس‌پرتی را کم
<MoveRight className="h-auto w-5 rtl:rotate-180" /> می‌کنند.
</p>
<Button size="lg" className="w-fit max-w-full gap-2">
شروع همکاری
<MoveRight className="size-5 shrink-0 rtl:rotate-180" />
</Button> </Button>
<div className="grid grid-cols-2 justify-between gap-4 pt-10 text-start md:gap-20"> <div className="grid w-full min-w-0 grid-cols-2 justify-between gap-4 pt-10 text-start md:gap-8 lg:gap-20">
<div className="flex flex-col gap-1"> <div className="flex min-w-0 flex-col gap-1">
<h2 className="text-3xl font-semibold md:text-2xll"> <h2 className="text-3xl font-semibold break-words md:text-2xll">
{(85).toLocaleString("fa-IR")}٪ {(85).toLocaleString("fa-IR")}٪
</h2> </h2>
<p className="text-muted-foreground md:text-lg"> <p className="text-sm text-pretty break-words text-muted-foreground md:text-lg">
تصمیم‌ها را سریع‌تر هماهنگ کنید تصمیم‌ها را سریع‌تر هماهنگ کنید
</p> </p>
</div> </div>
<div className="flex flex-col gap-1"> <div className="flex min-w-0 flex-col gap-1">
<h2 className="text-3xl font-semibold md:text-2xll"> <h2 className="text-3xl font-semibold break-words md:text-2xll">
{(25000).toLocaleString("fa-IR")}+ {(25000).toLocaleString("fa-IR")}+
</h2> </h2>
<p className="text-muted-foreground md:text-lg">تیم‌ها را در یک فضای مشترک هم‌راستا کنید</p> <p className="text-sm text-pretty break-words text-muted-foreground md:text-lg">
تیم‌ها را در یک فضای مشترک هم‌راستا کنید
</p>
</div> </div>
</div> </div>
</div> </div>
<div className="grid gap-4 md:gap-7 lg:grid-cols-2">
<div className="grid w-full min-w-0 gap-4 overflow-hidden md:gap-7 lg:grid-cols-2">
<Carousel <Carousel
opts={{ opts={{
loop: true, loop: true,
@@ -153,11 +178,11 @@ const Feature114 = ({ className }: Feature114Props) => {
}), }),
]} ]}
orientation="vertical" orientation="vertical"
className="pointer-events-none relative lg:hidden" className="pointer-events-none relative w-full min-w-0 lg:hidden"
> >
<CarouselContent className="max-h-[600px]"> <CarouselContent className="mt-0 max-h-[600px]">
{features.map((feature) => ( {features.map((feature) => (
<CarouselItem key={feature.title}> <CarouselItem key={feature.title} className="pt-4">
<FeatureCard {...feature} /> <FeatureCard {...feature} />
</CarouselItem> </CarouselItem>
))} ))}
@@ -175,11 +200,11 @@ const Feature114 = ({ className }: Feature114Props) => {
}), }),
]} ]}
orientation="vertical" orientation="vertical"
className="pointer-events-none relative hidden lg:block" className="pointer-events-none relative hidden w-full min-w-0 lg:block"
> >
<CarouselContent className="max-h-[600px]"> <CarouselContent className="mt-0 max-h-[600px]">
{firstHalf.map((feature) => ( {firstHalf.map((feature) => (
<CarouselItem key={feature.title}> <CarouselItem key={feature.title} className="pt-4">
<FeatureCard {...feature} className="p-4 md:p-7" /> <FeatureCard {...feature} className="p-4 md:p-7" />
</CarouselItem> </CarouselItem>
))} ))}
@@ -197,11 +222,11 @@ const Feature114 = ({ className }: Feature114Props) => {
}), }),
]} ]}
orientation="vertical" orientation="vertical"
className="pointer-events-none relative hidden lg:block" className="pointer-events-none relative hidden w-full min-w-0 lg:block"
> >
<CarouselContent className="max-h-[600px]"> <CarouselContent className="mt-0 max-h-[600px]">
{secondHalf.map((feature) => ( {secondHalf.map((feature) => (
<CarouselItem key={feature.title}> <CarouselItem key={feature.title} className="pt-4">
<FeatureCard {...feature} className="p-4 md:p-7" /> <FeatureCard {...feature} className="p-4 md:p-7" />
</CarouselItem> </CarouselItem>
))} ))}
+26 -19
View File
@@ -107,36 +107,43 @@ const Feature12 = ({ className }: Feature12Props) => {
}, [api]); }, [api]);
return ( return (
<section dir="rtl" lang="fa" className={cn("py-32", className)}> <section
<div className="container max-w-7xl"> dir="rtl"
<div className="mb-10 flex flex-col items-center gap-6 md:mb-20"> lang="fa"
className={cn("w-full overflow-hidden py-32", className)}
>
<div className="container max-w-7xl min-w-0">
<div className="mb-10 flex min-w-0 flex-col items-center gap-6 md:mb-20">
<Badge variant="outline">داده سازمانی</Badge> <Badge variant="outline">داده سازمانی</Badge>
<h2 className="mb-2 text-center text-3xl font-semibold lg:text-2xll"> <h2 className="mb-2 max-w-full text-center text-3xl font-semibold text-balance break-words lg:text-2xll">
تصمیم استراتژیک را داده‌محور کنید تصمیم استراتژیک را داده‌محور کنید
</h2> </h2>
</div> </div>
<Carousel <Carousel
className="w-full" className="w-full min-w-0"
setApi={setApi} setApi={setApi}
opts={{ opts={{
align: "start", align: "start",
direction: "rtl", direction: "rtl",
}} }}
> >
<div className="mb-4 flex justify-between px-1 md:mb-5"> <div className="mb-4 space-y-4 px-1 md:mb-5 lg:flex lg:items-center lg:justify-between lg:space-y-0">
<p className="font-medium">داشبوردهای تعاملی به تیم‌ها اجازه می‌دهد سؤال جدید بپرسند بدون اینکه هر بار به تیم داده وابسته باشند.</p> <p className="w-full min-w-0 text-pretty break-words font-medium lg:flex-1 lg:pe-3">
<div className="flex items-center gap-2"> داشبوردهای تعاملی به تیم‌ها اجازه می‌دهد سؤال جدید بپرسند بدون
<div className="me-2 hidden items-center gap-3 text-xs text-muted-foreground md:flex"> اینکه هر بار به تیم داده وابسته باشند.
<span> </p>
<div className="flex w-full min-w-0 items-center gap-2 lg:w-auto lg:shrink-0">
<div className="me-2 flex min-w-0 flex-1 items-center gap-3 text-xs text-muted-foreground lg:flex-none">
<span className="shrink-0">
{currentSlide.toLocaleString("fa-IR").padStart(2, "۰")} {currentSlide.toLocaleString("fa-IR").padStart(2, "۰")}
</span> </span>
<div className="h-[2px] w-52 overflow-hidden rounded-full bg-muted"> <div className="h-[2px] min-w-0 flex-1 overflow-hidden rounded-full bg-muted lg:w-52 lg:flex-none">
<div <div
className="h-full origin-start bg-primary transition-transform" className="h-full origin-start bg-primary transition-transform"
style={{ transform: `scaleX(${progress})` }} style={{ transform: `scaleX(${progress})` }}
/> />
</div> </div>
<span> <span className="shrink-0">
{slides.length.toLocaleString("fa-IR").padStart(2, "۰")} {slides.length.toLocaleString("fa-IR").padStart(2, "۰")}
</span> </span>
</div> </div>
@@ -148,19 +155,19 @@ const Feature12 = ({ className }: Feature12Props) => {
{slides.map((slide, index) => ( {slides.map((slide, index) => (
<CarouselItem <CarouselItem
key={index} key={index}
className="basis-full md:basis-1/2 lg:basis-1/3" className="min-w-0 basis-full md:basis-1/2 lg:basis-1/3"
> >
<div className="p-1"> <div className="min-w-0 p-1">
<Card> <Card className="min-w-0 overflow-hidden">
<CardContent className="flex flex-col justify-center p-6"> <CardContent className="flex min-w-0 flex-col justify-center p-6">
<div> <div className="min-w-0">
<span className="mb-5 flex size-8 items-center justify-center rounded-full bg-accent lg:size-10"> <span className="mb-5 flex size-8 items-center justify-center rounded-full bg-accent lg:size-10">
{slide.icon} {slide.icon}
</span> </span>
<p className="text-xl font-semibold md:text-xl lg:text-xl"> <p className="text-xl font-semibold break-words md:text-xl lg:text-xl">
{slide.title} {slide.title}
</p> </p>
<p className="pt-2 text-muted-foreground"> <p className="pt-2 text-pretty break-words text-muted-foreground">
{slide.description} {slide.description}
</p> </p>
</div> </div>
+29 -15
View File
@@ -6,7 +6,8 @@ import { cn } from "@/lib/utils";
const items = [ const items = [
{ {
title: "Slack", title: "Slack",
description: "محصولات را دسته‌بندی کنید و ویژگی‌ها را برای جستجوی بهتر ساختاردهی کنید.", description:
"محصولات را دسته‌بندی کنید و ویژگی‌ها را برای جستجوی بهتر ساختاردهی کنید.",
number: 400, number: 400,
}, },
{ {
@@ -32,41 +33,54 @@ interface Feature139Props {
const Feature139 = ({ className }: Feature139Props) => { const Feature139 = ({ className }: Feature139Props) => {
return ( return (
<section dir="rtl" lang="fa" className={cn("py-32", className)}> <section
<div className="container"> dir="rtl"
<div className="rounded-lg border bg-card p-10 shadow-sm"> lang="fa"
<div className="flex w-full flex-col items-center justify-between gap-4 md:flex-row"> className={cn(
<div className="w-full max-w-md text-start"> "relative w-full max-w-full overflow-hidden py-32",
className,
)}
>
<div className="container min-w-0 max-w-full">
<div className="w-full min-w-0 rounded-lg border bg-card p-4 shadow-sm sm:p-6 md:p-10">
<div className="flex w-full min-w-0 flex-col items-center justify-between gap-6 md:flex-row md:gap-4">
<div className="w-full min-w-0 max-w-md text-start">
<Badge <Badge
variant="outline" variant="outline"
className="px-3 py-2 text-muted-foreground" className="px-3 py-2 text-muted-foreground"
> >
مسیر خرید را بهینه کنید تا سبد رها شده کمتر شود. پیشنهاد هوشمند محصول، میانگین سفارش را بالا می‌برد. فروش آنلاین
</Badge> </Badge>
<h2 className="my-5 text-xl font-medium lg:text-xl"> <h2 className="my-5 max-w-full text-xl font-medium text-balance break-words lg:text-xl">
فروش آنلاین را مقیاس‌پذیر کنید فروش آنلاین را مقیاس‌پذیر کنید
</h2> </h2>
<p className="text-sm text-muted-foreground lg:text-base"> <p className="max-w-full text-sm text-pretty break-words text-muted-foreground lg:text-base">
مسیر خرید را بهینه کنید تا سبد رها شده کمتر شود. پیشنهاد هوشمند
محصول، میانگین سفارش را بالا می‌برد.
</p>
<p className="mt-3 max-w-full text-sm text-pretty break-words text-muted-foreground lg:text-base">
تجربه خرید را روان‌تر بسازید تجربه خرید را روان‌تر بسازید
</p> </p>
</div> </div>
<div className="w-full max-w-lg"> <div className="w-full min-w-0 max-w-lg">
<img <img
src="/block-media/shadcnblocks/block/placeholder-1.svg" src="/block-media/shadcnblocks/block/placeholder-1.svg"
alt="مدیریت سفارش" alt="مدیریت سفارش"
className="max-h-[420px] w-full rounded-lg object-cover" className="max-h-[420px] w-full max-w-full rounded-lg object-cover"
/> />
</div> </div>
</div> </div>
<div className="mt-24 grid grid-cols-1 justify-between gap-12 sm:grid-cols-2 md:grid-cols-4"> <div className="mt-12 grid w-full min-w-0 grid-cols-1 justify-between gap-8 sm:mt-16 sm:grid-cols-2 sm:gap-12 md:mt-24 md:grid-cols-4">
{items.map((item) => ( {items.map((item) => (
<div key={item.title} className="text-start"> <div key={item.title} className="min-w-0 max-w-full text-start">
<p className="text-xl text-muted-foreground"> <p className="text-xl text-muted-foreground">
{item.number.toLocaleString("fa-IR")}+ {item.number.toLocaleString("fa-IR")}+
</p> </p>
<h6 className="mt-5 mb-3 font-semibold">{item.title}</h6> <h6 className="mt-5 mb-3 font-semibold break-words">
<p className="text-sm text-muted-foreground"> {item.title}
</h6>
<p className="text-sm text-pretty break-words text-muted-foreground">
{item.description} {item.description}
</p> </p>
</div> </div>
+26 -17
View File
@@ -12,8 +12,7 @@ import { cn } from "@/lib/utils";
const items = [ const items = [
{ {
title: "پیشنهاد عنوان", title: "پیشنهاد عنوان",
description: description: "ساختار عنوان و توضیحات را برای کلیک بیشتر بهینه کنید.",
"ساختار عنوان و توضیحات را برای کلیک بیشتر بهینه کنید.",
imgSrc: "/block-media/shadcnblocks/block/placeholder-dark-1.svg", imgSrc: "/block-media/shadcnblocks/block/placeholder-dark-1.svg",
}, },
{ {
@@ -36,42 +35,52 @@ interface Feature140Props {
const Feature140 = ({ className }: Feature140Props) => { const Feature140 = ({ className }: Feature140Props) => {
return ( return (
<section dir="rtl" lang="fa" className={cn("py-32", className)}> <section
<div className="container"> dir="rtl"
lang="fa"
className={cn(
"relative w-full max-w-full overflow-hidden py-32",
className,
)}
>
<div className="container min-w-0 max-w-full">
<Carousel <Carousel
className="relative w-full" className="relative w-full min-w-0"
opts={{ opts={{
align: "start",
loop: true,
direction: "rtl", direction: "rtl",
}} }}
> >
<CarouselContent className="ease-in"> <CarouselContent className="ml-0 ease-in">
{items.map((item) => ( {items.map((item) => (
<CarouselItem key={item.title}> <CarouselItem key={item.title} className="min-w-0 basis-full pl-0">
<div className="flex flex-col items-center justify-between gap-4 rounded-2xl bg-muted py-20 ps-8 md:flex-row md:ps-16"> <div className="relative flex min-w-0 flex-col items-center justify-between gap-4 overflow-hidden rounded-2xl bg-muted pt-20 ps-8 pb-32 md:flex-row md:ps-16">
<div className="w-full pe-2 text-start md:max-w-xs md:pe-0"> <div className="w-full min-w-0 pe-2 text-start md:max-w-xs md:pe-0">
<h2 className="mb-6 text-xl font-medium sm:text-xl md:text-2xll"> <h2 className="mb-6 max-w-full text-xl font-medium text-balance break-words sm:text-xl md:text-2xll">
{item.title} {item.title}
</h2> </h2>
<p className="text-sm text-muted-foreground md:text-base"> <p className="text-sm text-pretty break-words text-muted-foreground md:text-base">
{item.description} {item.description}
</p> </p>
</div> </div>
<div className="w-full max-w-2xl"> <div className="w-full min-w-0 max-w-2xl self-start md:self-center">
<img <img
src={item.imgSrc} src={item.imgSrc}
alt={`نمای ${item.title}`} alt={`نمای ${item.title}`}
className="h-80 max-h-[560px] w-full rounded-s-2xl object-cover md:h-full" className="h-80 max-h-[560px] w-full max-w-full rounded-s-2xl object-cover md:h-auto md:max-h-[28rem]"
draggable={false}
/> />
</div> </div>
</div> </div>
</CarouselItem> </CarouselItem>
))} ))}
</CarouselContent> </CarouselContent>
<div className="absolute bottom-16 start-16 md:bottom-11"> <div className="absolute bottom-10 start-16 z-20">
<CarouselPrevious className="size-14" /> <CarouselPrevious className="static size-14 translate-y-0 rtl:rotate-180" />
</div> </div>
<div className="absolute end-16 bottom-16 md:bottom-11"> <div className="absolute end-16 bottom-10 z-20">
<CarouselNext className="size-14" /> <CarouselNext className="static size-14 translate-y-0 rtl:rotate-180" />
</div> </div>
</Carousel> </Carousel>
</div> </div>
+32 -19
View File
@@ -7,8 +7,7 @@ import { cn } from "@/lib/utils";
const utilities = [ const utilities = [
{ {
title: "تاریخچه مشتری", title: "تاریخچه مشتری",
description: description: "پاسخ‌های پرتکرار را ذخیره کنید و با یک کلیک ارسال کنید.",
"پاسخ‌های پرتکرار را ذخیره کنید و با یک کلیک ارسال کنید.",
image: "/block-media/shadcnblocks/block/placeholder-1.svg", image: "/block-media/shadcnblocks/block/placeholder-1.svg",
imageAlt: "مدیریت تیکت", imageAlt: "مدیریت تیکت",
}, },
@@ -28,15 +27,13 @@ const utilities = [
}, },
{ {
title: "پایگاه دانش", title: "پایگاه دانش",
description: description: "مشتریان و تیم با مقالات راهنما سریع‌تر به پاسخ می‌رسند.",
"مشتریان و تیم با مقالات راهنما سریع‌تر به پاسخ می‌رسند.",
image: "/block-media/shadcnblocks/block/placeholder-4.svg", image: "/block-media/shadcnblocks/block/placeholder-4.svg",
imageAlt: "مدیریت تیکت", imageAlt: "مدیریت تیکت",
}, },
{ {
title: "پاسخ آماده", title: "پاسخ آماده",
description: description: "پاسخ‌های پرتکرار را ذخیره کنید و با یک کلیک ارسال کنید.",
"پاسخ‌های پرتکرار را ذخیره کنید و با یک کلیک ارسال کنید.",
image: "/block-media/shadcnblocks/block/placeholder-5.svg", image: "/block-media/shadcnblocks/block/placeholder-5.svg",
imageAlt: "داشبورد رضایت", imageAlt: "داشبورد رضایت",
}, },
@@ -55,30 +52,46 @@ interface Feature148Props {
const Feature148 = ({ className }: Feature148Props) => { const Feature148 = ({ className }: Feature148Props) => {
return ( return (
<section dir="rtl" lang="fa" className={cn("py-32", className)}> <section
<div className="container"> dir="rtl"
<div className="m-auto mb-24 max-w-xl text-center"> lang="fa"
<h2 className="mb-6 text-3xl font-semibold lg:text-2xll"> className={cn(
"relative w-full max-w-full overflow-hidden py-32",
className,
)}
>
<div className="container min-w-0 max-w-full">
<div className="mx-auto mb-16 flex w-full min-w-0 max-w-xl flex-col items-center text-center md:mb-24">
<h2 className="mb-6 max-w-full text-3xl font-semibold text-balance break-words lg:text-2xll">
زمان حل مسئله را کوتاه کنید زمان حل مسئله را کوتاه کنید
</h2> </h2>
<p className="m-auto max-w-3xl text-lg lg:text-xl"> <p className="mx-auto max-w-full text-lg text-pretty break-words lg:text-xl">
کیفیت پاسخگویی را قابل اندازه‌گیری کنید کیفیت پاسخگویی را قابل اندازه‌گیری کنید
</p> </p>
<Button asChild className="mt-8 rounded-xl" size="lg"> <p className="mt-4 max-w-full text-sm text-pretty break-words text-muted-foreground md:text-base">
<a href="#">تیکت‌های مهم بر اساس قرارداد یا شدت مسئله در صف بالاتر قرار می‌گیرند.</a> تیکت‌های مهم بر اساس قرارداد یا شدت مسئله در صف بالاتر قرار
می‌گیرند.
</p>
<Button asChild className="mt-8 max-w-full rounded-xl" size="lg">
<a href="#">مشاهده امکانات</a>
</Button> </Button>
</div> </div>
<div className="mt-11 grid w-full grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3"> <div className="mt-11 grid w-full min-w-0 grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
{utilities.map((utility) => ( {utilities.map((utility) => (
<Card key={utility.title} className="border-0 pt-0"> <Card
key={utility.title}
className="min-w-0 max-w-full overflow-hidden border-0 pt-0"
>
<img <img
src={utility.image} src={utility.image}
alt={utility.imageAlt} alt={utility.imageAlt}
className="aspect-video w-full rounded-t-xl object-cover" className="aspect-video w-full max-w-full rounded-t-xl object-cover"
/> />
<div className="p-5 text-start"> <div className="min-w-0 p-5 text-start">
<p className="mb-1 font-medium">{utility.title}</p> <p className="mb-1 font-medium break-words">{utility.title}</p>
<p className="text-muted-foreground">{utility.description}</p> <p className="text-pretty break-words text-muted-foreground">
{utility.description}
</p>
</div> </div>
</Card> </Card>
))} ))}
+39 -24
View File
@@ -9,55 +9,70 @@ interface Feature149Props {
const Feature149 = ({ className }: Feature149Props) => { const Feature149 = ({ className }: Feature149Props) => {
return ( return (
<section dir="rtl" lang="fa" className={cn("py-32", className)}> <section
<div className="container"> dir="rtl"
<div className="relative isolate flex flex-col md:flex-row md:gap-0"> lang="fa"
className={cn(
"relative w-full max-w-full overflow-hidden py-32",
className,
)}
>
<div className="container min-w-0 max-w-full">
<div className="relative isolate flex w-full min-w-0 flex-col gap-3 md:flex-row md:gap-0">
<img <img
src="/block-media/shadcnblocks/block/photos/simone-hutsch-9jsQcDsxyqA-unsplash.jpg" src="/block-media/shadcnblocks/block/photos/simone-hutsch-9jsQcDsxyqA-unsplash.jpg"
alt="دستیار هوش مصنوعی" alt="دستیار هوش مصنوعی"
className="absolute top-0 start-0 z-[-1] h-full w-full rounded-2xl object-cover" className="absolute inset-0 z-[-1] hidden size-full rounded-2xl object-cover md:block"
/> />
<div className="group relative flex h-[300px] w-full cursor-pointer flex-col items-start gap-6 p-6 md:h-[600px] md:w-1/2 md:p-10 md:transition-[width] hover:md:w-2/3"> <div className="group relative flex min-h-[320px] w-full min-w-0 cursor-pointer flex-col items-start justify-end gap-3 overflow-hidden rounded-2xl p-5 sm:min-h-[360px] sm:gap-4 sm:p-6 md:h-[600px] md:w-1/2 md:justify-start md:gap-6 md:p-10 md:transition-[width] hover:md:w-2/3">
<div className="md:backdrop-blur-0 md:group-hover:backdrop-blur-0 absolute top-0 start-0 z-[-1] h-full w-full rounded-t-[20px] bg-linear-to-b from-black/40 to-black/30 backdrop-filter transition-all duration-500 ease-out group-hover:from-black/30 group-hover:to-black/20 group-hover:backdrop-blur-[2px] md:rounded-2xl md:from-black/40 md:to-black/30 md:transition-colors md:duration-300 group-hover:md:from-black/50 group-hover:md:to-black/40" /> <img
src="/block-media/shadcnblocks/block/photos/simone-hutsch-9jsQcDsxyqA-unsplash.jpg"
alt=""
aria-hidden
className="absolute inset-0 z-[-2] size-full object-cover md:hidden"
/>
<div className="absolute inset-0 z-[-1] rounded-2xl bg-linear-to-b from-black/40 to-black/50 backdrop-blur-[2px] transition-all duration-500 ease-out group-hover:from-black/30 group-hover:to-black/40 md:rounded-2xl md:from-black/40 md:to-black/30 md:backdrop-blur-0 md:transition-colors md:duration-300 group-hover:md:from-black/50 group-hover:md:to-black/40 md:group-hover:backdrop-blur-0" />
<Button <Button
variant="outline" variant="outline"
className="rounded-full border-white/20 bg-background/10 text-white hover:bg-background/20" className="h-auto max-w-full rounded-full border-white/20 bg-background/10 px-3 py-1.5 text-xs whitespace-normal text-white hover:bg-background/20 sm:text-sm"
> >
درخواست‌ها را خودکار دسته‌بندی کنید و به تیم مناسب بفرستید. دسته‌بندی خودکار
</Button> </Button>
<h1 className="text-3xl font-bold text-white md:text-2xll"> <h2 className="max-w-full text-2xl font-bold text-balance break-words text-white sm:text-3xl md:text-2xll">
با هوش مصنوعی سریع‌تر تصمیم بگیرید با هوش مصنوعی سریع‌تر تصمیم بگیرید
</h1> </h2>
<p className="max-w-md text-start text-white/90"> <p className="max-w-md text-start text-sm text-pretty break-words text-white/90 sm:text-base">
کارهای تکراری را به AI بسپارید درخواست‌ها را خودکار دسته‌بندی کنید و به تیم مناسب بفرستید. کارهای
تکراری را به AI بسپارید.
</p> </p>
</div> </div>
<div className="relative hidden h-[600px] w-5 bg-background md:block"> <div className="relative hidden h-[600px] w-5 shrink-0 bg-background md:block">
<div className="absolute top-0 start-[-40px] h-[40px] w-[40px] rounded-[1rem] shadow-[-10px_-10px_0_0_var(--background)]" /> <div className="absolute top-0 start-[-40px] h-[40px] w-[40px] rounded-[1rem] shadow-[-10px_-10px_0_0_var(--background)]" />
<div className="absolute top-0 end-[-40px] h-[40px] w-[40px] rounded-[1rem] shadow-[10px_-10px_0_0_var(--background)]" /> <div className="absolute top-0 end-[-40px] h-[40px] w-[40px] rounded-[1rem] shadow-[10px_-10px_0_0_var(--background)]" />
<div className="absolute bottom-0 start-[-40px] h-[40px] w-[40px] rounded-[1rem] shadow-[-10px_10px_0_0_var(--background)]" /> <div className="absolute bottom-0 start-[-40px] h-[40px] w-[40px] rounded-[1rem] shadow-[-10px_10px_0_0_var(--background)]" />
<div className="absolute end-[-40px] bottom-0 h-[40px] w-[40px] rounded-[1rem] shadow-[10px_10px_0_0_var(--background)]" /> <div className="absolute end-[-40px] bottom-0 h-[40px] w-[40px] rounded-[1rem] shadow-[10px_10px_0_0_var(--background)]" />
</div> </div>
<div <div className="group relative flex min-h-[320px] w-full min-w-0 cursor-pointer flex-col items-start justify-end gap-3 overflow-hidden rounded-2xl p-5 sm:min-h-[360px] sm:gap-4 sm:p-6 md:h-[600px] md:w-1/2 md:justify-start md:gap-6 md:p-10 md:transition-[width] hover:md:w-2/3">
className="group relative flex h-[300px] w-full cursor-pointer flex-col items-start gap-6 p-6 md:h-[600px] md:w-1/2 md:p-10 md:transition-[width] hover:md:w-2/3" <img
onClick={() => { src="/block-media/shadcnblocks/block/photos/simone-hutsch-9jsQcDsxyqA-unsplash.jpg"
console.log("click"); alt=""
}} aria-hidden
> className="absolute inset-0 z-[-2] size-full object-cover object-[center_70%] md:hidden"
<div className="md:backdrop-blur-0 md:group-hover:backdrop-blur-0 absolute top-0 start-0 z-[-1] h-full w-full rounded-b-[20px] bg-linear-to-t from-black/40 to-black/30 backdrop-filter transition-all duration-500 ease-out group-hover:from-black/30 group-hover:to-black/20 group-hover:backdrop-blur-[2px] md:rounded-2xl md:from-black/40 md:to-black/30 md:transition-colors md:duration-300 group-hover:md:from-black/50 group-hover:md:to-black/40" /> />
<div className="absolute inset-0 z-[-1] rounded-2xl bg-linear-to-t from-black/50 to-black/40 backdrop-blur-[2px] transition-all duration-500 ease-out group-hover:from-black/40 group-hover:to-black/30 md:rounded-2xl md:from-black/40 md:to-black/30 md:backdrop-blur-0 md:transition-colors md:duration-300 group-hover:md:from-black/50 group-hover:md:to-black/40 md:group-hover:backdrop-blur-0" />
<Button <Button
variant="outline" variant="outline"
className="rounded-full border-white/20 bg-background/10 text-white hover:bg-background/20" className="h-auto max-w-full rounded-full border-white/20 bg-background/10 px-3 py-1.5 text-xs whitespace-normal text-white hover:bg-background/20 sm:text-sm"
> >
اتوماسیون AI اتوماسیون AI
</Button> </Button>
<h1 className="text-3xl font-bold text-white md:text-2xll"> <h2 className="max-w-full text-2xl font-bold text-balance break-words text-white sm:text-3xl md:text-2xll">
پیشنهادهایی که واقعاً مفیدند پیشنهادهایی که واقعاً مفیدند
</h1> </h2>
<p className="max-w-md text-start text-white/90"> <p className="max-w-md text-start text-sm text-pretty break-words text-white/90 sm:text-base">
داده را به بینش عملی تبدیل کنید داده را به بینش عملی تبدیل کنید
</p> </p>
</div> </div>
+75 -45
View File
@@ -6,14 +6,48 @@ import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
const icons = [
{
image: "/block-media/shadcnblocks/block/block-1.svg",
title: "فروش آنلاین را مقیاس‌پذیر کنید",
},
{
image: "/block-media/shadcnblocks/block/block-2.svg",
title: "تجربه خرید را روان‌تر بسازید",
},
{
image: "/block-media/shadcnblocks/block/block-3.svg",
title: "هر سفارش را از انبار تا تحویل ببینید",
},
{
image: "/block-media/shadcnblocks/block/block-4.svg",
title: "نرخ تبدیل فروشگاه را بالا ببرید",
},
{
image: "/block-media/shadcnblocks/block/block-5.svg",
title: "موجودی و سفارش را یکجا مدیریت کنید",
},
{
image: "/block-media/shadcnblocks/block/block-6.svg",
title: "مشتری را به خرید دوباره برگردانید",
},
{
image: "/block-media/shadcnblocks/block/block-1.svg",
title: "فروش آنلاین را مقیاس‌پذیر کنید",
},
] as const;
const IconElem = ({ image, title }: { image: string; title: string }) => ( const IconElem = ({ image, title }: { image: string; title: string }) => (
<div className="flex flex-col items-center"> <div className="flex min-w-0 max-w-full flex-col items-center">
<img <img
src={image} src={image}
alt={`لوگوی ${title}`} alt={`لوگوی ${title}`}
className="mb-3 hidden h-14 w-14 rounded-lg object-cover p-2 shadow-[rgba(50,50,105,0.15)_0px_2px_5px_0px,rgba(0,0,0,0.05)_0px_1px_1px_0px] md:block dark:invert" className="mb-3 hidden size-14 rounded-lg object-cover p-2 shadow-[rgba(50,50,105,0.15)_0px_2px_5px_0px,rgba(0,0,0,0.05)_0px_1px_1px_0px] md:block dark:invert"
/> />
<Badge variant="secondary" className="font-mono text-xs font-semibold"> <Badge
variant="secondary"
className="h-auto max-w-[9.5rem] px-2 py-1 text-center font-mono text-[10px] leading-snug font-semibold whitespace-normal sm:max-w-[11rem] sm:text-xs md:max-w-none"
>
{title} {title}
</Badge> </Badge>
</div> </div>
@@ -25,69 +59,65 @@ interface Feature152Props {
const Feature152 = ({ className }: Feature152Props) => { const Feature152 = ({ className }: Feature152Props) => {
return ( return (
<section dir="rtl" lang="fa" className={cn("py-32", className)}> <section
<div className="container"> dir="rtl"
<div className="mb-16 flex flex-col items-center md:mb-6"> lang="fa"
className={cn(
"relative w-full max-w-full overflow-hidden py-32",
className,
)}
>
<div className="container min-w-0 max-w-full">
<div className="mb-12 flex w-full min-w-0 flex-col items-center md:mb-16">
<Badge variant="secondary" className="mb-6 bg-muted"> <Badge variant="secondary" className="mb-6 bg-muted">
فروش آنلاین فروش آنلاین
</Badge> </Badge>
<h1 className="mb-3 max-w-md text-center text-xl font-medium md:text-xl"> <h1 className="mb-3 max-w-md text-center text-xl font-medium text-balance break-words md:text-xl">
تجربه خرید را روان‌تر بسازید تجربه خرید را روان‌تر بسازید
</h1> </h1>
<p className="mb-3 max-w-80 text-center"> <p className="mb-3 max-w-80 text-center text-pretty break-words">
هر سفارش را از انبار تا تحویل ببینید هر سفارش را از انبار تا تحویل ببینید
</p> </p>
<Button variant="link" asChild className="text-blue-700"> <Button
<a href="#"> variant="link"
asChild
className="h-auto max-w-full px-2 text-blue-700 whitespace-normal"
>
<a
href="#"
className="inline-flex max-w-full flex-wrap items-center justify-center gap-1 text-center"
>
<span className="text-pretty break-words">
نرخ تبدیل فروشگاه را بالا ببرید نرخ تبدیل فروشگاه را بالا ببرید
<ArrowRight className="ms-2 size-4 rtl:rotate-180" /> </span>
<ArrowRight className="size-4 shrink-0 rtl:rotate-180" />
</a> </a>
</Button> </Button>
</div> </div>
<div className="relative mx-auto flex max-w-3xl flex-col gap-5 overflow-hidden pb-8 md:gap-0">
<div className="flex justify-around md:mb-[-30px]"> <div className="relative mx-auto flex w-full min-w-0 max-w-3xl flex-col gap-5 overflow-hidden pb-8 md:gap-0">
<IconElem <div className="grid grid-cols-2 justify-items-center gap-3 md:mb-[-30px] md:flex md:justify-around md:gap-0">
image="/block-media/shadcnblocks/block/block-1.svg" <IconElem {...icons[0]} />
title="فروش آنلاین را مقیاس‌پذیر کنید" <IconElem {...icons[1]} />
/>
<IconElem
image="/block-media/shadcnblocks/block/block-2.svg"
title="تجربه خرید را روان‌تر بسازید"
/>
</div> </div>
<div className="flex justify-center md:mb-[-30px]"> <div className="flex justify-center md:mb-[-30px]">
<IconElem <IconElem {...icons[2]} />
image="/block-media/shadcnblocks/block/block-3.svg"
title="هر سفارش را از انبار تا تحویل ببینید"
/>
</div> </div>
<div className="flex justify-evenly md:mb-[-30px]"> <div className="grid grid-cols-2 justify-items-center gap-3 md:mb-[-30px] md:flex md:justify-evenly md:gap-0">
<IconElem <IconElem {...icons[3]} />
image="/block-media/shadcnblocks/block/block-4.svg" <IconElem {...icons[4]} />
title="نرخ تبدیل فروشگاه را بالا ببرید"
/>
<IconElem
image="/block-media/shadcnblocks/block/block-5.svg"
title="موجودی و سفارش را یکجا مدیریت کنید"
/>
</div> </div>
<div className="flex justify-between"> <div className="grid grid-cols-2 justify-items-center gap-3 md:flex md:justify-between md:gap-0">
<IconElem <IconElem {...icons[5]} />
image="/block-media/shadcnblocks/block/block-6.svg" <IconElem {...icons[6]} />
title="مشتری را به خرید دوباره برگردانید"
/>
<IconElem
image="/block-media/shadcnblocks/block/block-1.svg"
title="فروش آنلاین را مقیاس‌پذیر کنید"
/>
</div> </div>
{[...Array(11)].map((_, index) => ( {[...Array(11)].map((_, index) => (
<div <div
key={index} key={index}
className="absolute -bottom-2 start-1/2 z-[-2] aspect-square rounded-full border border-indigo-200" className="absolute -bottom-2 start-1/2 z-[-2] aspect-square max-w-none rounded-full border border-indigo-200"
style={{ style={{
width: 60 + 80 * index + "px", width: `${60 + 80 * index}px`,
opacity: 0.5, opacity: 0.5,
filter: "saturate(10%)", filter: "saturate(10%)",
transform: "translateX(-50%) translateY(50%)", transform: "translateX(-50%) translateY(50%)",
+41 -49
View File
@@ -1,7 +1,6 @@
"use client"; "use client";
import { ArrowRight } from "lucide-react"; import { ArrowRight } from "lucide-react";
import { useState } from "react";
import { import {
Carousel, Carousel,
@@ -14,11 +13,9 @@ import { cn } from "@/lib/utils";
const integrations = [ const integrations = [
{ {
image: image: "/block-media/shadcnblocks/block/logos/shadcn-ui-icon.svg",
"/block-media/shadcnblocks/block/logos/shadcn-ui-icon.svg",
title: "بهینه‌سازی محتوا", title: "بهینه‌سازی محتوا",
description: description: "ساختار عنوان و توضیحات را برای کلیک بیشتر بهینه کنید.",
"ساختار عنوان و توضیحات را برای کلیک بیشتر بهینه کنید.",
info: [ info: [
{ {
title: "تحلیل رقیب", title: "تحلیل رقیب",
@@ -37,8 +34,7 @@ const integrations = [
{ {
image: "/block-media/shadcnblocks/block/logos/figma-icon.svg", image: "/block-media/shadcnblocks/block/logos/figma-icon.svg",
title: "Figma", title: "Figma",
description: description: "ساختار عنوان و توضیحات را برای کلیک بیشتر بهینه کنید.",
"ساختار عنوان و توضیحات را برای کلیک بیشتر بهینه کنید.",
info: [ info: [
{ {
title: "پیشنهاد عنوان", title: "پیشنهاد عنوان",
@@ -57,8 +53,7 @@ const integrations = [
{ {
image: "/block-media/shadcnblocks/block/logos/tailwind-icon.svg", image: "/block-media/shadcnblocks/block/logos/tailwind-icon.svg",
title: "Tailwind", title: "Tailwind",
description: description: "ساختار عنوان و توضیحات را برای کلیک بیشتر بهینه کنید.",
"ساختار عنوان و توضیحات را برای کلیک بیشتر بهینه کنید.",
info: [ info: [
{ {
title: "ردیابی رتبه", title: "ردیابی رتبه",
@@ -73,8 +68,7 @@ const integrations = [
{ {
image: "/block-media/shadcnblocks/block/logos/google-icon.svg", image: "/block-media/shadcnblocks/block/logos/google-icon.svg",
title: "Google", title: "Google",
description: description: "تغییرات رتبه را روزانه ببینید و واکنش سریع داشته باشید.",
"تغییرات رتبه را روزانه ببینید و واکنش سریع داشته باشید.",
info: [ info: [
{ {
title: "تحلیل رقیب", title: "تحلیل رقیب",
@@ -97,66 +91,64 @@ interface Feature153Props {
} }
const Feature153 = ({ className }: Feature153Props) => { const Feature153 = ({ className }: Feature153Props) => {
const [startIndex, setStartIndex] = useState(0);
return ( return (
<section dir="rtl" lang="fa" className={cn("py-32", className)}> <section
<div className="container"> dir="rtl"
lang="fa"
className={cn(
"relative w-full max-w-full overflow-hidden py-32",
className,
)}
>
<div className="container min-w-0 max-w-full">
<Carousel <Carousel
opts={{ opts={{
align: "start", align: "start",
direction: "rtl", direction: "rtl",
}} }}
className="w-full" className="w-full min-w-0"
> >
<div className="mb-6 flex flex-col items-center gap-8 sm:flex-row sm:items-center"> <div className="mb-6 flex w-full min-w-0 flex-col items-center gap-4 sm:flex-row sm:items-center sm:justify-between sm:gap-8">
<h1 className="text-center text-xl font-medium sm:text-start"> <h1 className="max-w-full text-center text-xl font-medium text-balance break-words sm:text-start">
رتبه کلمات کلیدی را پیگیری کنید رتبه کلمات کلیدی را پیگیری کنید
</h1> </h1>
<div className="mb-[-32px] flex items-center gap-3"> <div className="flex shrink-0 items-center gap-3">
<CarouselPrevious <CarouselPrevious className="static size-8 translate-y-0 rtl:rotate-180" />
onClick={() => setStartIndex(startIndex - 1)} <CarouselNext className="static size-8 translate-y-0 rtl:rotate-180" />
disabled={startIndex === 0}
className="static"
/>
<CarouselNext
onClick={() => setStartIndex(startIndex + 1)}
disabled={startIndex === integrations.length - 1}
className="static"
/>
</div> </div>
</div> </div>
<div className="relative"> <div className="relative min-w-0">
<CarouselContent <CarouselContent className="ml-0 pb-5">
className="ms-6 pt-[5px] pb-5 transition-all duration-300"
style={{
transform: `translateX(${startIndex * 100}%)`,
}}
>
{integrations.map((item) => ( {integrations.map((item) => (
<CarouselItem <CarouselItem
key={item.title} key={item.title}
className="flex basis-full md:basis-1/2 xl:basis-1/3" className="min-w-0 basis-full pl-4 md:basis-1/2 xl:basis-1/3"
> >
<div className="flex h-full flex-col justify-between rounded-xl py-14 pe-20 ps-11 text-start shadow-[0px_0px_0px_1px_rgba(17,26,37,0.05),0px_2px_5px_rgba(16,25,36,0.1),0px_5px_20px_rgba(16,25,36,0.1)]"> <div className="flex h-full min-w-0 flex-col justify-between rounded-xl px-6 py-10 text-start shadow-[0px_0px_0px_1px_rgba(17,26,37,0.05),0px_2px_5px_rgba(16,25,36,0.1),0px_5px_20px_rgba(16,25,36,0.1)] sm:px-8 sm:py-12 md:px-11 md:py-14">
<div className="mb-6 flex items-center gap-2"> <div className="mb-6 flex min-w-0 items-center gap-2">
<img <img
src={item.image} src={item.image}
alt={`لوگوی ${item.title}`} alt={`لوگوی ${item.title}`}
className="h-7" className="h-7 shrink-0"
/> />
<h2 className="font-semibold">{item.title}</h2> <h2 className="min-w-0 font-semibold break-words">
{item.title}
</h2>
</div>
<div className="mb-4 text-pretty break-words">
{item.description}
</div> </div>
<div className="mb-4">{item.description}</div>
<div className="mb-10 flex items-center text-sm text-indigo-400"> <div className="mb-10 flex items-center text-sm text-indigo-400">
بیشتر بدانید بیشتر بدانید
<ArrowRight className="ms-2 h-4 rtl:rotate-180" /> <ArrowRight className="ms-2 size-4 shrink-0 rtl:rotate-180" />
</div> </div>
<div className="mt-auto flex flex-col gap-4"> <div className="mt-auto flex min-w-0 flex-col gap-4">
{item.info.map((infoItem) => ( {item.info.map((infoItem) => (
<div key={infoItem.title}> <div key={infoItem.title} className="min-w-0">
<h3 className="font-medium">{infoItem.title}</h3> <h3 className="font-medium break-words">
<p className="text-xs text-muted-foreground"> {infoItem.title}
</h3>
<p className="text-xs text-pretty break-words text-muted-foreground">
{infoItem.text} {infoItem.text}
</p> </p>
</div> </div>
@@ -166,8 +158,8 @@ const Feature153 = ({ className }: Feature153Props) => {
</CarouselItem> </CarouselItem>
))} ))}
</CarouselContent> </CarouselContent>
<div className="pointer-events-none absolute inset-0 start-0 z-10 w-[30px] bg-linear-to-e from-background from-10% to-transparent" /> <div className="pointer-events-none absolute inset-y-0 start-0 z-10 w-6 bg-linear-to-e from-background to-transparent sm:w-[30px]" />
<div className="pointer-events-none absolute inset-0 z-10 bg-linear-to-s from-background via-transparent to-transparent" /> <div className="pointer-events-none absolute inset-y-0 end-0 z-10 w-6 bg-linear-to-s from-background to-transparent sm:w-10" />
</div> </div>
</Carousel> </Carousel>
</div> </div>
+17 -11
View File
@@ -104,43 +104,49 @@ const Feature154 = ({ className }: Feature154Props) => {
<section <section
dir="rtl" dir="rtl"
lang="fa" lang="fa"
className={cn("relative w-full overflow-hidden py-32", className)} className={cn(
"relative w-full min-w-0 max-w-full overflow-x-clip py-32",
className,
)}
> >
<div className="container min-w-0"> <div className="container w-full min-w-0 max-w-full">
<div className="mx-auto flex max-w-3xl min-w-0 flex-col items-center justify-center gap-6 text-center"> <div className="mx-auto flex w-full min-w-0 max-w-3xl flex-col items-center justify-center gap-6 text-center">
<Badge variant="outline">ERP</Badge> <Badge variant="outline">ERP</Badge>
<h1 className="text-xl font-semibold text-balance md:text-2xll"> <h1 className="max-w-full text-xl font-semibold text-balance md:text-2xll">
عملیات سازمان را یکپارچه کنید عملیات سازمان را یکپارچه کنید
</h1> </h1>
<p className="mx-auto max-w-3xl text-lg text-pretty text-muted-foreground"> <p className="mx-auto max-w-3xl text-lg text-pretty text-muted-foreground">
گزارش‌های یکپارچه نشان می‌دهد کدام بخش بیشترین تأثیر را روی سودآوری دارد. گزارش‌های یکپارچه نشان می‌دهد کدام بخش بیشترین تأثیر را روی سودآوری دارد.
</p> </p>
</div> </div>
<div className="relative mt-10 w-full min-w-0 overflow-hidden"> <div
<Marquee className="[--duration:30s]"> dir="ltr"
className="relative mt-10 w-full min-w-0 max-w-full overflow-x-clip contain-inline-size"
>
<Marquee className="max-w-full [--duration:30s]">
{badges.map((badge, index) => ( {badges.map((badge, index) => (
<div <div
key={`row1-${badge.title}-${index}`} key={`row1-${badge.title}-${index}`}
className="flex shrink-0 items-center gap-2 rounded-full bg-muted px-4 py-2" className="flex shrink-0 items-center gap-2 rounded-full bg-muted px-4 py-2 whitespace-nowrap"
> >
{badge.icon} {badge.icon}
{badge.title} {badge.title}
</div> </div>
))} ))}
</Marquee> </Marquee>
<Marquee reverse className="[--duration:30s]"> <Marquee reverse className="max-w-full [--duration:30s]">
{badges.map((badge, index) => ( {badges.map((badge, index) => (
<div <div
key={`row2-${badge.title}-${index}`} key={`row2-${badge.title}-${index}`}
className="flex shrink-0 items-center gap-2 rounded-full bg-muted px-4 py-2" className="flex shrink-0 items-center gap-2 rounded-full bg-muted px-4 py-2 whitespace-nowrap"
> >
{badge.icon} {badge.icon}
{badge.title} {badge.title}
</div> </div>
))} ))}
</Marquee> </Marquee>
<div className="pointer-events-none absolute inset-y-0 start-0 w-1/4 bg-linear-to-e from-background" /> <div className="pointer-events-none absolute inset-y-0 left-0 z-10 w-1/4 bg-linear-to-r from-background to-transparent" />
<div className="pointer-events-none absolute inset-y-0 end-0 w-1/4 bg-linear-to-s from-background" /> <div className="pointer-events-none absolute inset-y-0 right-0 z-10 w-1/4 bg-linear-to-l from-background to-transparent" />
</div> </div>
</div> </div>
</section> </section>
+26 -12
View File
@@ -28,33 +28,47 @@ interface Feature158Props {
const Feature158 = ({ className }: Feature158Props) => { const Feature158 = ({ className }: Feature158Props) => {
return ( return (
<section dir="rtl" lang="fa" className={cn("py-32", className)}> <section
<div className="container"> dir="rtl"
<div className="mb-12 flex flex-col items-center"> lang="fa"
<h4 className="mb-4 text-muted-foreground/50"> className={cn(
"relative w-full min-w-0 max-w-full overflow-x-clip py-32",
className,
)}
>
<div className="container w-full min-w-0 max-w-full">
<div className="mb-12 flex w-full min-w-0 flex-col items-center">
<h4 className="mb-4 text-center text-muted-foreground/50">
همکاری فروش و بازاریابی همکاری فروش و بازاریابی
</h4> </h4>
<h1 className="mb-6 text-center text-xl font-semibold text-balance sm:text-2xll lg:text-[56px]"> <h1 className="mb-6 max-w-full text-center text-xl font-semibold text-balance wrap-break-word sm:text-2xll lg:text-[56px]">
پیش‌بینی درآمد را دقیق‌تر کنید پیش‌بینی درآمد را دقیق‌تر کنید
</h1> </h1>
<h3 className="text-center text-xl text-pretty"> <h3 className="max-w-full text-center text-xl text-pretty wrap-break-word">
اولویت‌بندی سرنخ اولویت‌بندی سرنخ
</h3> </h3>
</div> </div>
<div className="flex flex-col items-center"> <div className="flex w-full min-w-0 flex-col items-center">
<div className="mb-16 flex flex-col items-center justify-between gap-12 md:flex-row"> <div className="mb-16 flex w-full min-w-0 flex-col items-stretch justify-between gap-12 md:flex-row md:items-start">
{integrations.map((item) => ( {integrations.map((item) => (
<div key={item.id} className="text-center"> <div
key={item.id}
className="min-w-0 w-full max-w-full flex-1 text-center"
>
<img <img
src={item.image} src={item.image}
alt={item.imageAlt} alt={item.imageAlt}
className="mb-8 aspect-[1.6] w-full rounded-2xl border border-dashed object-cover" className="mb-8 aspect-[1.6] w-full max-w-full rounded-2xl border border-dashed object-cover"
/> />
<p className="text-sm text-pretty">{item.text}</p> <p className="max-w-full text-sm text-pretty wrap-break-word">
{item.text}
</p>
</div> </div>
))} ))}
</div> </div>
<Button>با یادآورهای هوشمند و اولویت‌بندی سرنخ، زمان تیم روی معاملات با احتمال بیشتر صرف می‌شود و چرخه فروش کوتاه‌تر می‌شود.</Button> <Button className="h-auto max-w-full shrink whitespace-normal px-4 py-2 text-center wrap-break-word">
درخواست دمو
</Button>
</div> </div>
</div> </div>
</section> </section>
+10 -10
View File
@@ -32,13 +32,17 @@ interface Feature164Props {
} }
const Feature164 = ({ className }: Feature164Props) => { const Feature164 = ({ className }: Feature164Props) => {
const [cardNumber, setCardNumber] = useState(0); const [activeTab, setActiveTab] = useState("0");
return ( return (
<section dir="rtl" lang="fa" className={cn("py-32", className)}> <section dir="rtl" lang="fa" className={cn("py-32", className)}>
<div className="container"> <div className="container">
<div className="flex flex-col justify-between lg:flex-row"> <div className="flex flex-col justify-between gap-10 lg:flex-row lg:gap-16">
<Tabs className="lg:w-1/2" defaultValue="0"> <Tabs
className="lg:w-1/2"
value={activeTab}
onValueChange={setActiveTab}
>
<div className="mb-8"> <div className="mb-8">
{integrations.map((item, index) => ( {integrations.map((item, index) => (
<TabsContent key={item.id} value={index.toString()}> <TabsContent key={item.id} value={index.toString()}>
@@ -50,23 +54,19 @@ const Feature164 = ({ className }: Feature164Props) => {
</TabsContent> </TabsContent>
))} ))}
</div> </div>
<TabsList className="flex h-full items-center justify-center gap-2 bg-transparent p-0"> <TabsList className="ml-auto flex h-auto w-fit flex-row items-center gap-2 bg-transparent p-0 group-data-horizontal/tabs:h-auto">
{integrations.map((item, index) => ( {integrations.map((item, index) => (
<TabsTrigger <TabsTrigger
key={item.id} key={item.id}
value={index.toString()} value={index.toString()}
className={cn( className="rounded-xl border border-border px-3 py-2 text-xs data-active:border-primary sm:text-base"
"rounded-xl border px-3 py-2 text-xs sm:text-base",
index === cardNumber && "border-primary",
)}
onClick={() => setCardNumber(index)}
> >
{item.title} {item.title}
</TabsTrigger> </TabsTrigger>
))} ))}
</TabsList> </TabsList>
</Tabs> </Tabs>
<div className="flex flex-col justify-center lg:w-1/2 lg:items-start"> <div className="flex flex-col justify-center lg:w-1/2 lg:items-start lg:ps-4">
<div className="max-w-md text-start"> <div className="max-w-md text-start">
<h1 className="mb-4 text-3xl font-semibold text-balance sm:text-2xll"> <h1 className="mb-4 text-3xl font-semibold text-balance sm:text-2xll">
<span className="text-muted-foreground/50">همکاری از راه دور را ساده کنید</span>{" "} <span className="text-muted-foreground/50">همکاری از راه دور را ساده کنید</span>{" "}
+4 -4
View File
@@ -42,9 +42,9 @@ interface Feature167Props {
const Feature167 = ({ className }: Feature167Props) => { const Feature167 = ({ className }: Feature167Props) => {
return ( return (
<section dir="rtl" lang="fa" className={cn("py-32", className)}> <section dir="rtl" lang="fa" className={cn("w-full max-w-full py-32", className)}>
<div className="border-y"> <div className="border-y">
<div className="container flex flex-col gap-6 border-x py-4 text-right max-lg:border-x lg:py-8"> <div className="container flex w-full flex-col gap-6 border-x py-4 text-right max-lg:border-x lg:py-8">
<Badge variant="outline" className="w-fit gap-1"> <Badge variant="outline" className="w-fit gap-1">
<Blocks /> <Blocks />
ترافیک ارگانیک ترافیک ارگانیک
@@ -59,11 +59,11 @@ const Feature167 = ({ className }: Feature167Props) => {
</div> </div>
</div> </div>
<div className="container border-x px-0"> <div className="container w-full border-x px-0">
<Tabs <Tabs
dir="rtl" dir="rtl"
defaultValue={FEATURES_DATA[0].title} defaultValue={FEATURES_DATA[0].title}
className="flex flex-col items-stretch gap-0 divide-y rounded-none lg:flex-row! lg:divide-x lg:divide-y-0" className="flex w-full flex-col items-stretch gap-0 divide-y rounded-none lg:flex-row! lg:divide-x lg:divide-y-0"
> >
<TabsList className="flex h-auto! w-full flex-col rounded-none border-b bg-transparent p-0 lg:w-1/3 lg:border-e lg:border-b-0"> <TabsList className="flex h-auto! w-full flex-col rounded-none border-b bg-transparent p-0 lg:w-1/3 lg:border-e lg:border-b-0">
{FEATURES_DATA.map((item, index, array) => ( {FEATURES_DATA.map((item, index, array) => (
+18 -12
View File
@@ -36,15 +36,21 @@ interface Feature168Props {
const Feature168 = ({ className }: Feature168Props) => { const Feature168 = ({ className }: Feature168Props) => {
return ( return (
<section dir="rtl" lang="fa" className={cn("py-32", className)}> <section
dir="rtl"
lang="fa"
className={cn("w-full max-w-full overflow-x-hidden py-32", className)}
>
<div className="border-y"> <div className="border-y">
<div className="container flex flex-col gap-6 border-x py-4 max-lg:border-x lg:py-8"> <div className="container flex min-w-0 w-full flex-col gap-6 border-x py-4 max-lg:border-x lg:py-8">
<Badge <Badge
variant="outline" variant="outline"
className="w-fit gap-1 bg-card px-3 text-sm font-normal tracking-tight shadow-sm" className="h-auto max-w-full shrink gap-1 bg-card px-3 py-1.5 text-sm font-normal tracking-tight whitespace-normal text-pretty shadow-sm"
> >
<PocketKnife className="size-4" /> <PocketKnife className="size-4 shrink-0" />
<span>گزارش‌های یکپارچه نشان می‌دهد کدام بخش بیشترین تأثیر را روی سودآوری دارد.</span> <span className="min-w-0">
گزارش‌های یکپارچه نشان می‌دهد کدام بخش بیشترین تأثیر را روی سودآوری دارد.
</span>
</Badge> </Badge>
<h2 className="text-3xl leading-tight tracking-tight text-balance md:text-xl lg:text-2xll"> <h2 className="text-3xl leading-tight tracking-tight text-balance md:text-xl lg:text-2xll">
عملیات سازمان را یکپارچه کنید عملیات سازمان را یکپارچه کنید
@@ -54,15 +60,15 @@ const Feature168 = ({ className }: Feature168Props) => {
</p> </p>
</div> </div>
</div> </div>
<div className="container border-x lg:px-0!"> <div className="container min-w-0 w-full border-x lg:px-0!">
<div className="items-center"> <div className="min-w-0 items-center">
<div className="grid flex-1 bg-border max-lg:divide-y max-lg:border-x lg:grid-cols-3 lg:gap-px"> <div className="grid min-w-0 flex-1 bg-border max-lg:divide-y max-lg:border-x lg:grid-cols-3 lg:gap-px">
{DATA.map((item) => ( {DATA.map((item) => (
<div <div
key={item.title} key={item.title}
className="relative isolate flex flex-col bg-background pt-5 text-start lg:pt-20" className="relative isolate flex min-w-0 flex-col bg-background pt-5 text-start lg:pt-20"
> >
<div className="flex-1 border-b border-border"> <div className="min-w-0 flex-1 border-b border-border">
<h3 className="mt-2 px-4 text-lg font-semibold tracking-tight lg:px-8"> <h3 className="mt-2 px-4 text-lg font-semibold tracking-tight lg:px-8">
{item.title} {item.title}
</h3> </h3>
@@ -70,11 +76,11 @@ const Feature168 = ({ className }: Feature168Props) => {
{item.description} {item.description}
</p> </p>
</div> </div>
<div className="bg-muted"> <div className="min-w-0 overflow-hidden bg-muted">
<img <img
src={item.image} src={item.image}
alt={item.imageAlt} alt={item.imageAlt}
className="p-12 dark:invert" className="h-auto w-full max-w-full p-6 sm:p-8 lg:p-12 dark:invert"
/> />
</div> </div>
</div> </div>
+40 -29
View File
@@ -1,4 +1,4 @@
import { ArrowDownRight } from "lucide-react"; import { ArrowDownLeft } from "lucide-react";
import { Card, CardContent } from "@/components/ui/card"; import { Card, CardContent } from "@/components/ui/card";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
@@ -27,57 +27,68 @@ interface Feature171Props {
const Feature171 = ({ className }: Feature171Props) => { const Feature171 = ({ className }: Feature171Props) => {
return ( return (
<section dir="rtl" lang="fa" className={cn("bg-secondary py-32", className)}> <section
<div className="container"> dir="rtl"
<div className="relative flex items-center justify-center"> lang="fa"
<DashedLine className="text-muted-foreground" /> className={cn("w-full max-w-full overflow-visible bg-secondary py-32", className)}
<span className="absolute bg-secondary px-3 font-mono text-sm font-medium tracking-wide text-muted-foreground max-lg:hidden"> >
با یادآورهای هوشمند و اولویت‌بندی سرنخ، زمان تیم روی معاملات با احتمال بیشتر صرف می‌شود و چرخه فروش کوتاه‌تر می‌شود. <div className="container min-w-0 w-full">
<div className="relative flex h-8 w-full items-center justify-center">
<DashedLine className="pointer-events-none absolute inset-x-0 top-1/2 -translate-y-1/2 text-muted-foreground" />
<span className="relative z-10 bg-secondary px-3 text-sm font-medium tracking-wide text-muted-foreground">
چرخه فروش
</span> </span>
</div> </div>
<div className="mx-auto mt-10 grid max-w-5xl gap-3 text-start lg:mt-24 lg:grid-cols-2"> <div className="mx-auto mt-10 grid w-full max-w-5xl gap-3 text-start lg:mt-24 lg:grid-cols-2">
<h2 className="text-xl font-semibold tracking-tight text-balance md:text-xl lg:text-2xll"> <h2 className="text-3xl font-semibold tracking-tight text-balance md:text-xl lg:text-2xll">
پیش‌بینی درآمد را دقیق‌تر کنید پیش‌بینی درآمد را دقیق‌تر کنید
</h2> </h2>
<p className="leading-snug font-medium text-pretty text-muted-foreground"> <p className="leading-snug font-medium text-pretty text-muted-foreground">
چرخه فروش را از سرنخ تا قرارداد در یک مسیر مشخص پیش ببرید. مدیران می‌توانند گلوگاه‌ها را ببینند و تیم‌ها با اولویت درست روی معاملات ارزشمند تمرکز کنند. چرخه فروش را از سرنخ تا قرارداد در یک مسیر مشخص پیش ببرید. مدیران می‌توانند
گلوگاه‌ها را ببینند و تیم‌ها با اولویت درست روی معاملات ارزشمند تمرکز کنند.
</p> </p>
</div> </div>
<Card className="mt-8 overflow-hidden rounded-2xl md:mt-12 lg:mt-20"> <Card className="mt-8 w-full gap-0! overflow-hidden rounded-2xl py-0! shadow-none ring-foreground/10 md:mt-12 lg:mt-20">
<CardContent className="flex p-0 max-lg:flex-col"> <CardContent className="flex w-full p-0! max-lg:flex-col">
{items.map((item, i) => ( {items.map((item, i) => (
<div key={item.title} className="flex flex-1 max-lg:flex-col"> <div
<div className="ps-6 pt-6 lg:ps-8 lg:pt-8"> key={item.title}
<div className="relative ps-4"> className="flex min-w-0 flex-1 max-lg:flex-col"
>
<div className="flex min-w-0 flex-1 flex-col ps-6 pt-6 lg:ps-8 lg:pt-8">
<div className="relative min-w-0 w-full ps-4">
<img <img
src={item.image} src={item.image}
alt={item.imageAlt} alt={item.imageAlt}
className="aspect-[1.28/1] overflow-hidden rounded-ts-xl object-cover" className="aspect-[1.28/1] h-auto w-full max-w-full rounded-ss-xl object-cover"
/> />
<div className="absolute inset-0 bg-linear-to-t from-background via-transparent to-transparent" /> <div className="pointer-events-none absolute inset-0 rounded-ss-xl bg-linear-to-t from-card via-transparent to-transparent" />
</div> </div>
<a <a
href="#" href="#"
className="group flex items-center justify-between gap-4 p-6 ps-0! lg:p-8" className="group flex items-center justify-between gap-4 py-6 pe-6 ps-0 lg:py-8 lg:pe-8"
> >
<h3 className="text-xl leading-tight font-semibold tracking-tight"> <h3 className="text-xl leading-tight font-semibold tracking-tight">
{item.title} {item.title}
</h3> </h3>
<ArrowDownRight className="size-6 shrink-0 rtl:rotate-180" /> <ArrowDownLeft className="size-6 shrink-0 transition-transform group-hover:translate-x-[-2px] group-hover:translate-y-[2px]" />
</a> </a>
</div> </div>
{i < items.length - 1 && ( {i < items.length - 1 ? (
<div className="relative hidden lg:block"> <>
<DashedLine orientation="vertical" /> <div className="relative hidden w-px shrink-0 self-stretch lg:block">
<DashedLine
orientation="vertical"
className="absolute inset-y-0 start-0 h-full"
/>
</div> </div>
)} <div className="relative block w-full shrink-0 py-2 lg:hidden">
{i < items.length - 1 && (
<div className="relative block lg:hidden">
<DashedLine orientation="horizontal" /> <DashedLine orientation="horizontal" />
</div> </div>
)} </>
) : null}
</div> </div>
))} ))}
</CardContent> </CardContent>
@@ -103,7 +114,7 @@ const DashedLine = ({
return ( return (
<div <div
className={cn( className={cn(
"relative text-muted-foreground", "text-muted-foreground",
isHorizontal ? "h-px w-full" : "h-full w-px", isHorizontal ? "h-px w-full" : "h-full w-px",
className, className,
)} )}
@@ -114,12 +125,12 @@ const DashedLine = ({
? [ ? [
"h-px w-full", "h-px w-full",
"bg-[repeating-linear-gradient(90deg,transparent,transparent_4px,currentColor_4px,currentColor_10px)]", "bg-[repeating-linear-gradient(90deg,transparent,transparent_4px,currentColor_4px,currentColor_10px)]",
"[mask-image:linear-gradient(90deg,transparent,black_25%,black_45%,transparent)]", "[mask-image:linear-gradient(90deg,transparent,black_20%,black_80%,transparent)]",
] ]
: [ : [
"h-full w-px", "h-full w-px",
"bg-[repeating-linear-gradient(180deg,transparent,transparent_4px,currentColor_4px,currentColor_8px)]", "bg-[repeating-linear-gradient(180deg,transparent,transparent_4px,currentColor_4px,currentColor_8px)]",
"[mask-image:linear-gradient(180deg,transparent,black_25%,black_45%,transparent)]", "[mask-image:linear-gradient(180deg,transparent,black_20%,black_80%,transparent)]",
], ],
)} )}
/> />
+104 -60
View File
@@ -57,29 +57,40 @@ interface Feature176Props {
const Feature176 = ({ className }: Feature176Props) => { const Feature176 = ({ className }: Feature176Props) => {
return ( return (
<section dir="rtl" lang="fa" className={cn("relative py-32", className)}> <section
dir="rtl"
lang="fa"
className={cn(
"relative w-full max-w-full overflow-x-hidden py-32",
className,
)}
>
<div className="absolute inset-0"> <div className="absolute inset-0">
<div className="absolute inset-0 bg-[radial-gradient(#e5e7eb_0.5px,transparent_0.5px)] bg-size-[16px_16px] opacity-20" /> <div className="absolute inset-0 bg-[radial-gradient(#e5e7eb_0.5px,transparent_0.5px)] bg-size-[16px_16px] opacity-20" />
<div className="absolute inset-0 bg-[radial-gradient(circle_at_center,transparent_0%,hsl(var(--background))_70%)]" /> <div className="absolute inset-0 bg-[radial-gradient(circle_at_center,transparent_0%,hsl(var(--background))_70%)]" />
<div className="absolute inset-0 bg-[linear-gradient(to_left,hsl(var(--muted-foreground)/10)_1px,transparent_1px),linear-gradient(to_bottom,hsl(var(--muted-foreground)/10)_1px,transparent_1px)] mask-[radial-gradient(circle_at_center,transparent_50%,hsl(var(--background))_100%)] bg-size-[32px_32px] opacity-20" /> <div className="absolute inset-0 bg-[linear-gradient(to_left,hsl(var(--muted-foreground)/10)_1px,transparent_1px),linear-gradient(to_bottom,hsl(var(--muted-foreground)/10)_1px,transparent_1px)] mask-[radial-gradient(circle_at_center,transparent_50%,hsl(var(--background))_100%)] bg-size-[32px_32px] opacity-20" />
</div> </div>
<div className="relative z-10 container mx-auto px-4"> <div className="relative z-10 container mx-auto min-w-0 px-4">
<div className="grid grid-cols-1 gap-8 md:grid-cols-2"> <div className="grid grid-cols-1 gap-6 lg:grid-cols-2 lg:gap-8">
<div className="flex h-fit flex-col gap-4 rounded-lg bg-background/50 p-4"> <div className="flex h-fit min-w-0 flex-col gap-4 rounded-lg bg-background/50 p-3 sm:p-4">
<div className="flex flex-row items-center gap-x-2 rounded-lg border bg-card p-4 shadow-sm"> <div className="flex min-w-0 flex-col gap-2 rounded-lg border bg-card p-3 shadow-sm sm:flex-row sm:items-center sm:gap-x-2 sm:p-4">
<ChartNoAxesColumnIncreasing className="size-6" /> <div className="flex min-w-0 items-center gap-x-2">
<h1 className="truncate text-xl font-bold sm:text-xl"> <ChartNoAxesColumnIncreasing className="size-5 shrink-0 sm:size-6" />
<h1 className="min-w-0 text-base font-bold text-pretty sm:truncate sm:text-xl">
با هوش مصنوعی سریع‌تر تصمیم بگیرید با هوش مصنوعی سریع‌تر تصمیم بگیرید
</h1> </h1>
<span className="ms-auto shrink-0 font-mono text-sm text-muted-foreground"> </div>
<span className="shrink-0 font-mono text-xs text-muted-foreground sm:ms-auto sm:text-sm">
Data/logs/3201927 Data/logs/3201927
</span> </span>
</div> </div>
<div className="rounded-lg border bg-card p-4 text-start shadow-sm"> <div className="min-w-0 rounded-lg border bg-card p-3 text-start shadow-sm sm:p-4">
<div className="flex flex-row items-center"> <div className="flex min-w-0 flex-col gap-2 sm:flex-row sm:items-center">
<h2 className="font-semibold">کارهای تکراری را به AI بسپارید</h2> <h2 className="min-w-0 font-semibold text-pretty">
<Badge className="ms-auto bg-green-300 text-green-600 hover:bg-green-300/80"> کارهای تکراری را به AI بسپارید
</h2>
<Badge className="h-auto max-w-full shrink whitespace-normal bg-green-300 text-green-600 hover:bg-green-300/80 sm:ms-auto">
پیشنهادهایی که واقعاً مفیدند پیشنهادهایی که واقعاً مفیدند
</Badge> </Badge>
</div> </div>
@@ -89,19 +100,32 @@ const Feature176 = ({ className }: Feature176Props) => {
</span> </span>
</div> </div>
<div className="flex flex-row items-center"> <div className="flex flex-row items-center">
<h2 className="font-semibold">داده را به بینش عملی تبدیل کنید</h2> <h2 className="font-semibold text-pretty">
داده را به بینش عملی تبدیل کنید
</h2>
</div> </div>
<div className="my-4 flex flex-row flex-wrap items-center gap-3"> <div className="my-4 flex flex-row flex-wrap items-center gap-2 sm:gap-3">
<Badge variant="secondary">تیم را با دستیار هوشمند تقویت کنید</Badge> <Badge
<Badge variant="secondary">پیشنهاد هوشمند</Badge> variant="secondary"
<Badge variant="secondary">اتوماسیون AI</Badge> className="h-auto max-w-full whitespace-normal"
>
تیم را با دستیار هوشمند تقویت کنید
</Badge>
<Badge variant="secondary" className="h-auto whitespace-normal">
پیشنهاد هوشمند
</Badge>
<Badge variant="secondary" className="h-auto whitespace-normal">
اتوماسیون AI
</Badge>
</div> </div>
<div> <div>
<div className="flex flex-row items-center"> <div className="flex min-w-0 flex-col gap-2 sm:flex-row sm:items-center">
<h2 className="font-semibold">فرایندها را با AI بهینه کنید</h2> <h2 className="min-w-0 font-semibold text-pretty">
فرایندها را با AI بهینه کنید
</h2>
<Progress <Progress
value={60} value={60}
className="ms-auto max-w-32 rounded-sm" className="w-full max-w-none rounded-sm sm:ms-auto sm:max-w-32"
/> />
</div> </div>
@@ -111,8 +135,8 @@ const Feature176 = ({ className }: Feature176Props) => {
<Skeleton className="h-1 w-full" /> <Skeleton className="h-1 w-full" />
</div> </div>
</div> </div>
<div className="mt-12 mb-4 flex items-center justify-between bg-card"> <div className="mt-8 mb-2 flex flex-col gap-3 bg-card sm:mt-12 sm:mb-4 sm:flex-row sm:items-center sm:justify-between">
<div className="flex gap-4"> <div className="flex min-w-0 flex-wrap gap-2 sm:gap-4">
<Button <Button
size="sm" size="sm"
variant="outline" variant="outline"
@@ -141,39 +165,49 @@ const Feature176 = ({ className }: Feature176Props) => {
</div> </div>
</div> </div>
<div> <div className="min-w-0">
<div className="mt-24 flex flex-col gap-4 rounded-lg bg-background/50 p-4"> <div className="mt-0 flex flex-col gap-4 rounded-lg bg-background/50 p-3 sm:p-4 lg:mt-24">
<div className="flex flex-row items-center gap-x-2 rounded-lg border bg-card p-4 shadow-sm"> <div className="flex min-w-0 flex-col gap-2 rounded-lg border bg-card p-3 shadow-sm sm:flex-row sm:items-center sm:gap-x-2 sm:p-4">
<ChartNoAxesColumnIncreasing className="size-6" /> <div className="flex min-w-0 items-center gap-x-2">
<h1 className="truncate text-xl font-bold sm:text-xl"> <ChartNoAxesColumnIncreasing className="size-5 shrink-0 sm:size-6" />
<h1 className="min-w-0 text-base font-bold text-pretty sm:truncate sm:text-xl">
با هوش مصنوعی سریع‌تر تصمیم بگیرید با هوش مصنوعی سریع‌تر تصمیم بگیرید
</h1> </h1>
<span className="ms-auto shrink-0 font-mono text-sm text-muted-foreground"> </div>
<span className="shrink-0 font-mono text-xs text-muted-foreground sm:ms-auto sm:text-sm">
Data/logs/182620 Data/logs/182620
</span> </span>
</div> </div>
<Card> <Card className="min-w-0 gap-0 overflow-hidden py-4">
<CardHeader className="flex flex-row items-center text-start"> <CardHeader className="flex flex-col gap-2 text-start sm:flex-row sm:items-center">
<CardTitle className="text-xl">پیشنهاد هوشمند</CardTitle> <CardTitle className="text-lg sm:text-xl">
<CardDescription className="ms-auto"> پیشنهاد هوشمند
</CardTitle>
<CardDescription className="sm:ms-auto">
<Badge className="bg-green-300 text-green-600 hover:bg-green-300/80"> <Badge className="bg-green-300 text-green-600 hover:bg-green-300/80">
اتوماسیون AI اتوماسیون AI
</Badge> </Badge>
</CardDescription> </CardDescription>
</CardHeader> </CardHeader>
<CardContent> <CardContent className="min-w-0 overflow-hidden px-3 sm:px-4">
<ChartContainer <ChartContainer
config={chartConfig} config={chartConfig}
className="h-[196px] w-full" className="aspect-auto! h-[180px] w-full min-w-0 sm:h-[196px]"
>
<BarChart
accessibilityLayer
data={chartData}
margin={{ left: 0, right: 0, top: 0, bottom: 0 }}
> >
<BarChart accessibilityLayer data={chartData}>
<CartesianGrid vertical={false} /> <CartesianGrid vertical={false} />
<XAxis <XAxis
dataKey="month" dataKey="month"
tickLine={false} tickLine={false}
tickMargin={10} tickMargin={8}
axisLine={false} axisLine={false}
interval="preserveStartEnd"
minTickGap={24}
tickFormatter={(value) => String(value).slice(0, 3)} tickFormatter={(value) => String(value).slice(0, 3)}
/> />
<ChartTooltip <ChartTooltip
@@ -187,41 +221,51 @@ const Feature176 = ({ className }: Feature176Props) => {
</CardContent> </CardContent>
</Card> </Card>
<div className="mt-4 flex flex-col rounded-lg border bg-background/50 p-4 text-start shadow-sm"> <div className="mt-2 flex min-w-0 flex-col rounded-lg border bg-background/50 p-3 text-start shadow-sm sm:mt-4 sm:p-4">
<div className="flex flex-row items-center"> <div className="flex min-w-0 flex-col gap-3 sm:flex-row sm:items-start">
<ChartCandlestick className="size-6 text-foreground/60" /> <ChartCandlestick className="size-6 shrink-0 text-foreground/60" />
<span className="ms-4 text-sm text-muted-foreground"> <span className="min-w-0 text-sm text-pretty text-muted-foreground sm:ms-4">
مدل‌های هوشمند الگوهای پنهان در داده فروش و پشتیبانی را پیدا می‌کنند. تیم‌ها با پیشنهادهای عملی، سریع‌تر اقدام می‌کنند. مدل‌های هوشمند الگوهای پنهان در داده فروش و پشتیبانی را پیدا
می‌کنند. تیم‌ها با پیشنهادهای عملی، سریع‌تر اقدام می‌کنند.
</span> </span>
</div> </div>
<div className="mt-4 grid gap-4 md:grid-cols-3"> <div className="mt-4 grid grid-cols-1 gap-3 sm:grid-cols-2 sm:gap-4 lg:grid-cols-3">
<div className="rounded-lg border bg-card p-4 shadow-sm"> <div className="min-w-0 rounded-lg border bg-card p-3 shadow-sm sm:p-4">
<div className="flex items-start justify-between"> <div className="flex items-start justify-between gap-2">
<h2 className="text-3xl font-bold">کارهای تکراری را به AI بسپارید</h2> <h2 className="min-w-0 text-base font-bold text-pretty sm:text-lg lg:text-xl">
<ArrowUpRight className="size-6 text-success rtl:rotate-180" /> کارهای تکراری را به AI بسپارید
</h2>
<ArrowUpRight className="size-5 shrink-0 text-success sm:size-6 rtl:rotate-180" />
</div> </div>
<p className="mt-2 text-sm text-muted-foreground"> <p className="mt-2 text-sm text-pretty text-muted-foreground">
از خلاصه‌سازی مکالمه تا پیشنهاد پاسخ، AI زمان کار دستی را کم می‌کند و کیفیت خروجی را بالا می‌برد. از خلاصه‌سازی مکالمه تا پیشنهاد پاسخ، AI زمان کار دستی را کم
می‌کند و کیفیت خروجی را بالا می‌برد.
</p> </p>
</div> </div>
<div className="rounded-lg border bg-card p-4 shadow-sm"> <div className="min-w-0 rounded-lg border bg-card p-3 shadow-sm sm:p-4">
<div className="flex items-start justify-between"> <div className="flex items-start justify-between gap-2">
<h2 className="text-3xl font-bold">پیشنهادهایی که واقعاً مفیدند</h2> <h2 className="min-w-0 text-base font-bold text-pretty sm:text-lg lg:text-xl">
<ArrowUpRight className="size-6 text-success rtl:rotate-180" /> پیشنهادهایی که واقعاً مفیدند
</h2>
<ArrowUpRight className="size-5 shrink-0 text-success sm:size-6 rtl:rotate-180" />
</div> </div>
<p className="mt-2 text-sm text-muted-foreground"> <p className="mt-2 text-sm text-pretty text-muted-foreground">
سیستم با داده سازمان شما یاد می‌گیرد و هر بار پیشنهادهای دقیق‌تری برای بهبود نتیجه ارائه می‌دهد. سیستم با داده سازمان شما یاد می‌گیرد و هر بار پیشنهادهای
دقیق‌تری برای بهبود نتیجه ارائه می‌دهد.
</p> </p>
</div> </div>
<div className="rounded-lg border bg-card p-4 shadow-sm"> <div className="min-w-0 rounded-lg border bg-card p-3 shadow-sm sm:col-span-2 sm:p-4 lg:col-span-1">
<div className="flex items-start justify-between"> <div className="flex items-start justify-between gap-2">
<h2 className="text-3xl font-bold">داده را به بینش عملی تبدیل کنید</h2> <h2 className="min-w-0 text-base font-bold text-pretty sm:text-lg lg:text-xl">
<ArrowUp className="size-6 text-success" /> داده را به بینش عملی تبدیل کنید
</h2>
<ArrowUp className="size-5 shrink-0 text-success sm:size-6" />
</div> </div>
<p className="mt-2 text-sm text-muted-foreground"> <p className="mt-2 text-sm text-pretty text-muted-foreground">
مدل‌های هوشمند الگوهای پنهان در داده فروش و پشتیبانی را پیدا می‌کنند. تیم‌ها با پیشنهادهای عملی، سریع‌تر اقدام می‌کنند. مدل‌های هوشمند الگوهای پنهان در داده فروش و پشتیبانی را پیدا
می‌کنند. تیم‌ها با پیشنهادهای عملی، سریع‌تر اقدام می‌کنند.
</p> </p>
</div> </div>
</div> </div>
+39 -43
View File
@@ -1,53 +1,33 @@
"use client"; "use client";
import { import { ArrowRight, Clock } from "lucide-react";
ArrowRight,
BadgeCheck,
Clock,
Pyramid,
Sparkle,
Zap,
} from "lucide-react";
import { Badge } from "@/components/ui/badge"; import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
interface DataItem { const DATA = [
title: string;
description: string;
image: string;
icon: React.ReactNode;
}
const DATA: DataItem[] = [
{ {
title: "موجودی انبار", title: "موجودی انبار",
description: description:
"محصولات را دسته‌بندی کنید و ویژگی‌ها را برای جستجوی بهتر ساختاردهی کنید.", "محصولات را دسته‌بندی کنید و ویژگی‌ها را برای جستجوی بهتر ساختاردهی کنید.",
image: "/block-media/shadcnblocks/block/placeholder-1.svg", duration: "۵ دقیقه",
icon: <Zap className="size-5" />,
}, },
{ {
title: "بازگشت مشتری", title: "بازگشت مشتری",
description: description: "پرداخت سریع و امن اعتماد مشتری را در لحظه خرید حفظ می‌کند.",
"پرداخت سریع و امن اعتماد مشتری را در لحظه خرید حفظ می‌کند.", duration: "۵ دقیقه",
image: "/block-media/shadcnblocks/block/placeholder-2.svg",
icon: <Pyramid className="size-5" />,
}, },
{ {
title: "صفحه فرود", title: "صفحه فرود",
description: description:
"وضعیت ارسال را شفاف نشان دهید و تماس‌های پشتیبانی را کم کنید.", "وضعیت ارسال را شفاف نشان دهید و تماس‌های پشتیبانی را کم کنید.",
image: "/block-media/shadcnblocks/block/placeholder-3.svg", duration: "۵ دقیقه",
icon: <Sparkle className="size-5" />,
}, },
{ {
title: "گزارش فروش", title: "گزارش فروش",
description: description: "کد تخفیف و کمپین را بر اساس رفتار خرید هدف بگیرید.",
"کد تخفیف و کمپین را بر اساس رفتار خرید هدف بگیرید.", duration: "۵ دقیقه",
image: "/block-media/shadcnblocks/block/placeholder-4.svg",
icon: <BadgeCheck className="size-5" />,
}, },
]; ];
@@ -57,40 +37,56 @@ interface Feature181Props {
const Feature181 = ({ className }: Feature181Props) => { const Feature181 = ({ className }: Feature181Props) => {
return ( return (
<section dir="rtl" lang="fa" className={cn("py-32", className)}> <section
<div className="container"> dir="rtl"
lang="fa"
className={cn(
"w-full max-w-full overflow-x-hidden py-32",
className,
)}
>
<div className="container min-w-0">
<div className="text-start"> <div className="text-start">
<h2 className="mb-6 text-3xl font-semibold text-balance lg:text-xl"> <h2 className="mb-6 text-3xl font-semibold text-balance md:text-4xl">
فروش آنلاین را مقیاس‌پذیر کنید فروش آنلاین را مقیاس‌پذیر کنید
</h2> </h2>
<Button className="me-4 rounded-full"> <Button className="rounded-full">
شروع کنید شروع کنید
<ArrowRight className="ms-2 size-4 rtl:rotate-180" /> <ArrowRight className="ms-2 size-4 rtl:rotate-180" />
</Button> </Button>
</div> </div>
<div className="mt-12 grid md:grid-cols-2 lg:grid-cols-4"> <div className="mt-12 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4">
{DATA.map((feature, index) => ( {DATA.map((feature, index) => (
<div <div
key={feature.title} key={feature.title}
className="mt-0 flex flex-col border-s px-6 sm:mt-4 md:mt-6" className={cn(
"flex min-w-0 flex-col px-4 py-8 sm:px-6 md:py-0 md:pt-6",
index < DATA.length - 1 && "border-b md:border-b-0",
"md:border-s",
)}
> >
<div className="relative"> <div className="relative min-w-0 overflow-hidden">
<h1 className="mb-16 bg-linear-to-e from-white to-transparent bg-clip-text text-9xl"> <p className="mb-10 text-6xl font-medium sm:mb-14 sm:text-8xl lg:mb-16 lg:text-9xl">
{(index + 1).toLocaleString("fa-IR", { {(index + 1).toLocaleString("fa-IR", {
minimumIntegerDigits: 2, minimumIntegerDigits: 2,
})} })}
</h1> </p>
<div className="absolute inset-0 bg-linear-to-e from-white to-transparent opacity-100" /> <div className="pointer-events-none absolute inset-0 bg-linear-to-e from-transparent to-background" />
</div> </div>
<p className="text-md mt-4 mb-2 font-semibold">{feature.title}</p> <p className="mt-2 mb-2 text-base font-semibold sm:mt-4">
<p className="text-md mb-6 text-pretty text-muted-foreground"> {feature.title}
</p>
<p className="mb-6 text-sm text-pretty text-muted-foreground sm:text-base">
{feature.description} {feature.description}
</p> </p>
<Badge variant="outline" className="w-fit gap-2 py-2"> <Badge
<Clock className="size-4" /> variant="outline"
مسیر خرید را بهینه کنید تا سبد رها شده کمتر شود. پیشنهاد هوشمند محصول، میانگین سفارش را بالا می‌برد. className="h-auto w-fit max-w-full gap-2 py-2 whitespace-normal"
>
<Clock className="size-4 shrink-0" />
{feature.duration}
</Badge> </Badge>
</div> </div>
))} ))}
+115 -60
View File
@@ -43,7 +43,12 @@ interface StatCardProps {
const StatCard = ({ title, value, description, className }: StatCardProps) => { const StatCard = ({ title, value, description, className }: StatCardProps) => {
return ( return (
<div className={cn("flex max-w-52 flex-col gap-4 text-start", className)}> <div
className={cn(
"flex w-full min-w-0 max-w-md flex-col gap-3 text-start sm:max-w-52 sm:gap-4",
className,
)}
>
<span className="font-medium">{title}</span> <span className="font-medium">{title}</span>
<div className="text-2xll font-bold"> <div className="text-2xll font-bold">
{value} {value}
@@ -54,6 +59,88 @@ const StatCard = ({ title, value, description, className }: StatCardProps) => {
); );
}; };
function FeatureCard({ className }: { className?: string }) {
return (
<div
className={cn(
"w-full min-w-0 rounded-2xl border bg-background p-4 text-start shadow-md",
className,
)}
>
<div className="flex min-w-0 flex-row items-start gap-2">
<h3 className="min-w-0 text-base font-semibold text-pretty sm:text-lg">
گردش تأیید
</h3>
<Badge variant="secondary" className="ms-auto shrink-0 rounded-sm">
ERP
</Badge>
</div>
<div className="mt-4">
<p className="text-sm text-pretty text-muted-foreground">
گزارش‌های یکپارچه نشان می‌دهد کدام بخش بیشترین تأثیر را روی سودآوری دارد.
</p>
</div>
</div>
);
}
const selectItemClassName =
"ps-8 pe-1.5 text-right [&_span.absolute]:right-auto [&_span.absolute]:left-2";
function ProductCard({ className }: { className?: string }) {
return (
<div
className={cn(
"w-full min-w-0 rounded-lg border bg-background p-4 text-start shadow-md",
className,
)}
>
<div className="flex flex-row border-b pb-4">
<h3 className="text-base font-semibold sm:text-lg">ERP</h3>
<div className="relative ms-auto">
<Badge variant="secondary" className="rounded-sm px-1">
<Plus className="size-4" />
</Badge>
</div>
</div>
<div className="mt-4 flex flex-col gap-4">
<Select dir="rtl">
<SelectTrigger className="w-full justify-between text-right">
<SelectValue placeholder="عملیات" />
</SelectTrigger>
<SelectContent dir="rtl" align="end" className="text-right">
<SelectItem value="category1" className={selectItemClassName}>
ERP
</SelectItem>
<SelectItem value="category2" className={selectItemClassName}>
ERP
</SelectItem>
<SelectItem value="category3" className={selectItemClassName}>
ERP
</SelectItem>
</SelectContent>
</Select>
<Select dir="rtl">
<SelectTrigger className="w-full justify-between text-right">
<SelectValue placeholder="ERP" />
</SelectTrigger>
<SelectContent dir="rtl" align="end" className="text-right">
<SelectItem value="sm" className={selectItemClassName}>
ERP
</SelectItem>
<SelectItem value="md" className={selectItemClassName}>
ERP
</SelectItem>
<SelectItem value="xl" className={selectItemClassName}>
مدیریت سازمان
</SelectItem>
</SelectContent>
</Select>
</div>
</div>
);
}
interface Feature183Props { interface Feature183Props {
className?: string; className?: string;
} }
@@ -63,33 +150,37 @@ const Feature183 = ({ className }: Feature183Props) => {
<section <section
dir="rtl" dir="rtl"
lang="fa" lang="fa"
className={cn("w-full min-w-0 overflow-x-clip pb-32", className)} className={cn(
"w-full min-w-0 max-w-full overflow-x-clip pb-16 sm:pb-24 lg:pb-32",
className,
)}
> >
<div className="container min-w-0"> <div className="container min-w-0 px-4 sm:px-6">
<div className="w-full min-w-0 shrink-0 pt-32"> <div className="w-full min-w-0 pt-16 sm:pt-24 lg:pt-32">
<div className="relative mx-auto h-96 w-full min-w-0 rounded-3xl bg-muted bg-cover bg-center bg-no-repeat sm:h-96"> <div className="relative mx-auto h-[22rem] w-full min-w-0 overflow-hidden rounded-3xl bg-muted bg-cover bg-center bg-no-repeat sm:h-[26rem] lg:h-96">
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
width="100%" width="100%"
height="100%" height="100%"
viewBox="0 0 4200 1080" viewBox="0 0 4200 1080"
fill="none" fill="none"
preserveAspectRatio="xMidYMid slice"
className="absolute inset-0 z-0 mask-[linear-gradient(to_bottom,transparent,white,transparent,transparent)] opacity-50" className="absolute inset-0 z-0 mask-[linear-gradient(to_bottom,transparent,white,transparent,transparent)] opacity-50"
aria-hidden="true" aria-hidden="true"
> >
<g clipPath="url(#clip0_4_5)"> <g clipPath="url(#clip0_feature183)">
<rect width="100%" height="1080" fill="none" /> <rect width="4200" height="1080" fill="none" />
{Array.from({ length: 5 }).map((_, index) => ( {Array.from({ length: 5 }).map((_, index) => (
<line <line
key={`horizontal-${index}`} key={`horizontal-${index}`}
y1={(index + 1) * 200 - 0.5} y1={(index + 1) * 200 - 0.5}
x2="100%" x2="4200"
y2={(index + 1) * 200 - 0.5} y2={(index + 1) * 200 - 0.5}
className="stroke-muted-foreground" className="stroke-muted-foreground"
strokeWidth="1" strokeWidth="1"
/> />
))} ))}
{Array.from({ length: 4000 }).map((_, index) => ( {Array.from({ length: 21 }).map((_, index) => (
<line <line
key={`vertical-${index}`} key={`vertical-${index}`}
x1={(index + 1) * 200 - 0.5} x1={(index + 1) * 200 - 0.5}
@@ -102,79 +193,43 @@ const Feature183 = ({ className }: Feature183Props) => {
))} ))}
</g> </g>
<defs> <defs>
<clipPath id="clip0_4_5"> <clipPath id="clip0_feature183">
<rect width="100%" height="1080" fill="white" /> <rect width="4200" height="1080" fill="white" />
</clipPath> </clipPath>
</defs> </defs>
</svg> </svg>
<div className="absolute -top-32 start-1/2 bottom-0 z-10 mt-12 w-[12.5rem] max-w-[calc(100%-2rem)] -translate-x-1/2 transform overflow-hidden sm:w-[18.75rem]"> <div className="absolute top-6 left-1/2 z-10 w-[9.5rem] max-w-[calc(100%-2rem)] -translate-x-1/2 overflow-hidden sm:top-8 sm:w-[14rem] lg:-top-28 lg:w-[18.75rem]">
<img <img
src="/block-media/shadcnblocks/block/hero108/iphone.png" src="/block-media/shadcnblocks/block/hero108/iphone.png"
alt="گزارش مالی یکپارچه" alt="گزارش مالی یکپارچه"
className="absolute top-0 z-20 block w-full" className="relative z-20 block h-auto w-full"
/> />
<img <img
src="/block-media/shadcnblocks/block/placeholder-dark-7-tall.svg" src="/block-media/shadcnblocks/block/placeholder-dark-7-tall.svg"
alt="داشبورد ERP" alt="داشبورد ERP"
className="absolute top-0 block w-full rounded-[50px]" className="absolute top-0 left-0 block w-full rounded-[2rem] sm:rounded-[40px] lg:rounded-[50px]"
/> />
</div> </div>
<div className="absolute top-12 end-[max(1rem,12%)] z-20 hidden w-60 max-w-[min(15rem,42%)] transform rounded-2xl border bg-background p-4 text-start shadow-md md:-rotate-12 lg:block"> <div className="absolute top-10 end-[max(0.75rem,8%)] z-20 hidden w-56 max-w-[min(14rem,38%)] -rotate-6 transform lg:block lg:w-60 lg:max-w-[min(15rem,42%)] lg:-rotate-12">
<div className="flex flex-row"> <FeatureCard />
<h3 className="text-lg font-semibold">گردش تأیید</h3>
<Badge variant="secondary" className="ms-auto rounded-sm">
ERP
</Badge>
</div> </div>
<div className="mt-4">
<p className="text-sm text-pretty text-muted-foreground"> <div className="absolute top-10 start-[max(0.75rem,8%)] z-20 hidden w-56 max-w-[min(14rem,38%)] transform lg:block lg:w-60 lg:max-w-[min(15rem,42%)]">
گزارش‌های یکپارچه نشان می‌دهد کدام بخش بیشترین تأثیر را روی سودآوری دارد. <ProductCard />
</p>
</div> </div>
</div> </div>
<div className="absolute top-12 start-[max(1rem,12%)] z-20 hidden w-60 max-w-[min(15rem,42%)] transform rounded-lg border bg-background p-4 text-start shadow-md lg:block"> <div className="mt-6 grid grid-cols-1 gap-4 sm:mt-8 sm:grid-cols-2 lg:hidden">
<div className="flex flex-row border-b pb-4"> <FeatureCard />
<h3 className="text-lg font-semibold">ERP</h3> <ProductCard />
<div className="relative ms-auto">
<Badge variant="secondary" className="rounded-sm px-1">
<Plus className="size-4" />
</Badge>
</div>
</div>
<div className="mt-4 flex flex-col gap-4">
<Select>
<SelectTrigger className="w-full">
<SelectValue placeholder="عملیات" />
</SelectTrigger>
<SelectContent>
<SelectItem value="category1">ERP</SelectItem>
<SelectItem value="category2">ERP</SelectItem>
<SelectItem value="category3">ERP</SelectItem>
</SelectContent>
</Select>
<div className="flex flex-col gap-2">
<Select>
<SelectTrigger className="w-full">
<SelectValue placeholder="ERP" />
</SelectTrigger>
<SelectContent>
<SelectItem value="sm">ERP</SelectItem>
<SelectItem value="md">ERP</SelectItem>
<SelectItem value="xl">مدیریت سازمان</SelectItem>
</SelectContent>
</Select>
</div>
</div>
</div>
</div> </div>
</div> </div>
<div className="mt-14 flex min-w-0 flex-col items-center justify-center gap-x-24 gap-y-8 lg:flex-row"> <div className="mt-10 grid min-w-0 grid-cols-1 justify-items-stretch gap-8 sm:mt-14 sm:grid-cols-3 sm:justify-items-center lg:gap-x-16">
{DATA.map((item) => ( {DATA.map((item) => (
<StatCard key={item.title} {...item} /> <StatCard key={item.title} {...item} className="sm:mx-auto" />
))} ))}
</div> </div>
</div> </div>
+38 -27
View File
@@ -13,21 +13,21 @@ const FEATURES = [
description: "گزارش سفارشی را بدون SQL بسازید و سریع منتشر کنید.", description: "گزارش سفارشی را بدون SQL بسازید و سریع منتشر کنید.",
image: "/block-media/shadcnblocks/block/placeholder-1.svg", image: "/block-media/shadcnblocks/block/placeholder-1.svg",
imageAlt: "گزارش‌ساز", imageAlt: "گزارش‌ساز",
icon: <Workflow />, icon: <Workflow className="size-5 sm:size-6" />,
}, },
{ {
title: "Pivot تعاملی", title: "Pivot تعاملی",
description: "ابعاد مختلف را بچرخانید و الگوی پنهان را پیدا کنید.", description: "ابعاد مختلف را بچرخانید و الگوی پنهان را پیدا کنید.",
image: "/block-media/shadcnblocks/block/placeholder-2.svg", image: "/block-media/shadcnblocks/block/placeholder-2.svg",
imageAlt: "تحلیل داده سازمان", imageAlt: "تحلیل داده سازمان",
icon: <Users />, icon: <Users className="size-5 sm:size-6" />,
}, },
{ {
title: "داشبورد مدیریتی", title: "داشبورد مدیریتی",
description: "نمای اجرایی برای تصمیم‌های سریع طراحی کنید.", description: "نمای اجرایی برای تصمیم‌های سریع طراحی کنید.",
image: "/block-media/shadcnblocks/block/placeholder-3.svg", image: "/block-media/shadcnblocks/block/placeholder-3.svg",
imageAlt: "داشبورد هوش تجاری", imageAlt: "داشبورد هوش تجاری",
icon: <Flag />, icon: <Flag className="size-5 sm:size-6" />,
}, },
]; ];
@@ -41,54 +41,62 @@ const Feature184 = ({ className }: Feature184Props) => {
const activeFeature = FEATURES.find((f) => f.title === activeTab); const activeFeature = FEATURES.find((f) => f.title === activeTab);
return ( return (
<section dir="rtl" lang="fa" className={cn("py-20 md:py-32", className)}> <section
<div className="container mx-auto flex flex-col items-center px-4 sm:px-6 lg:px-8"> dir="rtl"
<div className="mb-12 max-w-3xl text-center"> lang="fa"
className={cn(
"w-full max-w-full overflow-x-hidden py-20 md:py-32",
className,
)}
>
<div className="container mx-auto flex min-w-0 flex-col items-center px-4 sm:px-6 lg:px-8">
<div className="mb-8 w-full max-w-3xl text-center sm:mb-12">
<h2 className="text-xl leading-tight font-semibold tracking-tight text-balance sm:text-3xl md:text-xl lg:text-2xll"> <h2 className="text-xl leading-tight font-semibold tracking-tight text-balance sm:text-3xl md:text-xl lg:text-2xll">
تصمیم استراتژیک را داده‌محور کنید تصمیم استراتژیک را داده‌محور کنید
</h2> </h2>
</div> </div>
<div className="grid gap-8 lg:grid-cols-2"> <div className="grid w-full min-w-0 gap-6 sm:gap-8 lg:grid-cols-2">
<div className="relative h-[300px] overflow-hidden rounded-xl sm:h-[420px]"> <div className="relative h-[220px] min-w-0 overflow-hidden rounded-xl sm:h-[300px] md:h-[420px]">
<img <img
src={activeFeature?.image} src={activeFeature?.image}
alt={activeFeature?.imageAlt ?? activeTab} alt={activeFeature?.imageAlt ?? activeTab}
className="h-full w-full object-cover" className="h-full w-full max-w-full object-cover"
/> />
</div> </div>
<div className="relative flex flex-col justify-between"> <div className="relative flex min-w-0 flex-col justify-between">
<Tabs <Tabs
defaultValue={FEATURES[0].title} value={activeTab}
onValueChange={(value) => setActiveTab(value)} onValueChange={setActiveTab}
className="h-full w-full" className="h-full w-full min-w-0"
> >
<TabsList className="flex !h-full w-full flex-col gap-4 rounded-xl border-none bg-transparent p-0"> <TabsList className="flex !h-auto w-full min-w-0 flex-col gap-3 rounded-xl border-none bg-transparent p-0 sm:gap-4">
{FEATURES.map((feature) => ( {FEATURES.map((feature) => (
<TabsTrigger <TabsTrigger
key={feature.title} key={feature.title}
value={feature.title} value={feature.title}
className={cn( className={cn(
"group relative flex h-full w-full flex-col items-start rounded-xl p-6 text-start transition-all", "group relative flex h-auto w-full min-w-0 flex-col items-stretch rounded-xl p-4 text-start whitespace-normal transition-all sm:p-6",
"border border-border/50 bg-card hover:border-primary/50", "border border-border/50 bg-card hover:border-primary/50",
"data-[state=active]:z-20 data-[state=active]:scale-[1.02] data-[state=active]:border-primary data-[state=active]:bg-primary/95 data-[state=active]:shadow-lg", "data-[state=active]:z-10 data-[state=active]:border-primary data-[state=active]:bg-primary/95 data-[state=active]:shadow-lg",
"sm:data-[state=active]:scale-[1.02]",
)} )}
> >
<div className="flex w-full items-center justify-between"> <div className="flex w-full min-w-0 items-start gap-3 sm:items-center sm:justify-between sm:gap-4">
<div className="flex items-center gap-6"> <div className="flex min-w-0 flex-1 items-start gap-3 sm:items-center sm:gap-6">
<div <div
className={cn( className={cn(
"rounded-lg bg-muted p-4 transition-colors", "shrink-0 rounded-lg bg-muted p-2.5 transition-colors sm:p-4",
"group-data-[state=active]:bg-background", "group-data-[state=active]:bg-background",
)} )}
> >
{feature.icon} {feature.icon}
</div> </div>
<div className="flex flex-col gap-2 text-start"> <div className="flex min-w-0 flex-col gap-1.5 text-start sm:gap-2">
<h3 <h3
className={cn( className={cn(
"text-xl font-medium", "text-base font-medium text-pretty sm:text-xl",
"group-data-[state=active]:text-primary-foreground", "group-data-[state=active]:text-primary-foreground",
)} )}
> >
@@ -96,7 +104,7 @@ const Feature184 = ({ className }: Feature184Props) => {
</h3> </h3>
<span <span
className={cn( className={cn(
"text-sm text-muted-foreground transition-colors", "text-sm text-pretty text-muted-foreground transition-colors",
"group-data-[state=active]:text-primary-foreground/90", "group-data-[state=active]:text-primary-foreground/90",
)} )}
> >
@@ -104,7 +112,7 @@ const Feature184 = ({ className }: Feature184Props) => {
</span> </span>
</div> </div>
</div> </div>
<div className="ps-8"> <div className="shrink-0 pt-1 sm:ps-4 sm:pt-0">
<ChevronUp <ChevronUp
className={cn( className={cn(
"size-5 text-muted-foreground transition-all duration-300", "size-5 text-muted-foreground transition-all duration-300",
@@ -120,14 +128,17 @@ const Feature184 = ({ className }: Feature184Props) => {
</div> </div>
</div> </div>
<div className="mt-12 flex flex-col items-center justify-center gap-4 sm:flex-row"> <div className="mt-10 flex w-full min-w-0 flex-col items-stretch justify-center gap-3 sm:mt-12 sm:flex-row sm:items-center sm:gap-4">
<Button className="w-full gap-2 sm:w-auto"> <Button className="w-full gap-2 sm:w-auto">
<Zap className="size-4" /> <Zap className="size-4" />
شروع کنید شروع کنید
</Button> </Button>
<Button variant="outline" className="w-full gap-2 sm:w-auto"> <Button
<Pyramid className="size-4" /> variant="outline"
داشبوردهای تعاملی به تیم‌ها اجازه می‌دهد سؤال جدید بپرسند بدون اینکه هر بار به تیم داده وابسته باشند. className="h-auto w-full gap-2 whitespace-normal px-4 py-2 text-pretty sm:w-auto"
>
<Pyramid className="size-4 shrink-0" />
بیشتر بدانید
</Button> </Button>
</div> </div>
</div> </div>
+47 -36
View File
@@ -24,15 +24,16 @@ const DATA: DataItem[] = [
"تاریخچه تماس، قرارداد و تیکت هر مشتری را در یک صفحه ببینید و بدون جستجو تصمیم بگیرید.", "تاریخچه تماس، قرارداد و تیکت هر مشتری را در یک صفحه ببینید و بدون جستجو تصمیم بگیرید.",
image: "/block-media/shadcnblocks/block/placeholder-dark-1.svg", image: "/block-media/shadcnblocks/block/placeholder-dark-1.svg",
imageAlt: "داشبورد مدیریت ارتباط با مشتری", imageAlt: "داشبورد مدیریت ارتباط با مشتری",
icon: <Sparkles className="h-6 w-6 text-white" />, icon: <Sparkles className="size-5 text-white sm:size-6" />,
}, },
{ {
id: "feature-2", id: "feature-2",
title: "اتوماسیون مراحل فروش", title: "اتوماسیون مراحل فروش",
description: "وظایف تکراری فروش را خودکار کنید و تمرکز تیم را روی بستن معامله بگذارید.", description:
"وظایف تکراری فروش را خودکار کنید و تمرکز تیم را روی بستن معامله بگذارید.",
image: "/block-media/shadcnblocks/block/placeholder-dark-2.svg", image: "/block-media/shadcnblocks/block/placeholder-dark-2.svg",
imageAlt: "نمای پایپ‌لاین فروش", imageAlt: "نمای پایپ‌لاین فروش",
icon: <Database className="h-6 w-6 text-white" />, icon: <Database className="size-5 text-white sm:size-6" />,
}, },
{ {
id: "feature-3", id: "feature-3",
@@ -41,7 +42,7 @@ const DATA: DataItem[] = [
"بر اساس داده واقعی پایپ‌لاین، درآمد ماه‌های آینده را با اطمینان بیشتر تخمین بزنید.", "بر اساس داده واقعی پایپ‌لاین، درآمد ماه‌های آینده را با اطمینان بیشتر تخمین بزنید.",
image: "/block-media/shadcnblocks/block/placeholder-dark-3.svg", image: "/block-media/shadcnblocks/block/placeholder-dark-3.svg",
imageAlt: "پروفایل یکپارچه مشتری", imageAlt: "پروفایل یکپارچه مشتری",
icon: <LockKeyhole className="h-6 w-6 text-white" />, icon: <LockKeyhole className="size-5 text-white sm:size-6" />,
}, },
]; ];
@@ -53,86 +54,96 @@ const Feature186 = ({ className }: Feature186Props) => {
const [selection, setSelection] = useState(DATA[0].id); const [selection, setSelection] = useState(DATA[0].id);
return ( return (
<section dir="rtl" lang="fa" className={cn("relative py-16 md:py-32", className)}> <section
dir="rtl"
lang="fa"
className={cn(
"relative w-full max-w-full overflow-x-hidden py-16 md:py-32",
className,
)}
>
<div <div
className="absolute top-0 right-0 left-0 z-0 h-[800px] w-screen [mask-image:radial-gradient(ellipse_at_center,white_20%,transparent_70%)] bg-repeat opacity-30" className="absolute inset-x-0 top-0 z-0 h-[min(800px,100%)] w-full [mask-image:radial-gradient(ellipse_at_center,white_20%,transparent_70%)] bg-repeat opacity-30"
style={{ style={{
backgroundImage: backgroundImage:
"url('/block-media/shadcnblocks/block/patterns/architect.svg')", "url('/block-media/shadcnblocks/block/patterns/architect.svg')",
backgroundSize: "60px", backgroundSize: "60px",
}} }}
/> />
<div className="relative z-10 container"> <div className="relative z-10 container min-w-0 px-4 sm:px-6">
<div className="text-right"> <div className="min-w-0 text-right">
<h2 className="text-xl font-medium text-balance sm:text-2xll lg:text-2xll"> <h2 className="text-xl font-medium text-balance sm:text-2xll lg:text-2xll">
هر سرنخ را تا قرارداد دنبال کنید هر سرنخ را تا قرارداد دنبال کنید
</h2> </h2>
<p className="mt-4 text-pretty text-muted-foreground md:text-lg"> <p className="mt-4 max-w-3xl text-sm text-pretty text-muted-foreground sm:text-base md:text-lg">
تمام تعاملات، سرنخ‌ها و قراردادها در یک فضای کاری متمرکز جمع می‌شود. تیم فروش بدون جابجایی بین ابزارها، سریع‌تر پیش‌بینی می‌کند و معاملات بیشتری می‌بندد. تمام تعاملات، سرنخ‌ها و قراردادها در یک فضای کاری متمرکز جمع می‌شود.
تیم فروش بدون جابجایی بین ابزارها، سریع‌تر پیش‌بینی می‌کند و معاملات
بیشتری می‌بندد.
</p> </p>
<div className="mt-4 lg:mt-8"> <div className="mt-6 min-w-0 lg:mt-8">
<Tabs dir="rtl" value={selection} onValueChange={setSelection}> <Tabs
<div className="relative">
<div className="overflow-auto">
<div
dir="rtl" dir="rtl"
className="flex min-w-fit flex-col items-start overflow-y-hidden lg:mb-8" value={selection}
onValueChange={setSelection}
className="w-full min-w-0 gap-4"
> >
<TabsList className="gap-4 bg-transparent"> <TabsList className="flex h-auto! w-full min-w-0 flex-wrap justify-start gap-2 bg-transparent p-0 sm:gap-3">
{DATA.map((feature) => ( {DATA.map((feature) => (
<TabsTrigger key={feature.id} value={feature.id}> <TabsTrigger
key={feature.id}
value={feature.id}
className="h-auto! flex-none max-w-full px-3 py-2 text-xs whitespace-normal sm:text-sm"
>
{feature.title} {feature.title}
</TabsTrigger> </TabsTrigger>
))} ))}
</TabsList> </TabsList>
</div>
<div className="pointer-events-none absolute inset-0 bg-[linear-gradient(to_left,hsl(var(--background))_0%,transparent_10%,transparent_90%,hsl(var(--background))_100%)] md:hidden" />
</div>
</div>
<div className="relative w-full overflow-hidden"> <div className="relative w-full min-w-0">
{DATA.map((feature) => ( {DATA.map((feature) => (
<TabsContent <TabsContent
key={feature.id} key={feature.id}
value={feature.id} value={feature.id}
className="relative z-20" className="mt-0 min-w-0"
> >
<div className="aspect-3/2 w-full rounded-lg bg-accent p-6 md:p-14 md:px-24"> <div className="flex w-full min-w-0 flex-col gap-4 rounded-lg bg-accent p-4 sm:gap-6 sm:p-6 md:p-10 lg:p-14 lg:px-24">
<div className="max-w-full text-right md:max-w-md"> <div className="w-full min-w-0 max-w-md text-right">
<div className="flex size-12 items-center justify-center rounded-full bg-black"> <div className="flex size-10 items-center justify-center rounded-full bg-black sm:size-12">
{feature.icon} {feature.icon}
</div> </div>
<div className="my-4 md:my-8"> <div className="mt-4 space-y-2 sm:mt-6 md:mt-8">
<h3 className="text-lg font-bold sm:text-xl lg:text-xl"> <h3 className="text-lg font-bold text-pretty sm:text-xl">
{feature.title} {feature.title}
</h3> </h3>
<p className="text-base text-pretty text-muted-foreground sm:text-lg lg:text-xl"> <p className="text-sm text-pretty text-muted-foreground sm:text-base lg:text-lg">
{feature.description} {feature.description}
</p> </p>
</div> </div>
</div> </div>
<div className="w-full min-w-0 overflow-hidden rounded-lg">
<img <img
src={feature.image} src={feature.image}
alt={feature.imageAlt} alt={feature.imageAlt}
className="mt-4 h-full w-full rounded-lg object-cover object-center md:mt-0" className="aspect-video h-auto w-full max-w-full object-cover object-center sm:aspect-[16/10]"
/> />
</div> </div>
</div>
</TabsContent> </TabsContent>
))} ))}
</div> </div>
<div className="flex justify-center py-3 md:hidden"> <div className="flex justify-center gap-1 py-1 sm:hidden">
{DATA.map((feature) => ( {DATA.map((feature) => (
<Button <Button
key={feature.id} key={feature.id}
variant="ghost" variant="ghost"
size="sm" size="sm"
onClick={() => { className="size-8 px-0"
setSelection(feature.id); aria-label={feature.title}
}} onClick={() => setSelection(feature.id)}
> >
<div <span
className={cn( className={cn(
"size-2 rounded-full", "size-2 rounded-full",
feature.id === selection ? "bg-primary" : "bg-input", feature.id === selection ? "bg-primary" : "bg-input",
+29 -19
View File
@@ -93,27 +93,32 @@ interface Feature19Props {
const Feature19 = ({ className }: Feature19Props) => { const Feature19 = ({ className }: Feature19Props) => {
return ( return (
<section dir="rtl" lang="fa" className={cn("py-32", className)}> <section
<div className="container"> dir="rtl"
<div className="mx-auto flex max-w-3xl flex-col items-center gap-6"> lang="fa"
<h2 className="text-center text-3xl font-semibold lg:text-2xll"> className={cn("w-full overflow-hidden py-32", className)}
>
<div className="container min-w-0">
<div className="mx-auto flex min-w-0 max-w-3xl flex-col items-center gap-6">
<h2 className="max-w-full text-center text-3xl font-semibold text-balance break-words lg:text-2xll">
با هوش مصنوعی سریع‌تر تصمیم بگیرید با هوش مصنوعی سریع‌تر تصمیم بگیرید
</h2> </h2>
<p className="text-center text-balance text-muted-foreground lg:text-xl"> <p className="max-w-full text-center text-balance break-words text-muted-foreground lg:text-xl">
مدل‌های هوشمند الگوهای پنهان در داده فروش و پشتیبانی را پیدا می‌کنند. تیم‌ها با پیشنهادهای عملی، سریع‌تر اقدام می‌کنند. مدل‌های هوشمند الگوهای پنهان در داده فروش و پشتیبانی را پیدا می‌کنند.
تیم‌ها با پیشنهادهای عملی، سریع‌تر اقدام می‌کنند.
</p> </p>
</div> </div>
<div className="mt-12 flex justify-start"> <div className="mt-12 flex min-w-0 justify-start">
<Tabs <Tabs
dir="rtl" dir="rtl"
defaultValue="1" defaultValue="1"
className="flex w-full max-w-5xl flex-col items-start gap-8 md:gap-12" className="flex w-full min-w-0 max-w-5xl flex-col items-start gap-8 md:gap-12"
> >
<div <div
dir="rtl" dir="rtl"
className="flex w-full justify-start overflow-x-auto overflow-y-hidden" className="w-full min-w-0 max-w-full overflow-x-auto overflow-y-hidden"
> >
<TabsList className="w-max whitespace-nowrap"> <TabsList className="w-max max-w-none whitespace-nowrap">
{slides.map((slide) => ( {slides.map((slide) => (
<TabsTrigger key={slide.id} value={slide.id.toString()}> <TabsTrigger key={slide.id} value={slide.id.toString()}>
{slide.tabName} {slide.tabName}
@@ -125,24 +130,29 @@ const Feature19 = ({ className }: Feature19Props) => {
<TabsContent <TabsContent
value={slide.id.toString()} value={slide.id.toString()}
key={slide.id} key={slide.id}
className="w-full" className="w-full min-w-0"
> >
<div <div
dir="rtl" dir="rtl"
className="grid grid-cols-1 items-center gap-10 md:grid-cols-2" className="grid min-w-0 grid-cols-1 items-center gap-10 md:grid-cols-2"
> >
<div className="flex flex-col items-start text-right"> <div className="flex min-w-0 flex-col items-start text-right">
<h2 className="mb-4 text-xl font-semibold lg:text-xl"> <h2 className="mb-4 max-w-full text-xl font-semibold break-words lg:text-xl">
{slide.title} {slide.title}
</h2> </h2>
<p className="text-muted-foreground lg:text-xl"> <p className="max-w-full text-pretty break-words text-muted-foreground lg:text-xl">
{slide.description} {slide.description}
</p> </p>
<ul className="mt-8 grid w-full grid-cols-1 gap-2 lg:grid-cols-2"> <ul className="mt-8 grid w-full min-w-0 grid-cols-1 gap-2 lg:grid-cols-2">
{slide.features.map((feature) => ( {slide.features.map((feature) => (
<li key={feature} className="flex items-center gap-2"> <li
key={feature}
className="flex min-w-0 items-center gap-2"
>
<CheckCircle2 className="size-4 shrink-0" /> <CheckCircle2 className="size-4 shrink-0" />
<span className="font-medium">{feature}</span> <span className="min-w-0 font-medium break-words">
{feature}
</span>
</li> </li>
))} ))}
</ul> </ul>
@@ -156,7 +166,7 @@ const Feature19 = ({ className }: Feature19Props) => {
<img <img
src={slide.image} src={slide.image}
alt={slide.title} alt={slide.title}
className="order-first max-h-[400px] w-full rounded-lg object-cover md:order-0" className="order-first max-h-[400px] w-full max-w-full rounded-lg object-cover md:order-0"
/> />
</div> </div>
</TabsContent> </TabsContent>
+26 -14
View File
@@ -14,21 +14,24 @@ const DATA: Feature[] = [
{ {
id: "analytics-dashboard", id: "analytics-dashboard",
title: "گزارش زمان‌بندی‌شده", title: "گزارش زمان‌بندی‌شده",
description: "ویجت‌های موردنیاز هر تیم را بچینید و فقط معیارهای مرتبط را ببینید.", description:
"ویجت‌های موردنیاز هر تیم را بچینید و فقط معیارهای مرتبط را ببینید.",
imageUrl: "/block-media/shadcnblocks/block/block-1.svg", imageUrl: "/block-media/shadcnblocks/block/block-1.svg",
imageAlt: "گزارش عملکرد", imageAlt: "گزارش عملکرد",
}, },
{ {
id: "team-collaboration", id: "team-collaboration",
title: "تحلیل کوHORT", title: "تحلیل کوHORT",
description: "داده را بر اساس محصول، منطقه یا کانال برش دهید و الگو پیدا کنید.", description:
"داده را بر اساس محصول، منطقه یا کانال برش دهید و الگو پیدا کنید.",
imageUrl: "/block-media/shadcnblocks/block/block-2.svg", imageUrl: "/block-media/shadcnblocks/block/block-2.svg",
imageAlt: "داشبورد تحلیل داده", imageAlt: "داشبورد تحلیل داده",
}, },
{ {
id: "third-party-integrations", id: "third-party-integrations",
title: "مقایسه دوره‌ای", title: "مقایسه دوره‌ای",
description: "تغییرات مهم را در طول زمان دنبال کنید و نقطه عطف را شناسایی کنید.", description:
"تغییرات مهم را در طول زمان دنبال کنید و نقطه عطف را شناسایی کنید.",
imageUrl: "/block-media/shadcnblocks/block/block-3.svg", imageUrl: "/block-media/shadcnblocks/block/block-3.svg",
imageAlt: "نمودار شاخص کلیدی", imageAlt: "نمودار شاخص کلیدی",
}, },
@@ -42,21 +45,24 @@ const DATA: Feature[] = [
{ {
id: "automated-workflows", id: "automated-workflows",
title: "داشبورد سفارشی", title: "داشبورد سفارشی",
description: "ویجت‌های موردنیاز هر تیم را بچینید و فقط معیارهای مرتبط را ببینید.", description:
"ویجت‌های موردنیاز هر تیم را بچینید و فقط معیارهای مرتبط را ببینید.",
imageUrl: "/block-media/shadcnblocks/block/block-5.svg", imageUrl: "/block-media/shadcnblocks/block/block-5.svg",
imageAlt: "داشبورد تحلیل داده", imageAlt: "داشبورد تحلیل داده",
}, },
{ {
id: "data-security", id: "data-security",
title: "فیلتر پیشرفته", title: "فیلتر پیشرفته",
description: "داده را بر اساس محصول، منطقه یا کانال برش دهید و الگو پیدا کنید.", description:
"داده را بر اساس محصول، منطقه یا کانال برش دهید و الگو پیدا کنید.",
imageUrl: "/block-media/shadcnblocks/block/block-6.svg", imageUrl: "/block-media/shadcnblocks/block/block-6.svg",
imageAlt: "نمودار شاخص کلیدی", imageAlt: "نمودار شاخص کلیدی",
}, },
{ {
id: "customer-support", id: "customer-support",
title: "نمودار روند", title: "نمودار روند",
description: "تغییرات مهم را در طول زمان دنبال کنید و نقطه عطف را شناسایی کنید.", description:
"تغییرات مهم را در طول زمان دنبال کنید و نقطه عطف را شناسایی کنید.",
imageUrl: "/block-media/shadcnblocks/block/block-3.svg", imageUrl: "/block-media/shadcnblocks/block/block-3.svg",
imageAlt: "گزارش عملکرد", imageAlt: "گزارش عملکرد",
}, },
@@ -70,7 +76,8 @@ const DATA: Feature[] = [
{ {
id: "scalable-infrastructure", id: "scalable-infrastructure",
title: "گزارش زمان‌بندی‌شده", title: "گزارش زمان‌بندی‌شده",
description: "ویجت‌های موردنیاز هر تیم را بچینید و فقط معیارهای مرتبط را ببینید.", description:
"ویجت‌های موردنیاز هر تیم را بچینید و فقط معیارهای مرتبط را ببینید.",
imageUrl: "/block-media/shadcnblocks/block/block-4.svg", imageUrl: "/block-media/shadcnblocks/block/block-4.svg",
imageAlt: "نمودار شاخص کلیدی", imageAlt: "نمودار شاخص کلیدی",
}, },
@@ -82,28 +89,33 @@ interface Feature190Props {
const Feature190 = ({ className }: Feature190Props) => { const Feature190 = ({ className }: Feature190Props) => {
return ( return (
<section dir="rtl" lang="fa" className={cn("py-32", className)}> <section
<div className="container"> dir="rtl"
lang="fa"
className={cn("w-full max-w-full overflow-x-hidden py-32", className)}
>
<div className="container min-w-0">
<div className="flex flex-col items-center text-center"> <div className="flex flex-col items-center text-center">
<h2 className="mb-4 text-xl font-semibold tracking-tight text-balance sm:text-2xll"> <h2 className="mb-4 text-xl font-semibold tracking-tight text-balance sm:text-2xll">
داده پراکنده را به تصمیم تبدیل کنید داده پراکنده را به تصمیم تبدیل کنید
</h2> </h2>
<p className="mb-8 max-w-3xl text-lg text-pretty text-muted-foreground sm:text-xl"> <p className="mb-8 max-w-3xl text-lg text-pretty text-muted-foreground sm:text-xl">
گزارش‌های بصری نشان می‌دهند کدام اقدام بیشترین اثر را روی درآمد و نگهداشت مشتری داشته است. گزارش‌های بصری نشان می‌دهند کدام اقدام بیشترین اثر را روی درآمد و
نگهداشت مشتری داشته است.
</p> </p>
</div> </div>
<div className="grid md:grid-cols-2 lg:grid-cols-3"> <div className="grid min-w-0 md:grid-cols-2 lg:grid-cols-3">
{DATA.map((feature) => ( {DATA.map((feature) => (
<Card <Card
key={feature.id} key={feature.id}
className="mt-6 flex items-center rounded-none border-0 border-b border-muted pb-6 shadow-none" className="mt-6 flex min-w-0 flex-row items-center gap-0 rounded-none border-0 border-b border-muted py-0! pb-6 shadow-none ring-0"
> >
<a href="#" className="shrink-0 hover:opacity-70"> <a href="#" className="shrink-0 hover:opacity-70">
<img <img
src={feature.imageUrl} src={feature.imageUrl}
alt={feature.imageAlt} alt={feature.imageAlt}
className="me-4 h-16 w-16 rounded-md bg-muted object-contain p-2" className="me-4 size-16 rounded-md bg-muted object-contain p-2"
/> />
</a> </a>
<div className="min-w-0 grow text-start"> <div className="min-w-0 grow text-start">
@@ -118,7 +130,7 @@ const Feature190 = ({ className }: Feature190Props) => {
<div className="mt-12 text-center"> <div className="mt-12 text-center">
<Button variant="secondary" size="lg"> <Button variant="secondary" size="lg">
داده را بر اساس محصول، منطقه یا کانال برش دهید و الگو پیدا کنید. همه قابلیت‌ها را ببینید
</Button> </Button>
</div> </div>
</div> </div>
+32 -24
View File
@@ -1,7 +1,6 @@
"use client"; "use client";
import { type SVGProps, useId } from "react"; import { type SVGProps, useId, useState } from "react";
import { useState } from "react";
import { import {
Accordion, Accordion,
@@ -9,60 +8,67 @@ import {
AccordionItem, AccordionItem,
AccordionTrigger, AccordionTrigger,
} from "@/components/ui/accordion"; } from "@/components/ui/accordion";
import { cn } from "@/lib/utils";
const FEATURES = [ const FEATURES = [
{ {
id: "move-money", id: "move-money",
title: "طبقه‌بندی خودکار", title: "طبقه‌بندی خودکار",
description: description: "درخواست‌ها را خودکار دسته‌بندی کنید و به تیم مناسب بفرستید.",
"درخواست‌ها را خودکار دسته‌بندی کنید و به تیم مناسب بفرستید.",
image: "/block-media/shadcnblocks/block/placeholder-1.svg", image: "/block-media/shadcnblocks/block/placeholder-1.svg",
imageAlt: "دستیار هوش مصنوعی", imageAlt: "دستیار هوش مصنوعی",
}, },
{ {
id: "card-program", id: "card-program",
title: "پیش‌بینی ریزش", title: "پیش‌بینی ریزش",
description: description: "مشتریان در معرض ریزش را زودتر شناسایی کنید.",
"مشتریان در معرض ریزش را زودتر شناسایی کنید.",
image: "/block-media/shadcnblocks/block/placeholder-2.svg", image: "/block-media/shadcnblocks/block/placeholder-2.svg",
imageAlt: "پیشنهادهای هوشمند", imageAlt: "پیشنهادهای هوشمند",
}, },
{ {
id: "lend-money", id: "lend-money",
title: "جستجوی معنایی", title: "جستجوی معنایی",
description: description: "متن‌های طولانی را در چند ثانیه به نکات کلیدی تبدیل کنید.",
"متن‌های طولانی را در چند ثانیه به نکات کلیدی تبدیل کنید.",
image: "/block-media/shadcnblocks/block/placeholder-3.svg", image: "/block-media/shadcnblocks/block/placeholder-3.svg",
imageAlt: "تحلیل با AI", imageAlt: "تحلیل با AI",
}, },
{ {
id: "data-analytics", id: "data-analytics",
title: "تولید محتوا", title: "تولید محتوا",
description: description: "بهترین پاسخ را بر اساس زمینه مکالمه پیشنهاد دهید.",
"بهترین پاسخ را بر اساس زمینه مکالمه پیشنهاد دهید.",
image: "/block-media/shadcnblocks/block/placeholder-4.svg", image: "/block-media/shadcnblocks/block/placeholder-4.svg",
imageAlt: "دستیار هوش مصنوعی", imageAlt: "دستیار هوش مصنوعی",
}, },
{ {
id: "compliance", id: "compliance",
title: "تحلیل احساس", title: "تحلیل احساس",
description: description: "درخواست‌ها را خودکار دسته‌بندی کنید و به تیم مناسب بفرستید.",
"درخواست‌ها را خودکار دسته‌بندی کنید و به تیم مناسب بفرستید.",
image: "/block-media/shadcnblocks/block/placeholder-5.svg", image: "/block-media/shadcnblocks/block/placeholder-5.svg",
imageAlt: "پیشنهادهای هوشمند", imageAlt: "پیشنهادهای هوشمند",
}, },
]; ];
export function Feature192() { interface Feature192Props {
className?: string;
}
const Feature192 = ({ className }: Feature192Props) => {
const [selectedIndex, setSelectedIndex] = useState(0); const [selectedIndex, setSelectedIndex] = useState(0);
return ( return (
<section dir="rtl" lang="fa" className="container max-w-5xl py-32"> <section
<div className="relative overflow-hidden rounded-3xl border bg-linear-to-bl from-gradient-1/20 to-transparent rtl:bg-linear-to-br py-5 sm:py-6 lg:py-8"> dir="rtl"
lang="fa"
className={cn(
"container w-full min-w-0 max-w-5xl overflow-x-hidden py-32",
className,
)}
>
<div className="relative overflow-hidden rounded-3xl border bg-linear-to-bl from-gradient-1/20 to-transparent py-5 rtl:bg-linear-to-br sm:py-6 lg:py-8">
<div className="absolute inset-0 z-[-1]"> <div className="absolute inset-0 z-[-1]">
<PlusSigns className="h-full w-full text-foreground/[0.05]" /> <PlusSigns className="h-full w-full text-foreground/[0.05]" />
</div> </div>
<div className="sm:px-6 lg:px-8"> <div className="min-w-0 sm:px-6 lg:px-8">
<div className="px-5 text-start sm:px-0"> <div className="px-5 text-start sm:px-0">
<h3 className="font-mono text-sm font-semibold text-accent-foreground"> <h3 className="font-mono text-sm font-semibold text-accent-foreground">
دستیار گفتگو دستیار گفتگو
@@ -71,10 +77,10 @@ export function Feature192() {
با هوش مصنوعی سریع‌تر تصمیم بگیرید با هوش مصنوعی سریع‌تر تصمیم بگیرید
</h2> </h2>
</div> </div>
<div className="mt-10 flex gap-12 overflow-hidden sm:mt-16 lg:mt-20"> <div className="mt-10 flex min-w-0 gap-8 overflow-hidden sm:mt-16 sm:gap-12 lg:mt-20">
<Accordion <Accordion
type="single" type="single"
className="flex-1" className="min-w-0 flex-1"
defaultValue="0" defaultValue="0"
onValueChange={(value) => setSelectedIndex(Number(value))} onValueChange={(value) => setSelectedIndex(Number(value))}
> >
@@ -85,7 +91,7 @@ export function Feature192() {
className="border-black/20 dark:border-white/20" className="border-black/20 dark:border-white/20"
> >
<AccordionTrigger className="px-5 text-start hover:no-underline sm:px-0"> <AccordionTrigger className="px-5 text-start hover:no-underline sm:px-0">
<span className="text-xl font-bold opacity-80"> <span className="text-lg font-bold opacity-80 sm:text-xl">
{feature.title} {feature.title}
</span> </span>
</AccordionTrigger> </AccordionTrigger>
@@ -93,22 +99,22 @@ export function Feature192() {
<p className="px-5 text-pretty leading-relaxed font-medium text-muted-foreground sm:px-0"> <p className="px-5 text-pretty leading-relaxed font-medium text-muted-foreground sm:px-0">
{feature.description} {feature.description}
</p> </p>
<div className="relative mt-4 translate-x-5 rtl:-translate-x-5 sm:hidden"> <div className="mt-4 overflow-hidden ps-5 sm:hidden">
<img <img
src={feature.image} src={feature.image}
alt={feature.imageAlt} alt={feature.imageAlt}
className="h-[240px] w-full rounded-2xl object-cover shadow-lg" className="h-[200px] w-full max-w-full rounded-2xl object-cover shadow-lg sm:h-[240px]"
/> />
</div> </div>
</AccordionContent> </AccordionContent>
</AccordionItem> </AccordionItem>
))} ))}
</Accordion> </Accordion>
<div className="relative hidden sm:block sm:flex-1"> <div className="relative hidden min-w-0 flex-1 sm:block">
<img <img
src={FEATURES[selectedIndex].image} src={FEATURES[selectedIndex].image}
alt={FEATURES[selectedIndex].imageAlt} alt={FEATURES[selectedIndex].imageAlt}
className="rounded-2xl object-cover shadow-lg" className="h-auto w-full max-w-full rounded-2xl object-cover shadow-lg"
/> />
</div> </div>
</div> </div>
@@ -116,7 +122,7 @@ export function Feature192() {
</div> </div>
</section> </section>
); );
} };
interface PlusSignsProps extends SVGProps<SVGSVGElement> { interface PlusSignsProps extends SVGProps<SVGSVGElement> {
className?: string; className?: string;
@@ -162,3 +168,5 @@ const PlusSigns = ({ className, ...props }: PlusSignsProps) => {
</svg> </svg>
); );
}; };
export { Feature192 };
+19 -19
View File
@@ -1,4 +1,3 @@
import { AspectRatio } from "@/components/ui/aspect-ratio";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
@@ -29,8 +28,7 @@ const LIST: TabItem[] = [
id: "clear-audio", id: "clear-audio",
title: "Pivot تعاملی", title: "Pivot تعاملی",
value: "2", value: "2",
summary: summary: "گزارش سفارشی را بدون SQL بسازید و سریع منتشر کنید.",
"گزارش سفارشی را بدون SQL بسازید و سریع منتشر کنید.",
image: { image: {
src: "/block-media/shadcnblocks/block/placeholder-2.svg", src: "/block-media/shadcnblocks/block/placeholder-2.svg",
alt: "تحلیل داده سازمان", alt: "تحلیل داده سازمان",
@@ -40,8 +38,7 @@ const LIST: TabItem[] = [
id: "green-screen", id: "green-screen",
title: "داشبورد مدیریتی", title: "داشبورد مدیریتی",
value: "3", value: "3",
summary: summary: "داده سازمانی",
"داده سازمانی",
image: { image: {
src: "/block-media/shadcnblocks/block/placeholder-3.svg", src: "/block-media/shadcnblocks/block/placeholder-3.svg",
alt: "داشبورد هوش تجاری", alt: "داشبورد هوش تجاری",
@@ -55,23 +52,27 @@ interface Feature213Props {
const Feature213 = ({ className }: Feature213Props) => { const Feature213 = ({ className }: Feature213Props) => {
return ( return (
<section dir="rtl" lang="fa" className={cn("bg-background py-32", className)}> <section
<div className="container"> dir="rtl"
lang="fa"
className={cn("w-full max-w-full bg-background py-32", className)}
>
<div className="container min-w-0">
<div className="mx-auto mb-8 flex max-w-[52.5rem] flex-col items-center justify-between gap-6 md:mb-20"> <div className="mx-auto mb-8 flex max-w-[52.5rem] flex-col items-center justify-between gap-6 md:mb-20">
<h2 className="text-center text-2xll tracking-tight text-balance text-foreground lg:text-2xll"> <h2 className="text-center text-2xll tracking-tight text-balance text-foreground lg:text-2xll">
تصمیم استراتژیک را داده‌محور کنید تصمیم استراتژیک را داده‌محور کنید
</h2> </h2>
</div> </div>
<div>
<Tabs <Tabs
dir="rtl" dir="rtl"
defaultValue={LIST[0].value} defaultValue={LIST[0].value}
className="flex gap-14 xl:!flex-row" className="flex w-full min-w-0 flex-col items-stretch gap-8 lg:flex-row! lg:items-start lg:gap-14"
> >
<TabsList className="!h-fit w-fit flex-col gap-2.5 bg-transparent p-0"> <TabsList className="!h-fit w-full shrink-0 flex-col gap-2.5 bg-transparent p-0 lg:w-fit lg:max-w-[34.0625rem]">
{LIST.map((item) => ( {LIST.map((item) => (
<TabsTrigger <TabsTrigger
className="flex-col items-start rounded-[0.75rem] p-5 text-right whitespace-normal data-[state=active]:bg-muted xl:max-w-[34.0625rem]" className="w-full flex-col items-start rounded-[0.75rem] p-5 text-right whitespace-normal data-[state=active]:bg-muted"
key={item.id} key={item.id}
value={item.value} value={item.value}
> >
@@ -82,26 +83,25 @@ const Feature213 = ({ className }: Feature213Props) => {
</TabsTrigger> </TabsTrigger>
))} ))}
</TabsList> </TabsList>
<div className="relative min-w-0 w-full flex-1">
{LIST.map((item) => ( {LIST.map((item) => (
<TabsContent <TabsContent
className="w-full" className="mt-0 w-full min-w-0"
key={item.id} key={item.id}
value={item.value} value={item.value}
> >
<AspectRatio <div className="aspect-video w-full min-w-0 overflow-hidden rounded-[0.75rem] bg-muted">
ratio={16 / 9}
className="overflow-hidden rounded-[0.75rem]"
>
<img <img
src={item.image.src} src={item.image.src}
alt={item.image.alt} alt={item.image.alt}
className="block size-full object-cover object-center" className="block size-full max-w-full object-cover object-center"
/> />
</AspectRatio> </div>
</TabsContent> </TabsContent>
))} ))}
</Tabs>
</div> </div>
</Tabs>
</div> </div>
</section> </section>
); );
+58 -53
View File
@@ -10,7 +10,6 @@ import {
ScanFace, ScanFace,
TextQuote, TextQuote,
} from "lucide-react"; } from "lucide-react";
import { useRef } from "react";
import { import {
Card, Card,
@@ -29,7 +28,8 @@ import { cn } from "@/lib/utils";
interface CarouselCardItem { interface CarouselCardItem {
id: string; id: string;
video: string; image: string;
imageAlt: string;
Icon: LucideIcon; Icon: LucideIcon;
title: string; title: string;
link: string; link: string;
@@ -39,7 +39,8 @@ interface CarouselCardItem {
const CARDS: CarouselCardItem[] = [ const CARDS: CarouselCardItem[] = [
{ {
id: "code-analysis", id: "code-analysis",
video: "/block-media/shadcnblocks/block/video-1.mp4", image: "/block-media/shadcnblocks/block/placeholder-1.svg",
imageAlt: "داشبورد مدیریت ارتباط با مشتری",
Icon: Eye, Icon: Eye,
title: "پروفایل ۳۶۰ درجه مشتری", title: "پروفایل ۳۶۰ درجه مشتری",
link: "#", link: "#",
@@ -48,7 +49,8 @@ const CARDS: CarouselCardItem[] = [
}, },
{ {
id: "multi-language", id: "multi-language",
video: "/block-media/shadcnblocks/block/video-6.mp4", image: "/block-media/shadcnblocks/block/placeholder-2.svg",
imageAlt: "نمای پایپ‌لاین فروش",
Icon: Languages, Icon: Languages,
title: "اتوماسیون مراحل فروش", title: "اتوماسیون مراحل فروش",
link: "#", link: "#",
@@ -57,7 +59,8 @@ const CARDS: CarouselCardItem[] = [
}, },
{ {
id: "refactoring", id: "refactoring",
video: "/block-media/shadcnblocks/block/video-7-640_360_30fps.mp4", image: "/block-media/shadcnblocks/block/placeholder-3.svg",
imageAlt: "پروفایل یکپارچه مشتری",
Icon: AudioLines, Icon: AudioLines,
title: "پیش‌بینی درآمد", title: "پیش‌بینی درآمد",
link: "#", link: "#",
@@ -66,7 +69,8 @@ const CARDS: CarouselCardItem[] = [
}, },
{ {
id: "code-cleanup", id: "code-cleanup",
video: "/block-media/shadcnblocks/block/video-5.mp4", image: "/block-media/shadcnblocks/block/placeholder-4.svg",
imageAlt: "داشبورد مدیریت ارتباط با مشتری",
Icon: ListMinus, Icon: ListMinus,
title: "یادآور پیگیری هوشمند", title: "یادآور پیگیری هوشمند",
link: "#", link: "#",
@@ -75,7 +79,8 @@ const CARDS: CarouselCardItem[] = [
}, },
{ {
id: "security-scanner", id: "security-scanner",
video: "/block-media/shadcnblocks/block/video-1.mp4", image: "/block-media/shadcnblocks/block/placeholder-5.svg",
imageAlt: "نمای پایپ‌لاین فروش",
Icon: ScanFace, Icon: ScanFace,
title: "تقسیم خودکار سرنخ", title: "تقسیم خودکار سرنخ",
link: "#", link: "#",
@@ -84,7 +89,8 @@ const CARDS: CarouselCardItem[] = [
}, },
{ {
id: "documentation", id: "documentation",
video: "/block-media/shadcnblocks/block/video-6.mp4", image: "/block-media/shadcnblocks/block/placeholder-6.svg",
imageAlt: "پروفایل یکپارچه مشتری",
Icon: TextQuote, Icon: TextQuote,
title: "گزارش عملکرد فروش", title: "گزارش عملکرد فروش",
link: "#", link: "#",
@@ -93,7 +99,8 @@ const CARDS: CarouselCardItem[] = [
}, },
{ {
id: "code-suggestions", id: "code-suggestions",
video: "/block-media/shadcnblocks/block/video-7-640_360_30fps.mp4", image: "/block-media/shadcnblocks/block/placeholder-dark-1.svg",
imageAlt: "داشبورد مدیریت ارتباط با مشتری",
Icon: Captions, Icon: Captions,
title: "مدیریت قرارداد", title: "مدیریت قرارداد",
link: "#", link: "#",
@@ -102,47 +109,35 @@ const CARDS: CarouselCardItem[] = [
}, },
]; ];
const CarouselCard = ({ video, Icon, title, link, summary }: CarouselCardItem) => { const CarouselCard = ({
const videoRef = useRef<HTMLVideoElement | null>(null); image,
imageAlt,
Icon,
title,
link,
summary,
}: CarouselCardItem) => {
return ( return (
<a <a href={link} className="group block h-full min-w-0">
href={link} <Card className="h-full min-w-0 gap-0 overflow-hidden rounded-xl border-0 bg-muted p-4 py-4! shadow-none ring-0 transition-all group-hover:shadow-md sm:p-6 lg:min-h-[39.75rem] lg:p-8">
className="group block h-full" <CardContent className="min-w-0 p-0">
onMouseEnter={() => { <div className="relative min-w-0">
if (videoRef.current) { <div className="h-48 w-full min-w-0 overflow-hidden rounded-lg sm:h-56 lg:h-[20rem]">
videoRef.current.play(); <img
} src={image}
}} alt={imageAlt}
onMouseLeave={() => { className="block size-full max-w-full object-cover object-center"
if (videoRef.current) {
videoRef.current.pause();
videoRef.current.currentTime = 0;
}
}}
>
<Card className="min-h-[39.75rem] bg-muted p-8 shadow-none transition-all group-hover:shadow-md">
<CardContent className="p-0">
<div className="relative">
<div className="h-[20rem] w-full overflow-hidden rounded-[0.5rem]">
<video
src={video}
className="block size-full object-cover object-center"
ref={videoRef}
controls={false}
muted
aria-label={title}
/> />
</div> </div>
<div className="absolute -start-2 -top-3 flex size-9 rounded-[0.5rem] bg-primary"> <div className="absolute -start-1 -top-2 flex size-8 rounded-lg bg-primary sm:-start-2 sm:-top-3 sm:size-9 sm:rounded-[0.5rem]">
<Icon className="m-auto size-4 stroke-primary-foreground" /> <Icon className="m-auto size-4 stroke-primary-foreground" />
</div> </div>
</div> </div>
<div className="mt-8 flex flex-col gap-2 text-start"> <div className="mt-6 flex min-w-0 flex-col gap-2 text-start sm:mt-8">
<CardTitle className="text-xl leading-[130%] font-normal tracking-[-0.48px] text-foreground"> <CardTitle className="text-lg leading-[130%] font-normal tracking-[-0.48px] text-pretty text-foreground sm:text-xl">
{title} {title}
</CardTitle> </CardTitle>
<CardDescription className="text-lg leading-[150%] tracking-[-0.36px] text-pretty"> <CardDescription className="text-sm leading-[150%] tracking-[-0.36px] text-pretty sm:text-base lg:text-lg">
{summary} {summary}
</CardDescription> </CardDescription>
</div> </div>
@@ -158,36 +153,46 @@ interface Feature214Props {
const Feature214 = ({ className }: Feature214Props) => { const Feature214 = ({ className }: Feature214Props) => {
return ( return (
<section dir="rtl" lang="fa" className={cn("py-32", className)}> <section
<div className="container"> dir="rtl"
<div className="mx-auto mb-16 flex max-w-[47.5rem] flex-col gap-6"> lang="fa"
className={cn(
"w-full max-w-full overflow-x-hidden py-20 sm:py-32",
className,
)}
>
<div className="container min-w-0 px-4 sm:px-6">
<div className="mx-auto mb-10 flex max-w-[47.5rem] flex-col gap-4 sm:mb-16 sm:gap-6">
<h2 className="text-center font-serif text-xl text-balance md:text-2xll xl:text-2xll"> <h2 className="text-center font-serif text-xl text-balance md:text-2xll xl:text-2xll">
هر سرنخ را تا قرارداد دنبال کنید هر سرنخ را تا قرارداد دنبال کنید
</h2> </h2>
<p className="text-center text-xl text-pretty"> <p className="text-center text-base text-pretty sm:text-lg md:text-xl">
پروفایل یکپارچه مشتری، تاریخچه تماس و وضعیت معامله را همزمان نشان می‌دهد. تیم‌ها با دید مشترک، هماهنگ‌تر پیش می‌روند و نرخ تبدیل بالاتر می‌رود. پروفایل یکپارچه مشتری، تاریخچه تماس و وضعیت معامله را همزمان نشان
می‌دهد. تیم‌ها با دید مشترک، هماهنگ‌تر پیش می‌روند و نرخ تبدیل بالاتر
می‌رود.
</p> </p>
</div> </div>
<Carousel <Carousel
opts={{ opts={{
align: "start", align: "start",
direction: "rtl", direction: "rtl",
}} }}
className="w-full" className="w-full min-w-0 max-w-full"
> >
<CarouselContent className="py-4"> <CarouselContent className="py-2 sm:py-4">
{CARDS.map((item) => ( {CARDS.map((item) => (
<CarouselItem <CarouselItem
key={item.id} key={item.id}
className="basis-full sm:basis-1/2 lg:basis-1/3 xl:basis-1/4" className="min-w-0 basis-[85%] sm:basis-1/2 lg:basis-1/3 xl:basis-1/4"
> >
<CarouselCard {...item} /> <CarouselCard {...item} />
</CarouselItem> </CarouselItem>
))} ))}
</CarouselContent> </CarouselContent>
<div className="mt-8 flex w-full justify-end gap-4"> <div className="mt-6 flex w-full min-w-0 justify-center gap-3 sm:mt-8 sm:justify-end sm:gap-4">
<CarouselPrevious className="static size-12" /> <CarouselPrevious className="static size-10 translate-y-0 sm:size-12 rtl:rotate-180" />
<CarouselNext className="static size-12" /> <CarouselNext className="static size-10 translate-y-0 sm:size-12 rtl:rotate-180" />
</div> </div>
</Carousel> </Carousel>
</div> </div>
+57 -35
View File
@@ -12,7 +12,6 @@ import {
} from "lucide-react"; } from "lucide-react";
import { useRef } from "react"; import { useRef } from "react";
import { AspectRatio } from "@/components/ui/aspect-ratio";
import { import {
Card, Card,
CardContent, CardContent,
@@ -31,6 +30,7 @@ import { cn } from "@/lib/utils";
interface CarouselCardItem { interface CarouselCardItem {
id: string; id: string;
video: string; video: string;
poster: string;
Icon: LucideIcon; Icon: LucideIcon;
title: string; title: string;
link: string; link: string;
@@ -41,6 +41,7 @@ const CARDS: CarouselCardItem[] = [
{ {
id: "design-system", id: "design-system",
video: "/block-media/shadcnblocks/block/video-1.mp4", video: "/block-media/shadcnblocks/block/video-1.mp4",
poster: "/block-media/shadcnblocks/block/placeholder-1.svg",
Icon: Eye, Icon: Eye,
title: "همکاری فروش و بازاریابی", title: "همکاری فروش و بازاریابی",
link: "#", link: "#",
@@ -50,6 +51,7 @@ const CARDS: CarouselCardItem[] = [
{ {
id: "framework-agnostic", id: "framework-agnostic",
video: "/block-media/shadcnblocks/block/video-2.mp4", video: "/block-media/shadcnblocks/block/video-2.mp4",
poster: "/block-media/shadcnblocks/block/placeholder-2.svg",
Icon: Languages, Icon: Languages,
title: "اولویت‌بندی سرنخ", title: "اولویت‌بندی سرنخ",
link: "#", link: "#",
@@ -58,7 +60,8 @@ const CARDS: CarouselCardItem[] = [
}, },
{ {
id: "interactive", id: "interactive",
video: "/block-media/shadcnblocks/block/video-3.mp4", video: "/block-media/shadcnblocks/block/landscape.mp4",
poster: "/block-media/shadcnblocks/block/placeholder-3.svg",
Icon: AudioLines, Icon: AudioLines,
title: "قالب پیشنهاد فروش", title: "قالب پیشنهاد فروش",
link: "#", link: "#",
@@ -67,7 +70,8 @@ const CARDS: CarouselCardItem[] = [
}, },
{ {
id: "minimal-setup", id: "minimal-setup",
video: "/block-media/shadcnblocks/block/video-4.mp4", video: "/block-media/shadcnblocks/block/video-1.mp4",
poster: "/block-media/shadcnblocks/block/placeholder-4.svg",
Icon: ListMinus, Icon: ListMinus,
title: "ردیابی کووت", title: "ردیابی کووت",
link: "#", link: "#",
@@ -76,7 +80,8 @@ const CARDS: CarouselCardItem[] = [
}, },
{ {
id: "accessibility", id: "accessibility",
video: "/block-media/shadcnblocks/block/video-5.mp4", video: "/block-media/shadcnblocks/block/video-2.mp4",
poster: "/block-media/shadcnblocks/block/placeholder-5.svg",
Icon: ScanFace, Icon: ScanFace,
title: "تحلیل باخت معامله", title: "تحلیل باخت معامله",
link: "#", link: "#",
@@ -85,7 +90,8 @@ const CARDS: CarouselCardItem[] = [
}, },
{ {
id: "documentation", id: "documentation",
video: "/block-media/shadcnblocks/block/video-6.mp4", video: "/block-media/shadcnblocks/block/landscape.mp4",
poster: "/block-media/shadcnblocks/block/placeholder-6.svg",
Icon: TextQuote, Icon: TextQuote,
title: "هدف‌گذاری تیمی", title: "هدف‌گذاری تیمی",
link: "#", link: "#",
@@ -94,7 +100,8 @@ const CARDS: CarouselCardItem[] = [
}, },
{ {
id: "typescript", id: "typescript",
video: "/block-media/shadcnblocks/block/video-6.mp4", video: "/block-media/shadcnblocks/block/video-1.mp4",
poster: "/block-media/shadcnblocks/block/placeholder-dark-1.svg",
Icon: Captions, Icon: Captions,
title: "اتوماسیون پیگیری", title: "اتوماسیون پیگیری",
link: "#", link: "#",
@@ -103,17 +110,22 @@ const CARDS: CarouselCardItem[] = [
}, },
]; ];
const CarouselCard = ({ video, Icon, title, link, summary }: CarouselCardItem) => { const CarouselCard = ({
video,
poster,
Icon,
title,
link,
summary,
}: CarouselCardItem) => {
const videoRef = useRef<HTMLVideoElement | null>(null); const videoRef = useRef<HTMLVideoElement | null>(null);
return ( return (
<a <a
href={link} href={link}
className="group block h-full" className="group block h-full min-w-0"
onMouseEnter={() => { onMouseEnter={() => {
if (videoRef.current) { void videoRef.current?.play();
videoRef.current.play();
}
}} }}
onMouseLeave={() => { onMouseLeave={() => {
if (videoRef.current) { if (videoRef.current) {
@@ -122,28 +134,29 @@ const CarouselCard = ({ video, Icon, title, link, summary }: CarouselCardItem) =
} }
}} }}
> >
<Card className="h-full min-h-[24rem] bg-muted p-8 shadow-none transition-all group-hover:shadow-md"> <Card className="h-full min-h-0 min-w-0 gap-0 overflow-hidden rounded-xl border-0 bg-muted p-4 py-4! shadow-none ring-0 transition-all group-hover:shadow-md sm:min-h-[22rem] sm:p-6 lg:min-h-[24rem] lg:p-8">
<CardContent className="p-0"> <CardContent className="min-w-0 p-0">
<div className="relative"> <div className="relative min-w-0">
<AspectRatio <div className="aspect-video w-full min-w-0 overflow-hidden rounded-lg bg-background">
ratio={16 / 9}
className="overflow-hidden rounded-[0.5rem]"
>
<video <video
src={video}
className="block size-full object-cover object-center"
ref={videoRef} ref={videoRef}
className="block size-full max-w-full object-cover object-center"
src={video}
poster={poster}
controls={false} controls={false}
muted muted
loop
playsInline
preload="metadata"
aria-label={title} aria-label={title}
/> />
</AspectRatio> </div>
<div className="absolute -start-2 -top-3 flex size-9 rounded-[0.5rem] bg-primary"> <div className="absolute -start-1 -top-2 flex size-8 rounded-lg bg-primary sm:-start-2 sm:-top-3 sm:size-9 sm:rounded-[0.5rem]">
<Icon className="m-auto size-4 stroke-primary-foreground" /> <Icon className="m-auto size-4 stroke-primary-foreground" />
</div> </div>
</div> </div>
<div className="mt-8 flex flex-col gap-2 text-start"> <div className="mt-6 flex min-w-0 flex-col gap-2 text-start sm:mt-8">
<CardTitle className="text-xl leading-[130%] font-normal tracking-[-0.48px] text-foreground"> <CardTitle className="text-lg leading-[130%] font-normal tracking-[-0.48px] text-pretty text-foreground sm:text-xl">
{title} {title}
</CardTitle> </CardTitle>
<CardDescription className="text-sm leading-[150%] tracking-[-0.36px] text-pretty"> <CardDescription className="text-sm leading-[150%] tracking-[-0.36px] text-pretty">
@@ -162,36 +175,45 @@ interface Feature215Props {
const Feature215 = ({ className }: Feature215Props) => { const Feature215 = ({ className }: Feature215Props) => {
return ( return (
<section dir="rtl" lang="fa" className={cn("py-32", className)}> <section
<div className="container"> dir="rtl"
<div className="mx-auto mb-16 flex max-w-[47.5rem] flex-col gap-6"> lang="fa"
className={cn(
"w-full max-w-full overflow-x-hidden py-20 sm:py-32",
className,
)}
>
<div className="container min-w-0 px-4 sm:px-6">
<div className="mx-auto mb-10 flex max-w-[47.5rem] flex-col gap-4 sm:mb-16 sm:gap-6">
<h2 className="text-center text-xl font-semibold text-balance xl:text-2xll"> <h2 className="text-center text-xl font-semibold text-balance xl:text-2xll">
پیش‌بینی درآمد را دقیق‌تر کنید پیش‌بینی درآمد را دقیق‌تر کنید
</h2> </h2>
<p className="text-center text-xl text-pretty text-muted-foreground"> <p className="text-center text-base text-pretty text-muted-foreground sm:text-lg md:text-xl">
الگوهای موفق فروش را در کل سازمان تکرار کنید. داده لحظه‌ای نشان می‌دهد کدام مرحله بیشترین افت تبدیل را دارد. الگوهای موفق فروش را در کل سازمان تکرار کنید. داده لحظه‌ای نشان
می‌دهد کدام مرحله بیشترین افت تبدیل را دارد.
</p> </p>
</div> </div>
<Carousel <Carousel
opts={{ opts={{
align: "start", align: "start",
direction: "rtl", direction: "rtl",
}} }}
className="w-full" className="w-full min-w-0 max-w-full"
> >
<CarouselContent className="py-4"> <CarouselContent className="py-2 sm:py-4">
{CARDS.map((item) => ( {CARDS.map((item) => (
<CarouselItem <CarouselItem
key={item.id} key={item.id}
className="basis-full md:basis-1/2 lg:basis-1/3" className="min-w-0 basis-[85%] sm:basis-1/2 lg:basis-1/3"
> >
<CarouselCard {...item} /> <CarouselCard {...item} />
</CarouselItem> </CarouselItem>
))} ))}
</CarouselContent> </CarouselContent>
<div className="mt-8 flex w-full justify-center gap-4"> <div className="mt-6 flex w-full min-w-0 justify-center gap-3 sm:mt-8 sm:gap-4">
<CarouselPrevious className="static size-12" /> <CarouselPrevious className="static size-10 translate-y-0 sm:size-12 rtl:rotate-180" />
<CarouselNext className="static size-12" /> <CarouselNext className="static size-10 translate-y-0 sm:size-12 rtl:rotate-180" />
</div> </div>
</Carousel> </Carousel>
</div> </div>
+50 -29
View File
@@ -11,7 +11,6 @@ import {
} from "lucide-react"; } from "lucide-react";
import { useRef } from "react"; import { useRef } from "react";
import { AspectRatio } from "@/components/ui/aspect-ratio";
import { import {
Card, Card,
CardContent, CardContent,
@@ -23,6 +22,7 @@ import { cn } from "@/lib/utils";
interface GridCardItem { interface GridCardItem {
id: string; id: string;
video: string; video: string;
poster: string;
Icon: LucideIcon; Icon: LucideIcon;
title: string; title: string;
link: string; link: string;
@@ -33,15 +33,16 @@ const CARDS: GridCardItem[] = [
{ {
id: "design-system", id: "design-system",
video: "/block-media/shadcnblocks/block/video-1.mp4", video: "/block-media/shadcnblocks/block/video-1.mp4",
poster: "/block-media/shadcnblocks/block/placeholder-1.svg",
Icon: Eye, Icon: Eye,
title: "ردیابی UTM", title: "ردیابی UTM",
link: "#", link: "#",
summary: summary: "عنوان، تصویر یا فراخوان را تست کنید و برنده را سریع پیدا کنید.",
"عنوان، تصویر یا فراخوان را تست کنید و برنده را سریع پیدا کنید.",
}, },
{ {
id: "framework-agnostic", id: "framework-agnostic",
video: "/block-media/shadcnblocks/block/video-2.mp4", video: "/block-media/shadcnblocks/block/video-2.mp4",
poster: "/block-media/shadcnblocks/block/placeholder-2.svg",
Icon: Languages, Icon: Languages,
title: "گزارش ROI", title: "گزارش ROI",
link: "#", link: "#",
@@ -50,7 +51,8 @@ const CARDS: GridCardItem[] = [
}, },
{ {
id: "interactive", id: "interactive",
video: "/block-media/shadcnblocks/block/video-3.mp4", video: "/block-media/shadcnblocks/block/landscape.mp4",
poster: "/block-media/shadcnblocks/block/placeholder-3.svg",
Icon: AudioLines, Icon: AudioLines,
title: "مدیریت کمپین", title: "مدیریت کمپین",
link: "#", link: "#",
@@ -59,7 +61,8 @@ const CARDS: GridCardItem[] = [
}, },
{ {
id: "minimal-setup", id: "minimal-setup",
video: "/block-media/shadcnblocks/block/video-4.mp4", video: "/block-media/shadcnblocks/block/video-1.mp4",
poster: "/block-media/shadcnblocks/block/placeholder-4.svg",
Icon: ListMinus, Icon: ListMinus,
title: "سگمنت‌بندی مخاطب", title: "سگمنت‌بندی مخاطب",
link: "#", link: "#",
@@ -68,35 +71,40 @@ const CARDS: GridCardItem[] = [
}, },
{ {
id: "accessibility", id: "accessibility",
video: "/block-media/shadcnblocks/block/video-5.mp4", video: "/block-media/shadcnblocks/block/video-2.mp4",
poster: "/block-media/shadcnblocks/block/placeholder-5.svg",
Icon: ScanFace, Icon: ScanFace,
title: "تحلیل کانال", title: "تحلیل کانال",
link: "#", link: "#",
summary: summary: "مخاطبان را بر اساس رفتار، صنعت یا مرحله خرید دسته‌بندی کنید.",
"مخاطبان را بر اساس رفتار، صنعت یا مرحله خرید دسته‌بندی کنید.",
}, },
{ {
id: "documentation", id: "documentation",
video: "/block-media/shadcnblocks/block/video-6.mp4", video: "/block-media/shadcnblocks/block/landscape.mp4",
poster: "/block-media/shadcnblocks/block/placeholder-6.svg",
Icon: TextQuote, Icon: TextQuote,
title: "اتوماسیون ایمیل", title: "اتوماسیون ایمیل",
link: "#", link: "#",
summary: summary: "ببینید کدام کانال بیشترین سرنخ با کیفیت را می‌آورد.",
"ببینید کدام کانال بیشترین سرنخ با کیفیت را می‌آورد.",
}, },
]; ];
const GridCard = ({ video, Icon, title, link, summary }: GridCardItem) => { const GridCard = ({
video,
poster,
Icon,
title,
link,
summary,
}: GridCardItem) => {
const videoRef = useRef<HTMLVideoElement | null>(null); const videoRef = useRef<HTMLVideoElement | null>(null);
return ( return (
<a <a
href={link} href={link}
className="group block" className="group block min-w-0"
onMouseEnter={() => { onMouseEnter={() => {
if (videoRef.current) { void videoRef.current?.play();
videoRef.current.play();
}
}} }}
onMouseLeave={() => { onMouseLeave={() => {
if (videoRef.current) { if (videoRef.current) {
@@ -105,22 +113,26 @@ const GridCard = ({ video, Icon, title, link, summary }: GridCardItem) => {
} }
}} }}
> >
<Card className="h-full bg-muted transition-all duration-200 hover:shadow-lg"> <Card className="h-full min-w-0 gap-0 overflow-hidden border-0 bg-muted py-0! shadow-none ring-0 transition-all duration-200 hover:shadow-lg">
<CardContent> <CardContent className="min-w-0 p-4 sm:p-6">
<div className="relative mb-4"> <div className="relative mb-4 min-w-0">
<AspectRatio ratio={16 / 9} className="overflow-hidden rounded-md"> <div className="aspect-video w-full overflow-hidden rounded-md bg-background">
<video <video
src={video}
className="block size-full object-cover object-center"
ref={videoRef} ref={videoRef}
src={video}
poster={poster}
className="block size-full max-w-full object-cover object-center"
controls={false} controls={false}
muted muted
loop
playsInline
preload="metadata"
aria-label={title} aria-label={title}
/> />
</AspectRatio>
</div> </div>
<div className="flex flex-col gap-2 text-start"> </div>
<CardTitle className="flex items-center gap-2 text-lg font-medium text-foreground"> <div className="flex min-w-0 flex-col gap-2 text-start">
<CardTitle className="flex items-center gap-2 text-lg font-medium text-pretty text-foreground">
<Icon className="size-6 shrink-0 rounded-sm bg-primary stroke-primary-foreground p-1" /> <Icon className="size-6 shrink-0 rounded-sm bg-primary stroke-primary-foreground p-1" />
{title} {title}
</CardTitle> </CardTitle>
@@ -140,17 +152,26 @@ interface Feature215aProps {
const Feature215a = ({ className }: Feature215aProps) => { const Feature215a = ({ className }: Feature215aProps) => {
return ( return (
<section dir="rtl" lang="fa" className={cn("py-24", className)}> <section
<div className="container"> dir="rtl"
lang="fa"
className={cn(
"w-full max-w-full overflow-x-hidden py-24",
className,
)}
>
<div className="container min-w-0 px-4 sm:px-6">
<div className="mx-auto mb-16 flex max-w-[47.5rem] flex-col gap-4 text-center"> <div className="mx-auto mb-16 flex max-w-[47.5rem] flex-col gap-4 text-center">
<h2 className="text-3xl font-bold text-balance xl:text-2xll"> <h2 className="text-3xl font-bold text-balance xl:text-2xll">
کمپین‌هایی بسازید که واقعاً تبدیل می‌شوند کمپین‌هایی بسازید که واقعاً تبدیل می‌شوند
</h2> </h2>
<p className="text-lg text-pretty text-muted-foreground"> <p className="text-lg text-pretty text-muted-foreground">
کمپین‌ها، محتوا و عملکرد کانال‌ها در یک پنل واحد دیده می‌شود. تیم بازاریابی سریع‌تر تست می‌کند، بهینه می‌کند و ROI هر فعالیت را شفاف گزارش می‌دهد. کمپین‌ها، محتوا و عملکرد کانال‌ها در یک پنل واحد دیده می‌شود. تیم
بازاریابی سریع‌تر تست می‌کند، بهینه می‌کند و ROI هر فعالیت را شفاف
گزارش می‌دهد.
</p> </p>
</div> </div>
<div className="grid gap-6 md:grid-cols-2 lg:grid-cols-3"> <div className="grid min-w-0 gap-6 md:grid-cols-2 lg:grid-cols-3">
{CARDS.map((item) => ( {CARDS.map((item) => (
<GridCard key={item.id} {...item} /> <GridCard key={item.id} {...item} />
))} ))}
+32 -19
View File
@@ -11,13 +11,13 @@ import {
} from "lucide-react"; } from "lucide-react";
import { useRef } from "react"; import { useRef } from "react";
import { AspectRatio } from "@/components/ui/aspect-ratio";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
interface HorizontalCardItem { interface HorizontalCardItem {
id: string; id: string;
video: string; video: string;
poster: string;
Icon: LucideIcon; Icon: LucideIcon;
title: string; title: string;
link: string; link: string;
@@ -28,6 +28,7 @@ const CARDS: HorizontalCardItem[] = [
{ {
id: "design-system", id: "design-system",
video: "/block-media/shadcnblocks/block/video-1.mp4", video: "/block-media/shadcnblocks/block/video-1.mp4",
poster: "/block-media/shadcnblocks/block/placeholder-1.svg",
Icon: Eye, Icon: Eye,
title: "لاگ اجرا", title: "لاگ اجرا",
link: "#", link: "#",
@@ -37,6 +38,7 @@ const CARDS: HorizontalCardItem[] = [
{ {
id: "framework-agnostic", id: "framework-agnostic",
video: "/block-media/shadcnblocks/block/video-2.mp4", video: "/block-media/shadcnblocks/block/video-2.mp4",
poster: "/block-media/shadcnblocks/block/placeholder-2.svg",
Icon: Languages, Icon: Languages,
title: "قالب آماده", title: "قالب آماده",
link: "#", link: "#",
@@ -45,7 +47,8 @@ const CARDS: HorizontalCardItem[] = [
}, },
{ {
id: "interactive", id: "interactive",
video: "/block-media/shadcnblocks/block/video-3.mp4", video: "/block-media/shadcnblocks/block/landscape.mp4",
poster: "/block-media/shadcnblocks/block/placeholder-3.svg",
Icon: AudioLines, Icon: AudioLines,
title: "اتصال ابزار", title: "اتصال ابزار",
link: "#", link: "#",
@@ -54,7 +57,8 @@ const CARDS: HorizontalCardItem[] = [
}, },
{ {
id: "minimal-setup", id: "minimal-setup",
video: "/block-media/shadcnblocks/block/video-4.mp4", video: "/block-media/shadcnblocks/block/video-1.mp4",
poster: "/block-media/shadcnblocks/block/placeholder-4.svg",
Icon: ListMinus, Icon: ListMinus,
title: "سازنده گردش‌کار", title: "سازنده گردش‌کار",
link: "#", link: "#",
@@ -63,7 +67,8 @@ const CARDS: HorizontalCardItem[] = [
}, },
{ {
id: "accessibility", id: "accessibility",
video: "/block-media/shadcnblocks/block/video-5.mp4", video: "/block-media/shadcnblocks/block/video-2.mp4",
poster: "/block-media/shadcnblocks/block/placeholder-5.svg",
Icon: ScanFace, Icon: ScanFace,
title: "تریگر رویداد", title: "تریگر رویداد",
link: "#", link: "#",
@@ -72,7 +77,8 @@ const CARDS: HorizontalCardItem[] = [
}, },
{ {
id: "documentation", id: "documentation",
video: "/block-media/shadcnblocks/block/video-6.mp4", video: "/block-media/shadcnblocks/block/landscape.mp4",
poster: "/block-media/shadcnblocks/block/placeholder-6.svg",
Icon: TextQuote, Icon: TextQuote,
title: "شرط هوشمند", title: "شرط هوشمند",
link: "#", link: "#",
@@ -83,6 +89,7 @@ const CARDS: HorizontalCardItem[] = [
const HorizontalCard = ({ const HorizontalCard = ({
video, video,
poster,
Icon, Icon,
title, title,
link, link,
@@ -92,11 +99,9 @@ const HorizontalCard = ({
return ( return (
<div <div
className="group flex flex-col gap-6 border-b border-border py-8 last:border-b-0 md:flex-row md:items-center" className="group flex min-w-0 flex-col gap-6 border-b border-border py-8 last:border-b-0 md:flex-row md:items-center"
onMouseEnter={() => { onMouseEnter={() => {
if (videoRef.current) { void videoRef.current?.play();
videoRef.current.play();
}
}} }}
onMouseLeave={() => { onMouseLeave={() => {
if (videoRef.current) { if (videoRef.current) {
@@ -105,25 +110,29 @@ const HorizontalCard = ({
} }
}} }}
> >
<div className="md:w-1/3"> <div className="min-w-0 md:w-1/3">
<AspectRatio ratio={16 / 9} className="overflow-hidden rounded-lg"> <div className="aspect-video w-full overflow-hidden rounded-lg bg-muted">
<video <video
src={video}
className="block size-full object-cover object-center"
ref={videoRef} ref={videoRef}
src={video}
poster={poster}
className="block size-full max-w-full object-cover object-center"
controls={false} controls={false}
muted muted
loop
playsInline
preload="metadata"
aria-label={title} aria-label={title}
/> />
</AspectRatio> </div>
</div> </div>
<div className="flex flex-1 flex-col gap-4 text-start md:ps-6"> <div className="flex min-w-0 flex-1 flex-col gap-4 text-start md:ps-6">
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<div className="flex size-8 shrink-0 rounded-md bg-primary"> <div className="flex size-8 shrink-0 rounded-md bg-primary">
<Icon className="m-auto size-4 text-primary-foreground" /> <Icon className="m-auto size-4 text-primary-foreground" />
</div> </div>
<h3 className="text-xl font-semibold">{title}</h3> <h3 className="text-xl font-semibold text-pretty">{title}</h3>
</div> </div>
<p className="leading-relaxed text-pretty text-muted-foreground"> <p className="leading-relaxed text-pretty text-muted-foreground">
@@ -146,8 +155,12 @@ interface Feature215bProps {
const Feature215b = ({ className }: Feature215bProps) => { const Feature215b = ({ className }: Feature215bProps) => {
return ( return (
<section dir="rtl" lang="fa" className={cn("py-20", className)}> <section
<div className="container"> dir="rtl"
lang="fa"
className={cn("w-full max-w-full overflow-x-hidden py-20", className)}
>
<div className="container min-w-0 px-4 sm:px-6">
<div className="mx-auto mb-12 max-w-3xl text-center"> <div className="mx-auto mb-12 max-w-3xl text-center">
<h2 className="mb-4 text-3xl font-bold text-balance xl:text-2xll"> <h2 className="mb-4 text-3xl font-bold text-balance xl:text-2xll">
فرایندها را استاندارد و سریع کنید فرایندها را استاندارد و سریع کنید
@@ -157,7 +170,7 @@ const Feature215b = ({ className }: Feature215bProps) => {
</p> </p>
</div> </div>
<div className="mx-auto max-w-4xl"> <div className="mx-auto max-w-4xl min-w-0">
{CARDS.map((item) => ( {CARDS.map((item) => (
<HorizontalCard key={item.id} {...item} /> <HorizontalCard key={item.id} {...item} />
))} ))}
+17 -8
View File
@@ -33,21 +33,30 @@ interface Feature39Props {
const Feature39 = ({ className }: Feature39Props) => { const Feature39 = ({ className }: Feature39Props) => {
return ( return (
<section dir="rtl" lang="fa" className={cn("py-32", className)}> <section
<div className="container"> dir="rtl"
<h2 className="mb-9 text-3xl font-semibold lg:mb-14 lg:text-xl"> lang="fa"
className={cn(
"relative w-full max-w-full overflow-hidden py-32",
className,
)}
>
<div className="container min-w-0 max-w-full">
<h2 className="mb-9 max-w-full text-3xl font-semibold text-balance break-words lg:mb-14 lg:text-xl">
کمپین‌هایی بسازید که واقعاً تبدیل می‌شوند کمپین‌هایی بسازید که واقعاً تبدیل می‌شوند
</h2> </h2>
<div className="grid gap-10 md:grid-cols-2 lg:grid-cols-3 lg:gap-6"> <div className="grid min-w-0 gap-10 md:grid-cols-2 lg:grid-cols-3 lg:gap-6">
{features.map((feature) => ( {features.map((feature) => (
<div key={feature.title}> <div key={feature.title} className="min-w-0 max-w-full">
<img <img
src={feature.image} src={feature.image}
alt={feature.imageAlt} alt={feature.imageAlt}
className="aspect-video max-h-96 w-full rounded-lg object-cover" className="aspect-video max-h-96 w-full max-w-full rounded-lg object-cover"
/> />
<p className="mt-8 mb-2 text-lg font-semibold">{feature.title}</p> <p className="mt-8 mb-2 text-lg font-semibold break-words">
<p className="mb-4 text-muted-foreground"> {feature.title}
</p>
<p className="mb-4 text-pretty break-words text-muted-foreground">
{feature.description} {feature.description}
</p> </p>
<a href={feature.href} className="font-medium underline"> <a href={feature.href} className="font-medium underline">
+4 -4
View File
@@ -71,16 +71,16 @@ const Feature52 = ({ className }: Feature52Props) => {
<section dir="rtl" lang="fa" className={cn("py-32", className)}> <section dir="rtl" lang="fa" className={cn("py-32", className)}>
<div className="container"> <div className="container">
<Tabs defaultValue="feature-1"> <Tabs defaultValue="feature-1">
<TabsList className="flex w-full flex-wrap justify-between gap-2 bg-background p-0 group-data-horizontal/tabs:h-full"> <TabsList className="flex h-auto w-full flex-wrap items-stretch justify-between gap-2 bg-background p-0 group-data-horizontal/tabs:h-auto">
{tabs.map((tab, index) => ( {tabs.map((tab, index) => (
<TabsTrigger <TabsTrigger
key={index} key={index}
value={`feature-${index + 1}`} value={`feature-${index + 1}`}
className="flex flex-1 flex-col items-start justify-start gap-2 rounded-md border border-border bg-muted px-2 py-4 text-start whitespace-normal text-primary hover:border lg:py-6 group-data-[variant=default]/tabs-list:data-active:border-primary group-data-[variant=default]/tabs-list:data-active:shadow-none" className="flex h-auto min-h-0 min-w-0 flex-1 flex-col items-stretch justify-start gap-2 self-stretch rounded-md border border-border bg-muted px-2 py-4 text-start whitespace-normal text-primary hover:border lg:py-6 group-data-[variant=default]/tabs-list:data-active:border-primary group-data-[variant=default]/tabs-list:data-active:shadow-none"
> >
<div className="flex w-full flex-col items-center gap-4"> <div className="flex w-full flex-1 flex-col items-center justify-center gap-4">
{tab.icon} {tab.icon}
<p className="text-sm font-semibold lg:text-base"> <p className="line-clamp-2 min-h-10 w-full text-center text-sm leading-snug font-semibold text-balance lg:min-h-12 lg:text-base">
{tab.title} {tab.title}
</p> </p>
</div> </div>
+93 -36
View File
@@ -1,9 +1,14 @@
"use client"; "use client";
import { useState } from "react"; import { useEffect, useState } from "react";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import type { CarouselApi } from "@/components/ui/carousel";
import {
Carousel,
CarouselContent,
CarouselItem,
} from "@/components/ui/carousel";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
const features = [ const features = [
@@ -145,81 +150,133 @@ interface Feature54Props {
} }
const Feature54 = ({ className }: Feature54Props) => { const Feature54 = ({ className }: Feature54Props) => {
const [selection, setSelection] = useState("feature-5"); const [api, setApi] = useState<CarouselApi>();
const [selectedIndex, setSelectedIndex] = useState(0);
useEffect(() => {
if (!api) {
return;
}
const onSelect = () => {
setSelectedIndex(api.selectedScrollSnap());
};
onSelect();
api.on("select", onSelect);
api.on("reInit", onSelect);
return () => {
api.off("select", onSelect);
api.off("reInit", onSelect);
};
}, [api]);
return ( return (
<section dir="rtl" lang="fa" className={cn("py-32", className)}> <section
<div className="flex flex-col items-center md:gap-y-4 lg:px-16"> dir="rtl"
<div className="container flex flex-col items-center"> lang="fa"
<h3 className="mb-3 text-center text-3xl font-semibold text-pretty md:mb-4 md:text-xl lg:mb-6 lg:max-w-3xl lg:text-2xll"> className={cn(
"relative w-full max-w-full overflow-hidden py-32",
className,
)}
>
<div className="mx-auto flex w-full min-w-0 max-w-5xl flex-col items-center px-4 md:gap-y-4 sm:px-6 lg:px-8">
<div className="flex w-full min-w-0 flex-col items-center">
<h3 className="mb-3 max-w-full text-center text-3xl font-semibold text-pretty break-words md:mb-4 md:text-xl lg:mb-6 lg:max-w-3xl lg:text-2xll">
سطح دسترسی سطح دسترسی
</h3> </h3>
</div> </div>
<div className="w-full text-center">
<Tabs value={selection} onValueChange={setSelection}> <div className="mb-6 hidden w-full min-w-0 flex-col items-center md:flex lg:mb-8">
<div className="relative"> <div className="inline-flex w-fit max-w-full flex-wrap items-center justify-center gap-1 rounded-lg bg-muted p-[3px] text-muted-foreground">
<div className="container mb-6 hidden min-w-fit flex-col items-center md:flex lg:mb-8 lg:max-w-5xl"> {features.map((feature, index) => (
<TabsList className="gap-x-2"> <button
{features.map((feature) => ( key={feature.id}
<TabsTrigger key={feature.id} value={feature.id}> type="button"
onClick={() => api?.scrollTo(index)}
className={cn(
"inline-flex h-7 items-center justify-center rounded-md px-2.5 text-sm font-medium whitespace-nowrap transition-all",
selectedIndex === index
? "bg-background text-foreground shadow-sm"
: "text-foreground/60 hover:text-foreground",
)}
>
{feature.title} {feature.title}
</TabsTrigger> </button>
))} ))}
</TabsList>
</div> </div>
<div className="pointer-events-none absolute inset-0 bg-[linear-gradient(to_left,var(--color-background)_0%,transparent_10%,transparent_90%,var(--color-background)_100%)] md:hidden" />
</div> </div>
<div className="container w-full lg:max-w-5xl">
<div className="w-full min-w-0 max-w-full overflow-hidden">
<Carousel
className="w-full min-w-0 max-w-full"
setApi={setApi}
opts={{
align: "start",
direction: "rtl",
startIndex: 0,
containScroll: "trimSnaps",
}}
>
<CarouselContent className="ml-0">
{features.map((feature) => ( {features.map((feature) => (
<TabsContent key={feature.id} value={feature.id}> <CarouselItem
<div className=""> key={feature.id}
<div className="aspect-[1.67] w-full overflow-hidden rounded-lg border border-border bg-accent"> className="min-w-0 basis-full pl-0"
>
<div className="w-full min-w-0 max-w-full">
<div className="aspect-[5/3] w-full max-w-full overflow-hidden rounded-lg border border-border bg-accent">
<img <img
src={feature.image} src={feature.image}
alt={`نمای ${feature.title}`} alt={`نمای ${feature.title}`}
className="h-full w-full object-cover object-center" className="size-full max-w-full object-cover object-center"
draggable={false}
/> />
</div> </div>
<div <div
dir="rtl" dir="rtl"
className="hidden grid-cols-3 gap-6 py-6 md:grid" className="grid w-full min-w-0 grid-cols-1 gap-6 py-6 text-start md:grid-cols-3"
> >
{feature.subfeatures.map((subfeature) => ( {feature.subfeatures.map((subfeature) => (
<div <div
key={subfeature.id} key={`${feature.id}-${subfeature.id}`}
className="flex flex-col items-start text-right" className="flex min-w-0 flex-col items-start text-right"
> >
<p className="mb-2 text-xs font-semibold"> <p className="mb-2 text-xs font-semibold break-words">
{subfeature.title} {subfeature.title}
</p> </p>
<p className="mb-8 text-xs text-muted-foreground"> <p className="text-xs text-pretty break-words text-muted-foreground md:mb-8">
{subfeature.description} {subfeature.description}
</p> </p>
</div> </div>
))} ))}
</div> </div>
</div> </div>
</TabsContent> </CarouselItem>
))} ))}
</CarouselContent>
</Carousel>
</div> </div>
<div className="flex justify-center py-3 md:hidden">
{features.map((feature) => ( <div className="flex w-full min-w-0 justify-center py-3 md:hidden">
{features.map((feature, index) => (
<Button <Button
key={feature.id} key={feature.id}
variant="ghost" variant="ghost"
size="sm" size="sm"
aria-label={feature.title} aria-label={feature.title}
onClick={() => { onClick={() => api?.scrollTo(index)}
setSelection(feature.id);
}}
> >
<div <div
className={`size-2 rounded-full ${feature.id === selection ? "bg-primary" : "bg-input"}`} className={cn(
"size-2 rounded-full",
selectedIndex === index ? "bg-primary" : "bg-input",
)}
/> />
</Button> </Button>
))} ))}
</div> </div>
</Tabs>
</div>
</div> </div>
</section> </section>
); );
+17 -9
View File
@@ -31,33 +31,41 @@ interface Feature66Props {
const Feature66 = ({ className }: Feature66Props) => { const Feature66 = ({ className }: Feature66Props) => {
return ( return (
<section dir="rtl" lang="fa" className={cn("py-32", className)}> <section
<div className="container flex flex-col items-start gap-8 lg:gap-12 lg:px-16"> dir="rtl"
<h3 className="text-3xl font-semibold text-pretty md:text-xl lg:max-w-3xl lg:text-2xll"> lang="fa"
className={cn("w-full max-w-full py-32", className)}
>
<div className="mx-auto flex w-full min-w-0 max-w-full flex-col items-stretch gap-8 px-4 sm:container sm:px-6 lg:gap-12 lg:px-16">
<h3 className="w-full text-3xl font-semibold text-pretty md:text-xl lg:max-w-3xl lg:text-2xll">
سطح دسترسی سطح دسترسی
</h3> </h3>
<div className="grid w-full grid-cols-1 gap-4 max-md:grid-rows-[1fr_1fr] md:grid-cols-2 lg:gap-6"> <div className="grid w-full min-w-0 grid-cols-1 gap-4 max-md:grid-rows-[1fr_1fr] md:grid-cols-2 lg:gap-6">
{cards.map((card) => ( {cards.map((card) => (
<a key={card.logoAlt} href={card.href} className="h-full"> <a
key={card.logoAlt}
href={card.href}
className="block h-full w-full min-w-0"
>
<div <div
className={cn( className={cn(
"group relative h-full min-h-[27rem] max-w-full overflow-hidden rounded-xl md:aspect-5/4 lg:aspect-16/9", "group relative h-full min-h-[27rem] w-full max-w-full overflow-hidden rounded-xl md:aspect-5/4 lg:aspect-16/9",
card.cardClassName, card.cardClassName,
)} )}
> >
<img <img
src={card.image} src={card.image}
alt={card.imageAlt} alt={card.imageAlt}
className="absolute h-full w-full object-cover object-center transition-transform duration-300 group-hover:scale-105" className="absolute size-full max-w-full object-cover object-center transition-transform duration-300 group-hover:scale-105"
/> />
<div className="absolute inset-x-0 bottom-0 mt-auto max-h-[50%] min-h-[50%] bg-[linear-gradient(transparent,var(--primary)_80%)] mix-blend-multiply" /> <div className="absolute inset-x-0 bottom-0 mt-auto max-h-[50%] min-h-[50%] bg-[linear-gradient(transparent,var(--primary)_80%)] mix-blend-multiply" />
<div className="absolute inset-x-0 bottom-0 flex flex-col items-start p-6 text-primary-foreground md:p-8"> <div className="absolute inset-x-0 bottom-0 flex flex-col items-start p-5 text-primary-foreground sm:p-6 md:p-8">
<img <img
src={card.logo} src={card.logo}
alt={card.logoAlt} alt={card.logoAlt}
className="mb-3 h-8 invert" className="mb-3 h-8 invert"
/> />
<p className="text-xl font-semibold text-white"> <p className="text-xl font-semibold text-balance break-words text-white">
{card.description} {card.description}
</p> </p>
</div> </div>
+6 -6
View File
@@ -54,7 +54,7 @@ const Feature81 = ({ className }: Feature81Props) => {
با سگمنت‌بندی دقیق، پیام مناسب را به مخاطب مناسب برسانید. داده رفتاری نشان می‌دهد کدام محتوا بیشترین تأثیر را روی تبدیل دارد. با سگمنت‌بندی دقیق، پیام مناسب را به مخاطب مناسب برسانید. داده رفتاری نشان می‌دهد کدام محتوا بیشترین تأثیر را روی تبدیل دارد.
</p> </p>
</div> </div>
<div className="flex w-full flex-col gap-4 sm:gap-6 lg:h-80 lg:flex-row lg:gap-8"> <div className="flex w-full min-w-0 flex-col gap-4 sm:gap-6 lg:h-80 lg:flex-row lg:gap-8">
{items.map((item) => { {items.map((item) => {
const isOpen = activeId === item.id; const isOpen = activeId === item.id;
@@ -66,20 +66,20 @@ const Feature81 = ({ className }: Feature81Props) => {
aria-label={item.title} aria-label={item.title}
onClick={() => setActiveId(item.id)} onClick={() => setActiveId(item.id)}
className={cn( className={cn(
"group relative cursor-pointer overflow-clip rounded-lg text-start transition-all duration-500 ease-out", "group relative min-w-0 cursor-pointer overflow-clip rounded-lg text-start transition-all duration-500 ease-out",
isOpen isOpen
? "min-h-56 flex-2 lg:min-h-0" ? "h-56 flex-2 lg:h-full lg:min-h-0"
: "min-h-28 flex-1 lg:min-h-0", : "h-28 flex-1 lg:h-full lg:min-h-0",
)} )}
> >
<img <img
src={item.image} src={item.image}
alt={item.imageAlt} alt={item.imageAlt}
className="absolute h-full w-full object-cover object-center transition-transform duration-500 group-data-[state=closed]:scale-105" className="absolute inset-0 size-full object-cover object-center transition-transform duration-500 group-data-[state=closed]:scale-105"
/> />
<div <div
className={cn( className={cn(
"relative flex h-full w-full flex-col items-start gap-4 px-4 py-5 transition-colors duration-500 md:p-6 lg:p-8", "relative z-10 flex size-full flex-col items-start gap-4 px-4 py-5 transition-colors duration-500 md:p-6 lg:p-8",
isOpen isOpen
? "justify-between bg-black/60 hover:bg-black/65" ? "justify-between bg-black/60 hover:bg-black/65"
: "justify-end bg-black/75 hover:bg-black/80", : "justify-end bg-black/75 hover:bg-black/80",
+1 -1
View File
@@ -64,7 +64,7 @@ const Feature85 = ({ className }: Feature85Props) => {
زمان حل مسئله را کوتاه کنید زمان حل مسئله را کوتاه کنید
</h2> </h2>
<img <img
src="/block-media/shadcnblocks/block/placeholder-aspect-video-1.svg" src="/block-media/shadcnblocks/block/placeholder-1.svg"
alt="مدیریت تیکت" alt="مدیریت تیکت"
className="max-h-64 w-full rounded-xl object-cover" className="max-h-64 w-full rounded-xl object-cover"
/> />
+1 -1
View File
@@ -39,7 +39,7 @@ const Feature86 = ({ className }: Feature86Props) => {
</div> </div>
<div className="flex aspect-square w-full items-center justify-center bg-muted px-6 md:px-8 lg:col-span-2"> <div className="flex aspect-square w-full items-center justify-center bg-muted px-6 md:px-8 lg:col-span-2">
<img <img
src="/block-media/shadcnblocks/block/placeholder-aspect-video-1.svg" src="/block-media/shadcnblocks/block/placeholder-1.svg"
alt="دستیار هوش مصنوعی" alt="دستیار هوش مصنوعی"
className="aspect-video max-h-[464px] w-full rounded-lg object-cover" className="aspect-video max-h-[464px] w-full rounded-lg object-cover"
/> />
+2 -2
View File
@@ -57,11 +57,11 @@ const Feature95 = ({ className }: Feature95Props) => {
<TabsTrigger <TabsTrigger
key={tab.title} key={tab.title}
value={index.toString()} value={index.toString()}
className="group pointer-events-none flex !h-auto flex-col items-start rounded-none border-none p-0 whitespace-normal text-foreground after:hidden lg:pointer-events-auto" className="group flex !h-auto cursor-pointer flex-col items-start rounded-none border-none p-0 whitespace-normal text-foreground after:hidden"
> >
<div className="flex gap-4 rounded-md text-right hover:bg-muted lg:block lg:p-4"> <div className="flex gap-4 rounded-md text-right hover:bg-muted lg:block lg:p-4">
<div className="flex flex-col items-center lg:contents"> <div className="flex flex-col items-center lg:contents">
<span className="flex size-7 shrink-0 items-center justify-center rounded-full border bg-background font-mono text-xs font-medium lg:group-data-[state=active]:bg-primary lg:group-data-[state=active]:text-background lg:group-data-[state=active]:ring lg:group-data-[state=active]:ring-muted-foreground/40"> <span className="flex size-7 shrink-0 items-center justify-center rounded-full border bg-background font-mono text-xs font-medium group-data-[state=active]:bg-primary group-data-[state=active]:text-background group-data-[state=active]:ring group-data-[state=active]:ring-muted-foreground/40">
{(index + 1).toLocaleString("fa-IR")} {(index + 1).toLocaleString("fa-IR")}
</span> </span>
</div> </div>
+28 -15
View File
@@ -36,27 +36,40 @@ interface Feature97Props {
const Feature97 = ({ className }: Feature97Props) => { const Feature97 = ({ className }: Feature97Props) => {
return ( return (
<section dir="rtl" lang="fa" className={cn("py-32", className)}> <section
<div className="container"> dir="rtl"
<div className="mx-auto flex max-w-xl flex-col gap-6 text-center"> lang="fa"
<h2 className="text-xl font-semibold">فرایندها را استاندارد و سریع کنید</h2> className={cn("relative w-full max-w-full overflow-hidden py-32", className)}
<p className="text-lg"> >
<div className="container min-w-0 max-w-full">
<div className="mx-auto flex w-full min-w-0 max-w-xl flex-col gap-6 text-center">
<h2 className="max-w-full text-xl font-semibold text-balance break-words">
فرایندها را استاندارد و سریع کنید
</h2>
<p className="max-w-full text-lg text-pretty break-words">
اتوماسیون را در کل سازمان یکپارچه کنید اتوماسیون را در کل سازمان یکپارچه کنید
</p> </p>
<div className="flex flex-col justify-center gap-2 sm:flex-row"> <div className="flex w-full min-w-0 flex-col justify-center gap-2 sm:flex-row sm:flex-wrap sm:items-start">
<Button variant="outline">فرایند هوشمند</Button> <Button variant="outline" className="w-full shrink-0 sm:w-auto">
<Button> فرایند هوشمند
<Plus className="ms-2 h-auto w-4" /> </Button>
قوانین ساده تعریف کنید تا وظایف تکراری بدون دخالت دست انجام شود. تیم روی تصمیم‌های مهم تمرکز می‌کند و سرعت اجرا بالاتر می‌رود. <Button className="h-auto min-w-0 max-w-full whitespace-normal px-4 py-2 text-start text-pretty break-words sm:flex-1">
<Plus className="ms-2 size-4 shrink-0 self-start" />
<span className="min-w-0">
قوانین ساده تعریف کنید تا وظایف تکراری بدون دخالت دست انجام شود.
تیم روی تصمیم‌های مهم تمرکز می‌کند و سرعت اجرا بالاتر می‌رود.
</span>
</Button> </Button>
</div> </div>
</div> </div>
<div className="mx-auto mt-20 grid max-w-5xl gap-20 md:grid-cols-2"> <div className="mx-auto mt-20 grid w-full min-w-0 max-w-5xl gap-12 md:grid-cols-2 md:gap-20">
{highlights.map((item) => ( {highlights.map((item) => (
<div key={item.title} className="text-center"> <div key={item.title} className="min-w-0 max-w-full text-center">
<item.icon className="mx-auto h-auto w-7" /> <item.icon className="mx-auto size-7" />
<h3 className="mt-4 mb-2 text-xl font-semibold">{item.title}</h3> <h3 className="mt-4 mb-2 text-xl font-semibold break-words">
<p>{item.description}</p> {item.title}
</h3>
<p className="text-pretty break-words">{item.description}</p>
</div> </div>
))} ))}
</div> </div>
+1 -1
View File
@@ -53,7 +53,7 @@ const Hero146 = ({ className }: Hero146Props) => {
> >
<div> <div>
<img <img
src="/block-media/shadcnblocks/block/placeholder-aspect-video-1.svg" src="/block-media/shadcnblocks/block/placeholder-1.svg"
alt="تصویر نمونه" alt="تصویر نمونه"
className="w-full object-cover object-top-left" className="w-full object-cover object-top-left"
/> />
+1 -1
View File
@@ -95,7 +95,7 @@ const Hero170 = ({ className }: Hero170Props) => {
<div> <div>
<div className="relative mx-auto mt-16 w-full max-w-[52.8rem]"> <div className="relative mx-auto mt-16 w-full max-w-[52.8rem]">
<img <img
src="/block-media/shadcnblocks/block/placeholder-aspect-video-1.svg" src="/block-media/shadcnblocks/block/placeholder-1.svg"
alt="تصویر نمونه" alt="تصویر نمونه"
className="relative z-20 -mb-[2px] block w-full rounded-tl-lg rounded-tr-lg" className="relative z-20 -mb-[2px] block w-full rounded-tl-lg rounded-tr-lg"
/> />
+1 -1
View File
@@ -41,7 +41,7 @@ const Hero190 = () => {
<BorderedSection /> <BorderedSection />
<div className="container pt-0! lg:p-1.5!"> <div className="container pt-0! lg:p-1.5!">
<img <img
src="/block-media/shadcnblocks/block/placeholder-aspect-video-1.svg" src="/block-media/shadcnblocks/block/placeholder-1.svg"
alt="تصویر نمونه" alt="تصویر نمونه"
className="rounded-xl border object-contain p-1" className="rounded-xl border object-contain p-1"
style={{ style={{
+1 -1
View File
@@ -27,7 +27,7 @@ const Hero5 = ({ className }: Hero5Props) => {
</div> </div>
</div> </div>
<img <img
src="/block-media/shadcnblocks/block/placeholder-aspect-video-1.svg" src="/block-media/shadcnblocks/block/placeholder-1.svg"
alt="تصویر نمونه قهرمان" alt="تصویر نمونه قهرمان"
className="aspect-video rounded-md object-cover" className="aspect-video rounded-md object-cover"
/> />