From 10b395577a8c3694978531f5459957dea19c5360 Mon Sep 17 00:00:00 2001 From: hamid zarghami Date: Sun, 26 Oct 2025 13:12:02 +0330 Subject: [PATCH] fix: price variant + perfoma invoice download --- src/app/cart/invoice/page.tsx | 192 ++++++++++++++++++ src/app/cart/page.tsx | 4 +- src/app/globals.css | 23 +++ .../product/components/ShopInformation.tsx | 16 +- src/components/CartSummary.tsx | 16 +- 5 files changed, 238 insertions(+), 13 deletions(-) create mode 100644 src/app/cart/invoice/page.tsx diff --git a/src/app/cart/invoice/page.tsx b/src/app/cart/invoice/page.tsx new file mode 100644 index 0000000..88a1cc4 --- /dev/null +++ b/src/app/cart/invoice/page.tsx @@ -0,0 +1,192 @@ +'use client' +import { useGetCart } from "@/app/cart/hooks/useCartData" +import { NumberFormat, toJalaliDate } from "@/config/func" +import { useRouter } from "next/navigation" +import { useEffect } from "react" +import Image from "next/image" + +const InvoicePage = () => { + const { data, isLoading } = useGetCart() + const router = useRouter() + + useEffect(() => { + if (!isLoading && !data?.results?.cart?.items?.length) { + router.push('/cart') + } + }, [data, isLoading, router]) + + if (isLoading) { + return ( +
+
در حال بارگذاری...
+
+ ) + } + + const cart = data?.results?.cart + if (!cart?.items?.length) return null + + const handlePrint = () => { + window.print() + } + + return ( +
+
+
+ + +
+ +
+
+
+ لوگو +
+
+

پیش‌فاکتور خرید

+

+ تاریخ: {toJalaliDate(new Date())} +

+
+
+ +
+
+

نام و نام خانوادگی

+

{cart.user?.fullName || '-'}

+
+
+

شماره تماس

+

{cart.user?.phoneNumber || '-'}

+
+
+

شماره فاکتور

+

{cart._id.slice(-8).toUpperCase()}

+
+
+

تعداد کالا

+

{NumberFormat(cart.items_count)} محصول

+
+
+ +
+

لیست محصولات

+
+ + + + + + + + + + + + + {cart.items.map((item, index) => { + const retailPrice = item.variant.price.retailPrice + const sellingPrice = item.variant.price.selling_price + const totalRetail = retailPrice * item.quantity + const totalSelling = sellingPrice * item.quantity + const discount = totalRetail - totalSelling + + return ( + + + + + + + + + ) + })} + +
ردیفمحصولتعدادقیمت واحدتخفیفقیمت کل
+ {NumberFormat(index + 1)} + +
+

{item.product.title_fa}

+

+ فروشنده: {item.variant.shop.shopName} +

+ {item.variant.warranty && ( +

+ گارانتی: {item.variant.warranty.name} +

+ )} +
+
+ {NumberFormat(item.quantity)} + + {NumberFormat(retailPrice)} تومان + + {discount > 0 ? `${NumberFormat(discount)} تومان` : '-'} + + {NumberFormat(totalSelling)} تومان +
+
+
+ +
+
+
+
+ قیمت کالاها: + {NumberFormat(cart.retail_price)} تومان +
+
+ تخفیف: + + {NumberFormat(cart.total_discount)} تومان + +
+ {cart.coupon_discount > 0 && ( +
+ تخفیف کد تخفیف: + + {NumberFormat(cart.coupon_discount)} تومان + +
+ )} +
+ جمع کل: + + {NumberFormat(cart.payable_price)} تومان + +
+
+
+
+ +
+

+ این پیش‌فاکتور صرفاً جهت اطلاع شما صادر شده و فاکتور نهایی پس از تکمیل خرید ارسال خواهد شد. +

+
+
+
+
+ ) +} + +export default InvoicePage + diff --git a/src/app/cart/page.tsx b/src/app/cart/page.tsx index 9d78b98..038429e 100644 --- a/src/app/cart/page.tsx +++ b/src/app/cart/page.tsx @@ -8,9 +8,10 @@ import { NextPage } from "next" import { useGetCart, useRemoveAllCart } from "./hooks/useCartData" import { toast } from "@/components/Toast" import { useState } from "react" +import { useRouter } from "next/navigation" const Cart: NextPage = () => { - + const router = useRouter() const { data, isLoading, error } = useGetCart(); const removeAllCartMutation = useRemoveAllCart() const [isClearingAll, setIsClearingAll] = useState(false) @@ -113,6 +114,7 @@ const Cart: NextPage = () => { total={cart?.payable_price || 0} confirmHref="/cart/shipping" confirmLabel="ادامه به آدرس و ارسال" + onDownloadInvoice={() => router.push('/cart/invoice')} className="w-full lg:w-[360px] xl:w-[400px]" /> diff --git a/src/app/globals.css b/src/app/globals.css index e19c00c..d5fed93 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -282,3 +282,26 @@ textarea.place-black::placeholder { .rmdp-container { width: 100%; } + +/* Print Styles */ +@media print { + body { + print-color-adjust: exact; + -webkit-print-color-adjust: exact; + padding-bottom: 0 !important; + } + + /* Hide all fixed elements (header, mobile menu, etc) */ + .fixed { + display: none !important; + } + + /* Hide no-print class */ + .no-print { + display: none !important; + } + + @page { + margin: 1cm; + } +} diff --git a/src/app/product/components/ShopInformation.tsx b/src/app/product/components/ShopInformation.tsx index 2254952..5a2c7cd 100644 --- a/src/app/product/components/ShopInformation.tsx +++ b/src/app/product/components/ShopInformation.tsx @@ -8,6 +8,7 @@ import Image from 'next/image' import Cart from './Cart' import { PRIMARY_COLOR } from '@/config/const' import { useRouter } from 'next/navigation' +import { useProductStore } from '../store/Store' interface ShopInformationProps { product: Product @@ -15,12 +16,17 @@ interface ShopInformationProps { const ShopInformation = ({ product }: ShopInformationProps) => { const router = useRouter() + const { variantId } = useProductStore() - const defaultVariant = product.default_variant - const shop = defaultVariant.shop - const price = defaultVariant.price - const warranty = defaultVariant.warranty - const postingTime = defaultVariant.postingTime + // پیدا کردن variant انتخابی یا استفاده از default_variant + const selectedVariant = variantId + ? product.variants.find((variant) => variant._id === variantId) || product.default_variant + : product.default_variant + + const shop = selectedVariant.shop + const price = selectedVariant.price + const warranty = selectedVariant.warranty + const postingTime = selectedVariant.postingTime const formatPrice = (price: number) => { return price.toLocaleString('fa-IR') diff --git a/src/components/CartSummary.tsx b/src/components/CartSummary.tsx index 097e7a1..7c99336 100644 --- a/src/components/CartSummary.tsx +++ b/src/components/CartSummary.tsx @@ -53,13 +53,15 @@ const CartSummary: FC = (props) => {
- + {onDownloadInvoice && ( + + )}