255 lines
8.5 KiB
TypeScript
255 lines
8.5 KiB
TypeScript
"use client";
|
|
|
|
import { ChevronLeft, ChevronRight } from "lucide-react";
|
|
import { useState } from "react";
|
|
|
|
import { AspectRatio } from "@/components/ui/aspect-ratio";
|
|
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
|
import { Button } from "@/components/ui/button";
|
|
import { Card, CardContent } from "@/components/ui/card";
|
|
import {
|
|
Carousel,
|
|
type CarouselApi,
|
|
CarouselContent,
|
|
CarouselItem,
|
|
} from "@/components/ui/carousel";
|
|
import { Separator } from "@/components/ui/separator";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
type ReviewType = {
|
|
author: {
|
|
image?: string;
|
|
name: string;
|
|
verifiedBuyer?: boolean;
|
|
};
|
|
comment: string;
|
|
image?: string;
|
|
product: {
|
|
name: string;
|
|
image: string;
|
|
link: string;
|
|
};
|
|
};
|
|
|
|
type ReviewCardType = ReviewType;
|
|
|
|
interface Reviews23Props {
|
|
reviews?: ReviewType[];
|
|
title?: string;
|
|
className?: string;
|
|
}
|
|
|
|
const REVIEWS: ReviewType[] = [
|
|
{
|
|
author: {
|
|
image: "/block-media/shadcnblocks/block/avatar-1.webp",
|
|
name: "ژاله وحدتی",
|
|
verifiedBuyer: true,
|
|
},
|
|
comment:
|
|
"رژگونه خیلی نرم پخش میشود و درخشش طبیعی میدهد. سبک است، قابل لایهگذاری است و تا آخر روز محو نمیشود. واقعاً تحت تأثیرم!",
|
|
image:
|
|
"/block-media/shadcnblocks/block/ecommerce/promotional/Close-Up-of-Womans-Face-1.png",
|
|
product: {
|
|
name: "رژگونه ابریشمی درخشان",
|
|
image:
|
|
"/block-media/shadcnblocks/block/ecommerce/skin-care-product/Makeup-Product-Flat-Lay-1.png",
|
|
link: "#",
|
|
},
|
|
},
|
|
{
|
|
author: {
|
|
image: "/block-media/shadcnblocks/block/avatar-3.webp",
|
|
name: "ژاله وحدتی",
|
|
verifiedBuyer: true,
|
|
},
|
|
comment:
|
|
"رنگش زیباست و بافت کرمیاش کار با آن را خیلی آسان میکند. لبها را آبرسان میکند و درخشش برنزی غنی میدهد. حالا جزو لوازم ثابت آرایشم شده.",
|
|
image:
|
|
"/block-media/shadcnblocks/block/ecommerce/skin-care-product/Close-Up-of-Lips-1.png",
|
|
product: {
|
|
name: "رژ لب برنزی درخشان",
|
|
image:
|
|
"/block-media/shadcnblocks/block/ecommerce/skin-care-product/Shimmering-Bronze-Lipstick-Close-Up-1.png",
|
|
link: "#",
|
|
},
|
|
},
|
|
{
|
|
author: {
|
|
image: "/block-media/shadcnblocks/block/avatar-4.webp",
|
|
name: "ژاله وحدتی",
|
|
verifiedBuyer: true,
|
|
},
|
|
comment:
|
|
"این سرم ضد چروک سریع جذب میشود و پوستم سفتتر و نرمتر شده. بعد از چند هفته خطوط ریز بهطور محسوسی نرمتر به نظر میرسند. عاشقش شدم!",
|
|
image:
|
|
"/block-media/shadcnblocks/block/ecommerce/skin-care-product/Skincare-Routine-Close-Up-1.png",
|
|
product: {
|
|
name: "سرم ضد چروک جوانساز",
|
|
image:
|
|
"/block-media/shadcnblocks/block/ecommerce/skin-care-product/Frosted-Glass-Dropper-1.png",
|
|
link: "#",
|
|
},
|
|
},
|
|
{
|
|
author: {
|
|
image: "/block-media/shadcnblocks/block/avatar-5.webp",
|
|
name: "ژاله وحدتی",
|
|
verifiedBuyer: true,
|
|
},
|
|
comment:
|
|
"کرمی با آبرسانی عمیق که غنی است ولی سنگین نیست. پوستم تا آخر روز نرم، مرطوب و درخشان میماند. برای پوست خشک یا حساس عالی است.",
|
|
image:
|
|
"/block-media/shadcnblocks/block/ecommerce/skin-care-product/Woman-Applying-Face-Cream-1.png",
|
|
product: {
|
|
name: "کرم آبران فوقالعاده صورت",
|
|
image:
|
|
"/block-media/shadcnblocks/block/ecommerce/skin-care-product/pexels-carlos-diaz-216017-18350286-1.jpg",
|
|
link: "#",
|
|
},
|
|
},
|
|
{
|
|
author: {
|
|
image: "/block-media/shadcnblocks/block/avatar-2.webp",
|
|
name: "ژاله وحدتی",
|
|
verifiedBuyer: true,
|
|
},
|
|
comment:
|
|
"کرم بدن واقعاً لوکس است! روی پوست ذوب میشود و آن را ابریشمی، تغذیهشده و با عطر ملایم میگذارد. برای استفاده روزانه عالی شدیداً پیشنهاد میکنم.",
|
|
image:
|
|
"/block-media/shadcnblocks/block/ecommerce/promotional/Skincare-Routine-1.png",
|
|
product: {
|
|
name: "کرم مغذی بدن",
|
|
image:
|
|
"/block-media/shadcnblocks/block/ecommerce/skin-care-product/Elegant-Hand-Holding-Skincare-Product-1.png",
|
|
link: "#",
|
|
},
|
|
},
|
|
];
|
|
|
|
const Reviews23 = ({
|
|
reviews = REVIEWS,
|
|
title = "مشتریان عاشق ما هستند",
|
|
className,
|
|
}: Reviews23Props) => {
|
|
const [api, setApi] = useState<CarouselApi>();
|
|
|
|
return (
|
|
<section
|
|
dir="rtl"
|
|
lang="fa"
|
|
className={cn("overflow-hidden py-32", className)}
|
|
>
|
|
<div className="container space-y-8">
|
|
<div className="flex items-center justify-between gap-4">
|
|
<h2 className="font-serif text-xl">{title}</h2>
|
|
<div className="flex gap-3">
|
|
<Button
|
|
onClick={() => api?.scrollPrev()}
|
|
variant="outline"
|
|
className="rounded-full"
|
|
size="icon-lg"
|
|
aria-label="اسلاید قبلی"
|
|
>
|
|
<ChevronRight />
|
|
</Button>
|
|
<Button
|
|
onClick={() => api?.scrollNext()}
|
|
variant="outline"
|
|
className="rounded-full"
|
|
size="icon-lg"
|
|
aria-label="اسلاید بعدی"
|
|
>
|
|
<ChevronLeft />
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<Carousel
|
|
setApi={setApi}
|
|
className="[&>div]:overflow-visible"
|
|
opts={{ direction: "rtl", align: "start" }}
|
|
>
|
|
<CarouselContent>
|
|
{reviews.map((review, index) => (
|
|
<CarouselItem
|
|
className="sm:basis-9/12 md:basis-150 lg:basis-1/2 xl:basis-1/3"
|
|
key={`${review.product.name}-${index}`}
|
|
>
|
|
<ReviewCard {...review} />
|
|
</CarouselItem>
|
|
))}
|
|
</CarouselContent>
|
|
</Carousel>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
};
|
|
|
|
const ReviewCard = ({ image, product, author, comment }: ReviewCardType) => {
|
|
const initials = author.name
|
|
.split(/\s+/)
|
|
.slice(0, 2)
|
|
.map((part) => part[0])
|
|
.join("");
|
|
|
|
return (
|
|
<Card className="h-full rounded-lg px-4 py-5">
|
|
<CardContent className="flex h-full flex-col justify-between p-0">
|
|
<div className="flex gap-3 max-md:flex-col-reverse">
|
|
<div className="flex-1 space-y-4">
|
|
<div className="flex gap-3">
|
|
<Avatar className="size-12.5 border">
|
|
<AvatarImage src={author.image} alt={author.name} />
|
|
<AvatarFallback>{initials}</AvatarFallback>
|
|
</Avatar>
|
|
<div className="space-y-0.5">
|
|
<h3 className="font-serif text-base leading-normal">
|
|
{author.name}
|
|
</h3>
|
|
{author.verifiedBuyer && (
|
|
<span className="text-xs text-muted-foreground">
|
|
خریدار تأییدشده
|
|
</span>
|
|
)}
|
|
</div>
|
|
</div>
|
|
<p className="text-sm leading-relaxed text-muted-foreground">
|
|
{comment}
|
|
</p>
|
|
</div>
|
|
{image && (
|
|
<div className="basis-40">
|
|
<AspectRatio ratio={0.8} className="overflow-hidden rounded-lg">
|
|
<img
|
|
src={image}
|
|
alt={`تصویر نظر ${author.name} درباره ${product.name}`}
|
|
className="block size-full object-cover object-center"
|
|
/>
|
|
</AspectRatio>
|
|
</div>
|
|
)}
|
|
</div>
|
|
<div className="mt-auto space-y-3 pt-3">
|
|
<Separator />
|
|
<a href={product.link} className="group flex items-center gap-3">
|
|
<div className="size-10 shrink-0 overflow-hidden rounded-sm">
|
|
<img
|
|
src={product.image}
|
|
alt={product.name}
|
|
className="block size-full object-cover object-center"
|
|
/>
|
|
</div>
|
|
<span className="text-sm font-medium underline-offset-2 group-hover:underline">
|
|
{product.name}
|
|
</span>
|
|
</a>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
);
|
|
};
|
|
|
|
export { Reviews23 };
|