244 lines
8.3 KiB
TypeScript
244 lines
8.3 KiB
TypeScript
"use client";
|
|
|
|
import AutoScroll from "embla-carousel-auto-scroll";
|
|
import {
|
|
Globe,
|
|
MessagesSquare,
|
|
MoveRight,
|
|
PanelsTopLeft,
|
|
PenTool,
|
|
ScissorsLineDashed,
|
|
ShieldCheck,
|
|
Users,
|
|
Zap,
|
|
type LucideIcon,
|
|
} from "lucide-react";
|
|
|
|
import { Avatar, AvatarImage } from "@/components/ui/avatar";
|
|
import { Button } from "@/components/ui/button";
|
|
import {
|
|
Carousel,
|
|
CarouselContent,
|
|
CarouselItem,
|
|
} from "@/components/ui/carousel";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
const avatars = [
|
|
"/block-media/shadcnblocks/block/avatar-1.webp",
|
|
"/block-media/shadcnblocks/block/avatar-6.webp",
|
|
"/block-media/shadcnblocks/block/avatar-3.webp",
|
|
];
|
|
|
|
const features: {
|
|
title: string;
|
|
description: string;
|
|
icon: LucideIcon;
|
|
}[] = [
|
|
{
|
|
title: "تقویم تیمی",
|
|
description: "برنامه تیم را هماهنگ کنید و تداخل وظایف را کاهش دهید.",
|
|
icon: ScissorsLineDashed,
|
|
},
|
|
{
|
|
title: "اشتراک فایل",
|
|
description: "نسخه درست فایل همیشه در دسترس همه اعضا باشد.",
|
|
icon: Globe,
|
|
},
|
|
{
|
|
title: "منشن و بحث",
|
|
description: "بحث را کنار هر تسک نگه دارید تا تصمیمها گم نشود.",
|
|
icon: PanelsTopLeft,
|
|
},
|
|
{
|
|
title: "ردیابی زمان",
|
|
description:
|
|
"وضعیت هر کار را در یک نما ببینید و گلوگاهها را زودتر پیدا کنید.",
|
|
icon: PenTool,
|
|
},
|
|
{
|
|
title: "نقش و دسترسی",
|
|
description: "برنامه تیم را هماهنگ کنید و تداخل وظایف را کاهش دهید.",
|
|
icon: Zap,
|
|
},
|
|
{
|
|
title: "چکلیست تحویل",
|
|
description: "نسخه درست فایل همیشه در دسترس همه اعضا باشد.",
|
|
icon: ShieldCheck,
|
|
},
|
|
{
|
|
title: "گزارش پیشرفت",
|
|
description: "بحث را کنار هر تسک نگه دارید تا تصمیمها گم نشود.",
|
|
icon: MessagesSquare,
|
|
},
|
|
{
|
|
title: "برد Kanban",
|
|
description:
|
|
"وضعیت هر کار را در یک نما ببینید و گلوگاهها را زودتر پیدا کنید.",
|
|
icon: Users,
|
|
},
|
|
];
|
|
|
|
function FeatureCard({
|
|
title,
|
|
description,
|
|
icon: Icon,
|
|
className,
|
|
}: (typeof features)[number] & { className?: string }) {
|
|
return (
|
|
<div
|
|
className={cn(
|
|
"flex min-w-0 flex-col rounded-xl border p-5 md:p-7",
|
|
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>
|
|
);
|
|
}
|
|
|
|
interface Feature114Props {
|
|
className?: string;
|
|
}
|
|
|
|
const Feature114 = ({ className }: Feature114Props) => {
|
|
const firstHalf = features.slice(0, features.length / 2);
|
|
const secondHalf = features.slice(features.length / 2);
|
|
|
|
return (
|
|
<section
|
|
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">
|
|
<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">
|
|
{avatars.map((src, index) => (
|
|
<Avatar key={src} className="size-11 border lg:size-16">
|
|
<AvatarImage
|
|
src={src}
|
|
alt={`تصویر پروفایل ${(index + 1).toLocaleString("fa-IR")}`}
|
|
/>
|
|
</Avatar>
|
|
))}
|
|
</span>
|
|
<h1 className="max-w-full text-3xl font-semibold text-balance break-words md:text-2xll">
|
|
همکاری از راه دور را ساده کنید
|
|
</h1>
|
|
<p className="max-w-full text-pretty break-words text-muted-foreground md:text-lg">
|
|
هر عضو بداند چه زمانی چه کاری دارد
|
|
</p>
|
|
<p className="max-w-full text-sm text-pretty break-words text-muted-foreground md:text-base">
|
|
اعلانهای هوشمند فقط اطلاعات ضروری را میرسانند و حواسپرتی را کم
|
|
میکنند.
|
|
</p>
|
|
<Button size="lg" className="w-fit max-w-full gap-2">
|
|
شروع همکاری
|
|
<MoveRight className="size-5 shrink-0 rtl:rotate-180" />
|
|
</Button>
|
|
<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 min-w-0 flex-col gap-1">
|
|
<h2 className="text-3xl font-semibold break-words md:text-2xll">
|
|
{(85).toLocaleString("fa-IR")}٪
|
|
</h2>
|
|
<p className="text-sm text-pretty break-words text-muted-foreground md:text-lg">
|
|
تصمیمها را سریعتر هماهنگ کنید
|
|
</p>
|
|
</div>
|
|
<div className="flex min-w-0 flex-col gap-1">
|
|
<h2 className="text-3xl font-semibold break-words md:text-2xll">
|
|
{(25000).toLocaleString("fa-IR")}+
|
|
</h2>
|
|
<p className="text-sm text-pretty break-words text-muted-foreground md:text-lg">
|
|
تیمها را در یک فضای مشترک همراستا کنید
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="grid w-full min-w-0 gap-4 overflow-hidden md:gap-7 lg:grid-cols-2">
|
|
<Carousel
|
|
opts={{
|
|
loop: true,
|
|
align: "start",
|
|
}}
|
|
plugins={[
|
|
AutoScroll({
|
|
speed: 0.7,
|
|
}),
|
|
]}
|
|
orientation="vertical"
|
|
className="pointer-events-none relative w-full min-w-0 lg:hidden"
|
|
>
|
|
<CarouselContent className="mt-0 max-h-[600px]">
|
|
{features.map((feature) => (
|
|
<CarouselItem key={feature.title} className="pt-4">
|
|
<FeatureCard {...feature} />
|
|
</CarouselItem>
|
|
))}
|
|
</CarouselContent>
|
|
<div className="absolute inset-0 bg-linear-to-t from-background via-transparent to-background" />
|
|
</Carousel>
|
|
<Carousel
|
|
opts={{
|
|
loop: true,
|
|
align: "start",
|
|
}}
|
|
plugins={[
|
|
AutoScroll({
|
|
speed: 0.7,
|
|
}),
|
|
]}
|
|
orientation="vertical"
|
|
className="pointer-events-none relative hidden w-full min-w-0 lg:block"
|
|
>
|
|
<CarouselContent className="mt-0 max-h-[600px]">
|
|
{firstHalf.map((feature) => (
|
|
<CarouselItem key={feature.title} className="pt-4">
|
|
<FeatureCard {...feature} className="p-4 md:p-7" />
|
|
</CarouselItem>
|
|
))}
|
|
</CarouselContent>
|
|
<div className="absolute inset-0 bg-linear-to-t from-background via-transparent to-background" />
|
|
</Carousel>
|
|
<Carousel
|
|
opts={{
|
|
loop: true,
|
|
align: "start",
|
|
}}
|
|
plugins={[
|
|
AutoScroll({
|
|
speed: 0.7,
|
|
}),
|
|
]}
|
|
orientation="vertical"
|
|
className="pointer-events-none relative hidden w-full min-w-0 lg:block"
|
|
>
|
|
<CarouselContent className="mt-0 max-h-[600px]">
|
|
{secondHalf.map((feature) => (
|
|
<CarouselItem key={feature.title} className="pt-4">
|
|
<FeatureCard {...feature} className="p-4 md:p-7" />
|
|
</CarouselItem>
|
|
))}
|
|
</CarouselContent>
|
|
<div className="absolute inset-0 bg-linear-to-t from-background via-transparent to-background" />
|
|
</Carousel>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
};
|
|
|
|
export { Feature114 };
|