2026-07-11 21:21:29 +03:30
|
|
|
|
"use client";
|
|
|
|
|
|
|
|
|
|
|
|
import { X } from "lucide-react";
|
|
|
|
|
|
import { useEffect, useState } from "react";
|
|
|
|
|
|
|
|
|
|
|
|
import { Button } from "@/components/ui/button";
|
|
|
|
|
|
import { Card, CardContent } from "@/components/ui/card";
|
|
|
|
|
|
import { cn } from "@/lib/utils";
|
|
|
|
|
|
|
|
|
|
|
|
interface Purchase {
|
|
|
|
|
|
id: string;
|
|
|
|
|
|
customerName: string;
|
|
|
|
|
|
customerLocation: string;
|
|
|
|
|
|
customerAvatar?: string;
|
|
|
|
|
|
productName: string;
|
|
|
|
|
|
productImage: string;
|
|
|
|
|
|
timeAgo: string;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const DEFAULT_PURCHASES: Purchase[] = [
|
|
|
|
|
|
{
|
|
|
|
|
|
id: "1",
|
|
|
|
|
|
customerName: "سارا محمدی",
|
|
|
|
|
|
customerLocation: "تهران",
|
|
|
|
|
|
productName: "هدفون بیسیم",
|
|
|
|
|
|
productImage:
|
|
|
|
|
|
"/block-media/shadcnblocks/block/ecommerce/electronics/Modern-White-Headphones-1.png",
|
|
|
|
|
|
timeAgo: "۲ دقیقه پیش",
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: "2",
|
|
|
|
|
|
customerName: "علی رضایی",
|
|
|
|
|
|
customerLocation: "اصفهان",
|
|
|
|
|
|
productName: "کیف چرم دوشی",
|
|
|
|
|
|
productImage:
|
|
|
|
|
|
"/block-media/shadcnblocks/block/ecommerce/clothes/maroon-leather-handbag.png",
|
|
|
|
|
|
timeAgo: "۵ دقیقه پیش",
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: "3",
|
|
|
|
|
|
customerName: "مریم حسینی",
|
|
|
|
|
|
customerLocation: "شیراز",
|
|
|
|
|
|
productName: "هودی نخی",
|
|
|
|
|
|
productImage:
|
|
|
|
|
|
"/block-media/shadcnblocks/block/ecommerce/clothes/black-hoodie-against-light-background.png",
|
|
|
|
|
|
timeAgo: "۸ دقیقه پیش",
|
|
|
|
|
|
},
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
interface LivePurchase1Props {
|
|
|
|
|
|
purchases?: Purchase[];
|
|
|
|
|
|
autoRotate?: boolean;
|
|
|
|
|
|
rotateInterval?: number;
|
|
|
|
|
|
className?: string;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const LivePurchase1 = ({
|
|
|
|
|
|
purchases = DEFAULT_PURCHASES,
|
|
|
|
|
|
autoRotate = true,
|
|
|
|
|
|
rotateInterval = 5000,
|
|
|
|
|
|
className,
|
|
|
|
|
|
}: LivePurchase1Props) => {
|
|
|
|
|
|
const [currentIndex, setCurrentIndex] = useState(0);
|
|
|
|
|
|
const [isVisible, setIsVisible] = useState(true);
|
|
|
|
|
|
const [isAnimating, setIsAnimating] = useState(false);
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
if (!autoRotate || purchases.length <= 1) return;
|
|
|
|
|
|
|
|
|
|
|
|
const timer = setInterval(() => {
|
|
|
|
|
|
setIsAnimating(true);
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
setCurrentIndex((prev) => (prev + 1) % purchases.length);
|
|
|
|
|
|
setIsAnimating(false);
|
|
|
|
|
|
}, 300);
|
|
|
|
|
|
}, rotateInterval);
|
|
|
|
|
|
|
|
|
|
|
|
return () => clearInterval(timer);
|
|
|
|
|
|
}, [autoRotate, rotateInterval, purchases.length]);
|
|
|
|
|
|
|
|
|
|
|
|
if (!isVisible) return null;
|
|
|
|
|
|
|
|
|
|
|
|
const current = purchases[currentIndex];
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<div
|
|
|
|
|
|
dir="rtl"
|
|
|
|
|
|
lang="fa"
|
2026-07-15 20:22:14 +02:00
|
|
|
|
className={cn("flex w-full justify-center p-6", className)}
|
2026-07-11 21:21:29 +03:30
|
|
|
|
>
|
2026-07-15 20:22:14 +02:00
|
|
|
|
<Card
|
|
|
|
|
|
className={cn(
|
|
|
|
|
|
"w-full max-w-100 gap-0 p-0 shadow-lg transition-all duration-300",
|
|
|
|
|
|
isAnimating && "translate-y-2 opacity-0",
|
|
|
|
|
|
)}
|
|
|
|
|
|
>
|
|
|
|
|
|
<CardContent className="p-3">
|
|
|
|
|
|
<div className="flex items-start gap-3">
|
|
|
|
|
|
<div className="size-14 shrink-0 overflow-hidden rounded-md bg-muted">
|
|
|
|
|
|
<img
|
|
|
|
|
|
src={current.productImage}
|
|
|
|
|
|
alt={current.productName}
|
|
|
|
|
|
className="size-full object-cover"
|
|
|
|
|
|
/>
|
2026-07-11 21:21:29 +03:30
|
|
|
|
</div>
|
2026-07-15 20:22:14 +02:00
|
|
|
|
|
|
|
|
|
|
<div className="min-w-0 flex-1 text-start">
|
|
|
|
|
|
<p className="text-sm">
|
|
|
|
|
|
<span className="font-semibold">{current.customerName}</span>{" "}
|
|
|
|
|
|
<span className="text-muted-foreground">از</span>{" "}
|
|
|
|
|
|
<span>{current.customerLocation}</span>
|
|
|
|
|
|
</p>
|
|
|
|
|
|
<p className="text-sm text-muted-foreground">
|
|
|
|
|
|
همین الان{" "}
|
|
|
|
|
|
<span className="font-medium text-foreground">
|
|
|
|
|
|
{current.productName}
|
|
|
|
|
|
</span>{" "}
|
|
|
|
|
|
را خرید کرد
|
|
|
|
|
|
</p>
|
|
|
|
|
|
<p className="mt-1 text-xs text-muted-foreground">
|
|
|
|
|
|
{current.timeAgo}
|
|
|
|
|
|
</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<Button
|
|
|
|
|
|
type="button"
|
|
|
|
|
|
variant="ghost"
|
|
|
|
|
|
size="icon"
|
|
|
|
|
|
className="size-6 shrink-0"
|
|
|
|
|
|
aria-label="بستن"
|
|
|
|
|
|
onClick={() => setIsVisible(false)}
|
|
|
|
|
|
>
|
|
|
|
|
|
<X className="size-3" />
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</CardContent>
|
|
|
|
|
|
</Card>
|
2026-07-11 21:21:29 +03:30
|
|
|
|
</div>
|
|
|
|
|
|
);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
export { LivePurchase1 };
|