From cc27bce1b2118dcf189e6a5e475974e96bdb4499 Mon Sep 17 00:00:00 2001 From: hamid zarghami Date: Mon, 29 Jun 2026 09:37:07 +0330 Subject: [PATCH] compelete variable --- .../order/checkout/service/OrderService.ts | 5 +- .../(Dialogs)/order/checkout/types/Types.ts | 6 ++ .../(Dialogs)/order/track/[id]/page.tsx | 73 +++++++++++++++---- src/components/listview/MenuItem.tsx | 22 +++++- src/config/const.ts | 4 +- src/locales/fa/orders.json | 3 +- 6 files changed, 89 insertions(+), 24 deletions(-) diff --git a/src/app/[name]/(Dialogs)/order/checkout/service/OrderService.ts b/src/app/[name]/(Dialogs)/order/checkout/service/OrderService.ts index 52f06af..1b201c9 100644 --- a/src/app/[name]/(Dialogs)/order/checkout/service/OrderService.ts +++ b/src/app/[name]/(Dialogs)/order/checkout/service/OrderService.ts @@ -4,6 +4,7 @@ import { PaymentMethodsResponse, CreateOrderResponse, OrderDetailResponse, + PayOrderResponse, } from "../types/Types"; export const getShipmentMethod = async (): Promise => { @@ -81,7 +82,7 @@ export const cancelOrder = async (id: string) => { return data; }; -export const confirmOrder = async (id: string) => { - const { data } = await api.get(`/public/payments/pay-order/${id}`); +export const confirmOrder = async (id: string): Promise => { + const { data } = await api.get(`/public/payments/pay-order/${id}`); return data; }; diff --git a/src/app/[name]/(Dialogs)/order/checkout/types/Types.ts b/src/app/[name]/(Dialogs)/order/checkout/types/Types.ts index f9f1097..8abacaa 100644 --- a/src/app/[name]/(Dialogs)/order/checkout/types/Types.ts +++ b/src/app/[name]/(Dialogs)/order/checkout/types/Types.ts @@ -272,6 +272,12 @@ export interface CreateOrderData { export type CreateOrderResponse = BaseResponse; +export interface PayOrderData { + paymentUrl?: string; +} + +export type PayOrderResponse = BaseResponse; + export interface OrderDetailUser { id: string; createdAt: string; diff --git a/src/app/[name]/(Dialogs)/order/track/[id]/page.tsx b/src/app/[name]/(Dialogs)/order/track/[id]/page.tsx index 1e1dbe3..ccb6a7a 100644 --- a/src/app/[name]/(Dialogs)/order/track/[id]/page.tsx +++ b/src/app/[name]/(Dialogs)/order/track/[id]/page.tsx @@ -16,7 +16,7 @@ import clsx from "clsx"; import { Clock } from "iconsax-react"; import { useParams, useRouter } from "next/navigation"; import React from "react"; -import { useCancelOrder, useGetOrderDetail } from "../../checkout/hooks/useOrderData"; +import { useCancelOrder, useConfirmOrder, useGetOrderDetail } from "../../checkout/hooks/useOrderData"; import type { OrderDetailItem } from "../../checkout/types/Types"; const orderItemToProduct = (item: OrderDetailItem): Product => { @@ -107,6 +107,31 @@ function OrderTrackingPage() { const { state: cancelModal, toggle: toggleCancelModal } = useToggle(); const { data: orderDetail, isLoading } = useGetOrderDetail(id as string); const { mutate: cancelOrder } = useCancelOrder(); + const { mutate: payOrder, isPending: isPaying } = useConfirmOrder(); + + const orderStatus = orderDetail?.data?.status; + const showPayButton = orderStatus === "pendingPayment" || orderStatus === "needConfirmation"; + const isPayDisabled = orderStatus === "needConfirmation"; + + const onPayOrder = () => { + if (!id || isPayDisabled) return; + + payOrder(id as string, { + onSuccess: (data) => { + const paymentUrl = data?.data?.paymentUrl; + if (paymentUrl) { + toast("در حال ریدایرکت به صفحه پرداخت...", "success"); + window.location.href = paymentUrl; + } else { + queryClient.invalidateQueries({ queryKey: ["order-detail", id] }); + toast("پرداخت با موفقیت انجام شد", "success"); + } + }, + onError: (error) => { + toast(extractErrorMessage(error), "error"); + }, + }); + }; const onCancelOrder = (e: React.MouseEvent | null) => { if (!e || !id) return; @@ -199,7 +224,7 @@ function OrderTrackingPage() {
{orderDetail.data.items.map((item) => { const product = orderItemToProduct(item); - const showPendingBadge = isVariablePricing(product); + const needsConfirmation = isVariablePricing(product) || product.needAdminAcceptance; return ( @@ -208,11 +233,18 @@ function OrderTrackingPage() { variantId={item.variant.id} variantValue={item.variant.value} readOnly + displayQuantity={item.quantity} badge={ - showPendingBadge ? ( - - {ordersTranslations.itemStatus.needConfirmation} - + needsConfirmation ? ( + item.status === "confirmed" ? ( + + {ordersTranslations.itemStatus.confirmed} + + ) : ( + + {ordersTranslations.itemStatus.needConfirmation} + + ) ) : undefined } /> @@ -237,17 +269,28 @@ function OrderTrackingPage() {
- - + {showPayButton ? ( + + ) : ( + + )}
diff --git a/src/components/listview/MenuItem.tsx b/src/components/listview/MenuItem.tsx index 3f5f082..8ad4af0 100644 --- a/src/components/listview/MenuItem.tsx +++ b/src/components/listview/MenuItem.tsx @@ -3,7 +3,7 @@ import { useCart } from "@/app/[name]/(Dialogs)/cart/hook/useCart"; import type { Product, ProductImage } from "@/app/[name]/(Main)/types/Types"; -import { getPrimaryVariantId, getProductEffectivePrice, getPurchaseUnitLabel, hasVariants, isVariablePricing } from "@/app/[name]/(Main)/types/Types"; +import { formatPurchaseQuantity, getPrimaryVariantId, getProductEffectivePrice, getPurchaseUnitLabel, hasVariants, isVariablePricing } from "@/app/[name]/(Main)/types/Types"; import { CartQuantityControl } from "@/components/CartQuantityControl"; import { ArrowLeft } from "iconsax-react"; import Link from "next/link"; @@ -22,11 +22,13 @@ interface MenuItemProps { viewMode?: MenuItemViewMode; /** فقط نمایش اطلاعات بدون دکمه‌های افزودن/جزئیات */ readOnly?: boolean; + /** تعداد انتخاب‌شده — در حالت readOnly نمایش داده می‌شود */ + displayQuantity?: number; /** برچسب اختیاری بالای آیتم */ badge?: ReactNode; } -const MenuItem = ({ product, variantId: variantIdProp, variantValue: variantValueProp, viewMode = "list", readOnly = false, badge }: MenuItemProps) => { +const MenuItem = ({ product, variantId: variantIdProp, variantValue: variantValueProp, viewMode = "list", readOnly = false, displayQuantity, badge }: MenuItemProps) => { const { items, addToCart, removeFromCart, isCartMutating } = useCart(); const params = useParams<{ name: string }>(); const name = params?.name || ""; @@ -102,6 +104,14 @@ const MenuItem = ({ product, variantId: variantIdProp, variantValue: variantValu const hasDiscount = useMemo(() => (product.discount || 0) > 0, [product.discount]); + const quantityLabel = useMemo(() => { + if (displayQuantity == null) return null; + if (withVariablePricing) { + return formatPurchaseQuantity(displayQuantity, product.purchaseUnit); + } + return `${displayQuantity.toLocaleString("fa-IR")}×`; + }, [displayQuantity, withVariablePricing, product.purchaseUnit]); + const handleAddToCart = () => { if (variantId) addToCart(variantId); }; @@ -185,7 +195,11 @@ const MenuItem = ({ product, variantId: variantIdProp, variantValue: variantValu )}
- {!readOnly && ( + {readOnly && quantityLabel ? ( +
+ {quantityLabel} +
+ ) : !readOnly ? (
{showDetailsInsteadOfAdd ? (
@@ -200,7 +214,7 @@ const MenuItem = ({ product, variantId: variantIdProp, variantValue: variantValu
)}
- )} + ) : null} ); diff --git a/src/config/const.ts b/src/config/const.ts index 18c5731..62db678 100644 --- a/src/config/const.ts +++ b/src/config/const.ts @@ -1,5 +1,5 @@ // export const API_BASE_URL = "https://dmenuplus-api.dev.danakcorp.com"; -// export const API_BASE_URL = "https://dkala-api.danakcorp.com"; -export const API_BASE_URL = "http://192.168.99.131:4000"; +export const API_BASE_URL = "https://dkala-api.danakcorp.com"; +// export const API_BASE_URL = "http://192.168.99.131:4000"; export const TOKEN_NAME = "dkala-t"; export const REFRESH_TOKEN_NAME = "dkala-rt"; diff --git a/src/locales/fa/orders.json b/src/locales/fa/orders.json index 80f628f..adbac65 100644 --- a/src/locales/fa/orders.json +++ b/src/locales/fa/orders.json @@ -20,7 +20,8 @@ "Wallet": "پرداخت با کیف پول" }, "itemStatus": { - "needConfirmation": "در انتظار تایید قیمت نهایی" + "needConfirmation": "در انتظار تایید قیمت نهایی", + "confirmed": "تایید شده" }, "status": { "new": "سفارش جدید",