This commit is contained in:
@@ -4,6 +4,7 @@ import {
|
||||
PaymentMethodsResponse,
|
||||
CreateOrderResponse,
|
||||
OrderDetailResponse,
|
||||
PayOrderResponse,
|
||||
} from "../types/Types";
|
||||
|
||||
export const getShipmentMethod = async (): Promise<ShipmentMethodsResponse> => {
|
||||
@@ -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<PayOrderResponse> => {
|
||||
const { data } = await api.get<PayOrderResponse>(`/public/payments/pay-order/${id}`);
|
||||
return data;
|
||||
};
|
||||
|
||||
@@ -272,6 +272,12 @@ export interface CreateOrderData {
|
||||
|
||||
export type CreateOrderResponse = BaseResponse<CreateOrderData>;
|
||||
|
||||
export interface PayOrderData {
|
||||
paymentUrl?: string;
|
||||
}
|
||||
|
||||
export type PayOrderResponse = BaseResponse<PayOrderData>;
|
||||
|
||||
export interface OrderDetailUser {
|
||||
id: string;
|
||||
createdAt: string;
|
||||
|
||||
@@ -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() {
|
||||
<div className="flex flex-col gap-4">
|
||||
{orderDetail.data.items.map((item) => {
|
||||
const product = orderItemToProduct(item);
|
||||
const showPendingBadge = isVariablePricing(product);
|
||||
const needsConfirmation = isVariablePricing(product) || product.needAdminAcceptance;
|
||||
|
||||
return (
|
||||
<MenuItemRenderer key={item.id}>
|
||||
@@ -208,11 +233,18 @@ function OrderTrackingPage() {
|
||||
variantId={item.variant.id}
|
||||
variantValue={item.variant.value}
|
||||
readOnly
|
||||
displayQuantity={item.quantity}
|
||||
badge={
|
||||
showPendingBadge ? (
|
||||
needsConfirmation ? (
|
||||
item.status === "confirmed" ? (
|
||||
<span className="inline-block rounded-lg bg-green-50 dark:bg-green-950/40 px-3 py-1.5 text-xs text-green-600 dark:text-green-400">
|
||||
{ordersTranslations.itemStatus.confirmed}
|
||||
</span>
|
||||
) : (
|
||||
<span className="inline-block rounded-lg bg-orange-50 dark:bg-orange-950/40 px-3 py-1.5 text-xs text-orange-600 dark:text-orange-400">
|
||||
{ordersTranslations.itemStatus.needConfirmation}
|
||||
</span>
|
||||
)
|
||||
) : undefined
|
||||
}
|
||||
/>
|
||||
@@ -237,9 +269,19 @@ function OrderTrackingPage() {
|
||||
|
||||
<div className="p-4 border-t border-border bg-container">
|
||||
<div className="max-w-2xl mx-auto grid grid-cols-2 gap-4">
|
||||
<Button className="dark:bg-white dark:text-black! dark:hover:bg-gray-100" onClick={() => router.push(`/${name}`)} type="button">
|
||||
<Button className="bg-disabled! text-foreground!" onClick={() => router.push(`/${name}`)} type="button">
|
||||
بازگشت به منو
|
||||
</Button>
|
||||
{showPayButton ? (
|
||||
<Button
|
||||
type="button"
|
||||
onClick={onPayOrder}
|
||||
disabled={isPayDisabled}
|
||||
pending={isPaying}
|
||||
>
|
||||
پرداخت
|
||||
</Button>
|
||||
) : (
|
||||
<Button
|
||||
type="submit"
|
||||
onClick={toggleCancelModal}
|
||||
@@ -248,6 +290,7 @@ function OrderTrackingPage() {
|
||||
>
|
||||
لغو سفارش
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -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
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{!readOnly && (
|
||||
{readOnly && quantityLabel ? (
|
||||
<div className="flex flex-col justify-end shrink-0">
|
||||
<span className="text-sm font-semibold text-foreground">{quantityLabel}</span>
|
||||
</div>
|
||||
) : !readOnly ? (
|
||||
<div className="flex flex-col justify-end shrink-0">
|
||||
{showDetailsInsteadOfAdd ? (
|
||||
<div className="w-[115px]">
|
||||
@@ -200,7 +214,7 @@ const MenuItem = ({ product, variantId: variantIdProp, variantValue: variantValu
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
) : null}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
+2
-2
@@ -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";
|
||||
|
||||
@@ -20,7 +20,8 @@
|
||||
"Wallet": "پرداخت با کیف پول"
|
||||
},
|
||||
"itemStatus": {
|
||||
"needConfirmation": "در انتظار تایید قیمت نهایی"
|
||||
"needConfirmation": "در انتظار تایید قیمت نهایی",
|
||||
"confirmed": "تایید شده"
|
||||
},
|
||||
"status": {
|
||||
"new": "سفارش جدید",
|
||||
|
||||
Reference in New Issue
Block a user