Files
reui-blocks/blocks/order-summary5.tsx
T

235 lines
7.1 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 { CheckCircle, Package } from "lucide-react";
import { AspectRatio } from "@/components/ui/aspect-ratio";
import { Button } from "@/components/ui/button";
import { ScrollArea } from "@/components/ui/scroll-area";
import { Separator } from "@/components/ui/separator";
import {
Sheet,
SheetContent,
SheetDescription,
SheetFooter,
SheetHeader,
SheetTitle,
SheetTrigger,
} from "@/components/ui/sheet";
interface OrderItem {
id: string;
name: string;
image: string;
price: number;
quantity: number;
}
interface OrderSummaryData {
orderNumber: string;
items: OrderItem[];
subtotal: number;
shipping: number;
tax: number;
discount?: number;
total: number;
/** ISO 8601 date range for estimated delivery */
estimatedDeliveryFrom: string;
estimatedDeliveryTo?: string;
}
const currencyFormatter = new Intl.NumberFormat("fa-IR", {
style: "currency",
currency: "IRR",
});
const dateFormatter = new Intl.DateTimeFormat("fa-IR", {
year: "numeric",
month: "long",
day: "numeric",
});
const formatOrderDate = (isoDate: string) =>
dateFormatter.format(new Date(isoDate + "T12:00:00"));
const formatDeliveryEstimate = (from: string, to?: string) => {
if (to && to !== from) {
return `${formatOrderDate(from)} تا ${formatOrderDate(to)}`;
}
return formatOrderDate(from);
};
const DEFAULT_ORDER: OrderSummaryData = {
orderNumber: "ORD-2024-78432",
items: [
{
id: "1",
name: "کفش بژ مینیمال",
image:
"/block-media/shadcnblocks/block/ecommerce/clothes/Minimalist-Beige-Sneakers-2.png",
price: 120.0,
quantity: 1,
},
{
id: "2",
name: "تاپ آبی گلدوزی",
image:
"/block-media/shadcnblocks/block/ecommerce/clothes/Woman-in-Embroidered-Blue-Top-2.png",
price: 140.0,
quantity: 2,
},
{
id: "3",
name: "کلاه فدورا کلاسیک",
image:
"/block-media/shadcnblocks/block/ecommerce/accessories/Classic-Fedora-Hat-2.png",
price: 84.0,
quantity: 1,
},
],
subtotal: 484.0,
shipping: 12.0,
tax: 38.72,
discount: 50.0,
total: 484.72,
estimatedDeliveryFrom: "2024-12-18",
estimatedDeliveryTo: "2024-12-20",
};
interface OrderSummary5Props {
order?: OrderSummaryData;
}
const OrderSummary5 = ({ order = DEFAULT_ORDER }: OrderSummary5Props) => {
return (
<div
dir="rtl"
lang="fa"
className="flex min-h-[400px] items-center justify-center p-8"
>
<Sheet>
<SheetTrigger asChild>
<Button size="lg">مشاهده خلاصه سفارش</Button>
</SheetTrigger>
<SheetContent
dir="rtl"
lang="fa"
side="right"
className="flex w-full flex-col px-6 sm:max-w-md"
>
<SheetHeader className="px-0 text-start">
<div className="flex items-center gap-3">
<div className="flex size-10 items-center justify-center rounded-full bg-emerald-500">
<CheckCircle
className="size-5 text-white"
aria-hidden="true"
/>
</div>
<div>
<SheetTitle>سفارش تأیید شد</SheetTitle>
<SheetDescription dir="rtl">
{order.orderNumber}
</SheetDescription>
</div>
</div>
</SheetHeader>
<ScrollArea className="-mx-6 flex-1 px-6">
<div className="space-y-3 py-4">
{order.items.map((item) => (
<div key={item.id} className="flex gap-3">
<div className="w-16 shrink-0">
<AspectRatio
ratio={1}
className="overflow-hidden rounded-md bg-muted"
>
<img
src={item.image}
alt={item.name}
className="size-full object-cover"
/>
</AspectRatio>
</div>
<div className="min-w-0 flex-1">
<p className="truncate font-medium">{item.name}</p>
<p className="text-sm text-muted-foreground">
تعداد: {item.quantity.toLocaleString("fa-IR")}
</p>
</div>
<p className="font-semibold tabular-nums">
{currencyFormatter.format(item.price * item.quantity)}
</p>
</div>
))}
</div>
<Separator />
<div className="space-y-2 py-4 text-sm">
<div className="flex justify-between">
<span className="text-muted-foreground">جمع جزء</span>
<span className="tabular-nums">
{currencyFormatter.format(order.subtotal)}
</span>
</div>
<div className="flex justify-between">
<span className="text-muted-foreground">هزینه ارسال</span>
<span className="tabular-nums">
{order.shipping === 0
? "رایگان"
: currencyFormatter.format(order.shipping)}
</span>
</div>
<div className="flex justify-between">
<span className="text-muted-foreground">مالیات</span>
<span className="tabular-nums">
{currencyFormatter.format(order.tax)}
</span>
</div>
{order.discount && order.discount > 0 && (
<div className="flex justify-between text-emerald-600">
<span>تخفیف</span>
<span className="tabular-nums">
−{currencyFormatter.format(order.discount)}
</span>
</div>
)}
</div>
<Separator />
<div className="flex items-center justify-between py-4">
<span className="text-lg font-bold">مجموع</span>
<span className="text-xl font-bold tabular-nums">
{currencyFormatter.format(order.total)}
</span>
</div>
<div className="flex items-center gap-2 rounded-lg bg-muted p-3 text-sm">
<Package
className="size-4 shrink-0 text-muted-foreground"
aria-hidden="true"
/>
<span>
تحویل تقریبی:{" "}
{formatDeliveryEstimate(
order.estimatedDeliveryFrom,
order.estimatedDeliveryTo,
)}
</span>
</div>
</ScrollArea>
<SheetFooter className="flex-col gap-2 px-0 sm:flex-col">
<Button className="w-full">پیگیری سفارش</Button>
<Button variant="outline" className="w-full">
ادامه خرید
</Button>
</SheetFooter>
</SheetContent>
</Sheet>
</div>
);
};
export { OrderSummary5 };