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

148 lines
4.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
import { CheckCircle2, ShoppingBag, Users, 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 {
customerInitial: string;
productName: string;
timeAgo: string;
}
interface LivePurchase3Props {
purchases?: Purchase[];
viewerCount?: number;
purchasesToday?: number;
className?: string;
}
const DEFAULT_PURCHASES: Purchase[] = [
{
customerInitial: "س",
productName: "هندزفری بی‌سیم",
timeAgo: "همین الان",
},
{
customerInitial: "م",
productName: "ساعت هوشمند پرو",
timeAgo: "۱ دقیقه پیش",
},
{
customerInitial: "ع",
productName: "پایه لپ‌تاپ",
timeAgo: "۲ دقیقه پیش",
},
];
const formatCount = (value: number) =>
new Intl.NumberFormat("fa-IR").format(value);
const LivePurchase3 = ({
purchases = DEFAULT_PURCHASES,
viewerCount = 47,
purchasesToday = 156,
className,
}: LivePurchase3Props) => {
const [currentIndex, setCurrentIndex] = useState(0);
const [isVisible, setIsVisible] = useState(true);
const [showNotification, setShowNotification] = useState(true);
useEffect(() => {
if (purchases.length <= 1) return;
const timer = setInterval(() => {
setShowNotification(false);
setTimeout(() => {
setCurrentIndex((prev) => (prev + 1) % purchases.length);
setShowNotification(true);
}, 300);
}, 4000);
return () => clearInterval(timer);
}, [purchases.length]);
if (!isVisible) return null;
const current = purchases[currentIndex];
return (
<div
dir="rtl"
lang="fa"
className={cn("flex w-full justify-center p-6", className)}
>
<div className="flex flex-col gap-3">
<Card
className={cn(
"w-72 gap-0 p-0 shadow-lg transition-all duration-300",
showNotification
? "translate-y-0 opacity-100"
: "translate-y-2 opacity-0",
)}
>
<CardContent className="p-3">
<div className="flex items-center gap-3">
<div className="flex size-10 shrink-0 items-center justify-center rounded-full bg-emerald-100 text-emerald-600 dark:bg-emerald-900 dark:text-emerald-400">
<CheckCircle2 className="size-5" />
</div>
<div className="min-w-0 flex-1 text-start">
<p className="text-sm font-medium">خرید جدید!</p>
<p className="truncate text-sm text-muted-foreground">
یک نفر {current.productName} را خرید
</p>
<p className="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>
<div className="flex items-center gap-4 rounded-full bg-background px-4 py-2 shadow-lg ring-1 ring-border">
<div className="flex items-center gap-2">
<div className="relative">
<Users className="size-4 text-muted-foreground" />
<span className="absolute -top-1 -end-1 flex size-2">
<span className="absolute inline-flex size-full animate-ping rounded-full bg-emerald-400 opacity-75" />
<span className="relative inline-flex size-2 rounded-full bg-emerald-500" />
</span>
</div>
<span className="text-sm">
<span className="font-semibold">
{formatCount(viewerCount)}
</span>{" "}
<span className="text-muted-foreground">در حال مشاهده</span>
</span>
</div>
<div className="h-4 w-px bg-border" />
<div className="flex items-center gap-2">
<ShoppingBag className="size-4 text-muted-foreground" />
<span className="text-sm">
<span className="font-semibold">
{formatCount(purchasesToday)}
</span>{" "}
<span className="text-muted-foreground">فروش امروز</span>
</span>
</div>
</div>
</div>
</div>
);
};
export { LivePurchase3 };