Files
reui-blocks/blocks/live-purchase2.tsx
T

148 lines
4.1 KiB
TypeScript

"use client";
import { MapPin, X } from "lucide-react";
import { useEffect, useState } from "react";
import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";
interface Purchase {
customerName: string;
customerLocation: string;
productName: string;
productImage: string;
}
const DEFAULT_PURCHASES: Purchase[] = [
{
customerName: "رضا",
customerLocation: "مشهد",
productName: "هدفون پریمیوم",
productImage:
"/block-media/shadcnblocks/block/ecommerce/electronics/Modern-White-Headphones-1.png",
},
{
customerName: "نازنین",
customerLocation: "تبریز",
productName: "کیف چرم",
productImage:
"/block-media/shadcnblocks/block/placeholder-1.svg",
},
{
customerName: "امیر",
customerLocation: "کرمان",
productName: "کفش ورزشی",
productImage:
"/block-media/shadcnblocks/block/placeholder-2.svg",
},
];
interface LivePurchase2Props {
purchases?: Purchase[];
autoRotate?: boolean;
rotateInterval?: number;
className?: string;
}
const LivePurchase2 = ({
purchases = DEFAULT_PURCHASES,
autoRotate = true,
rotateInterval = 6000,
className,
}: LivePurchase2Props) => {
const [currentIndex, setCurrentIndex] = useState(0);
const [isVisible, setIsVisible] = useState(false);
const [isDismissed, setIsDismissed] = useState(false);
useEffect(() => {
if (isDismissed) return;
const showTimer = setTimeout(() => {
setIsVisible(true);
}, 2000);
return () => clearTimeout(showTimer);
}, [isDismissed]);
useEffect(() => {
if (!autoRotate || purchases.length <= 1 || !isVisible || isDismissed)
return;
const timer = setInterval(() => {
setIsVisible(false);
setTimeout(() => {
setCurrentIndex((prev) => (prev + 1) % purchases.length);
setIsVisible(true);
}, 500);
}, rotateInterval);
return () => clearInterval(timer);
}, [autoRotate, rotateInterval, purchases.length, isVisible, isDismissed]);
const handleDismiss = () => {
setIsVisible(false);
setIsDismissed(true);
};
if (isDismissed) return null;
const current = purchases[currentIndex];
return (
<div
dir="rtl"
lang="fa"
className={cn("flex w-full justify-center p-6", className)}
>
<div
className={cn(
"relative flex max-w-fit items-center gap-3 rounded-full bg-background py-2 ps-2 pe-10 shadow-lg ring-1 ring-border transition-all duration-500",
isVisible
? "translate-y-0 opacity-100"
: "pointer-events-none translate-y-4 opacity-0",
)}
>
<div className="absolute -top-1.5 end-2">
<span className="relative flex size-3">
<span className="absolute inline-flex size-full animate-ping rounded-full bg-emerald-400 opacity-75" />
<span className="relative inline-flex size-3 rounded-full bg-emerald-500" />
</span>
</div>
<Button
type="button"
variant="ghost"
size="icon"
className="absolute end-3 size-6 shrink-0 rounded-full"
aria-label="بستن"
onClick={handleDismiss}
>
<X className="size-3" />
</Button>
<div className="size-10 shrink-0 overflow-hidden rounded-full bg-muted">
<img
src={current.productImage}
alt={current.productName}
className="size-full object-cover"
/>
</div>
<div className="flex min-w-0 flex-col text-start">
<p className="text-sm">
<span className="font-semibold">{current.customerName}</span>{" "}
<span className="font-medium">{current.productName}</span>{" "}
<span className="text-muted-foreground">را خرید کرد</span>
</p>
<p className="flex items-center gap-1 text-xs text-muted-foreground">
<MapPin className="size-3 shrink-0" />
{current.customerLocation}
</p>
</div>
</div>
</div>
);
};
export { LivePurchase2 };