|
|
@@ -0,0 +1,516 @@
|
|
|
+import {
|
|
|
+ DataUsage,
|
|
|
+ OrderDetail,
|
|
|
+ OrderHistory,
|
|
|
+} from "../../services/product/type";
|
|
|
+import { productApi } from "../../apis/productApi";
|
|
|
+import { startLoading, stopLoading } from "../../features/loading/loadingSlice";
|
|
|
+import { useAppDispatch } from "../../hooks/useRedux";
|
|
|
+import { useMutation } from "@tanstack/react-query";
|
|
|
+import React, { useState, useEffect } from "react";
|
|
|
+import { useLocation, useNavigate } from "react-router-dom";
|
|
|
+
|
|
|
+const OrderDetailView = () => {
|
|
|
+ const location = useLocation();
|
|
|
+ const dispatch = useAppDispatch();
|
|
|
+ const navigate = useNavigate();
|
|
|
+ const [activeTab, setActiveTab] = useState<"detail" | "manage">("detail");
|
|
|
+ const [orderDetails, setOrderDetails] = useState<OrderDetail[] | []>([]);
|
|
|
+ const [dataUsage, setDataUsage] = useState<DataUsage[] | []>([]);
|
|
|
+ const state = location.state as {
|
|
|
+ id: number;
|
|
|
+ orderHistory: OrderHistory;
|
|
|
+ };
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ getOrderDetailMutation.mutate();
|
|
|
+ }, []);
|
|
|
+
|
|
|
+ const getOrderDetailMutation = useMutation({
|
|
|
+ mutationFn: async () => {
|
|
|
+ dispatch(startLoading({}));
|
|
|
+ const res = await productApi.getOrderDetail({
|
|
|
+ orderId: state.id,
|
|
|
+ });
|
|
|
+ return res;
|
|
|
+ },
|
|
|
+ onSuccess: (data) => {
|
|
|
+ dispatch(stopLoading());
|
|
|
+ console.log("Get order detail response data:", data);
|
|
|
+ if (data && data.errorCode === "0") {
|
|
|
+ console.log("Get order detail successful");
|
|
|
+ setOrderDetails(data.data ?? []);
|
|
|
+ } else {
|
|
|
+ console.error("Get order detail failed, no token received");
|
|
|
+ }
|
|
|
+ },
|
|
|
+ onError: (error: any) => {
|
|
|
+ dispatch(stopLoading());
|
|
|
+ console.error("Get order detail error:", error.response.data);
|
|
|
+ },
|
|
|
+ });
|
|
|
+
|
|
|
+ const handleTabChange = async (tab: "detail" | "manage") => {
|
|
|
+ if (tab === "manage") {
|
|
|
+ // Load manage data if needed
|
|
|
+ dispatch(startLoading({}));
|
|
|
+ try {
|
|
|
+ const results = await Promise.all(
|
|
|
+ orderDetails.map(async (element) => {
|
|
|
+ const res = await productApi.checkDataUsage({
|
|
|
+ iccid: element?.iccid,
|
|
|
+ });
|
|
|
+
|
|
|
+ if (res && res.errorCode === "0") {
|
|
|
+ return res.data;
|
|
|
+ }
|
|
|
+
|
|
|
+ return null;
|
|
|
+ })
|
|
|
+ );
|
|
|
+
|
|
|
+ const validResults = results.filter(Boolean);
|
|
|
+ setDataUsage(validResults);
|
|
|
+
|
|
|
+ console.log("All data usage results:", validResults);
|
|
|
+ } catch (error) {
|
|
|
+ console.error("Check data usage error:", error);
|
|
|
+ } finally {
|
|
|
+ dispatch(stopLoading());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ setActiveTab(tab);
|
|
|
+ };
|
|
|
+
|
|
|
+ // Circular Progress Component
|
|
|
+ const CircularProgress = ({
|
|
|
+ used,
|
|
|
+ total,
|
|
|
+ label,
|
|
|
+ }: {
|
|
|
+ used: number;
|
|
|
+ total: number;
|
|
|
+ label: string;
|
|
|
+ }) => {
|
|
|
+ const radius = 50;
|
|
|
+ const circumference = 2 * Math.PI * radius;
|
|
|
+ const percentage = (used / total) * 100;
|
|
|
+ const strokeDashoffset = circumference - (percentage / 100) * circumference;
|
|
|
+
|
|
|
+ return (
|
|
|
+ <div className="flex flex-col items-center">
|
|
|
+ <div className="relative w-32 h-32 md:w-40 md:h-40 flex items-center justify-center mb-4">
|
|
|
+ <svg
|
|
|
+ className="transform -rotate-90 w-full h-full"
|
|
|
+ viewBox="0 0 120 120"
|
|
|
+ >
|
|
|
+ <circle
|
|
|
+ cx="60"
|
|
|
+ cy="60"
|
|
|
+ r={radius}
|
|
|
+ stroke="#f1f5f9"
|
|
|
+ strokeWidth="10"
|
|
|
+ fill="transparent"
|
|
|
+ />
|
|
|
+ <circle
|
|
|
+ cx="60"
|
|
|
+ cy="60"
|
|
|
+ r={radius}
|
|
|
+ stroke="#00b0f0"
|
|
|
+ strokeWidth="10"
|
|
|
+ fill="transparent"
|
|
|
+ strokeDasharray={circumference}
|
|
|
+ strokeDashoffset={strokeDashoffset}
|
|
|
+ strokeLinecap="round"
|
|
|
+ />
|
|
|
+ </svg>
|
|
|
+ <div className="absolute flex flex-col items-center">
|
|
|
+ <span className="text-xl md:text-2xl font-bold text-[#00b0f0]">
|
|
|
+ {used} / <br />
|
|
|
+ {total}
|
|
|
+ </span>
|
|
|
+ <span className="text-sm md:text-xl font-bold text-[#00b0f0]">
|
|
|
+ MB
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {/* <div className="absolute bottom-2 left-0 text-[10px] font-bold text-slate-400">
|
|
|
+ 0 MB
|
|
|
+ </div>
|
|
|
+ <div className="absolute bottom-2 right-0 text-[10px] font-bold text-slate-400">
|
|
|
+ {total} MB
|
|
|
+ </div> */}
|
|
|
+ </div>
|
|
|
+ <p className="text-slate-400 text-sm font-bold uppercase tracking-widest">
|
|
|
+ {label}
|
|
|
+ </p>
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ };
|
|
|
+ const getStatusColor = (status: number) => {
|
|
|
+ switch (status) {
|
|
|
+ case 2:
|
|
|
+ return "bg-[#00c087] text-white";
|
|
|
+ case 1:
|
|
|
+ return "bg-orange-400 text-white";
|
|
|
+ default:
|
|
|
+ return "bg-slate-800 text-white";
|
|
|
+ }
|
|
|
+ };
|
|
|
+ return (
|
|
|
+ <div className="bg-[#fcfdfe] min-h-screen pb-20">
|
|
|
+ {/* Breadcrumb */}
|
|
|
+ <div className="max-w-7xl mx-auto px-4 py-4 md:py-6 border-b border-slate-50">
|
|
|
+ <nav className="flex items-center space-x-2 text-xs md:text-sm text-slate-500 font-medium">
|
|
|
+ <button
|
|
|
+ // onClick={() => onViewChange(ViewMode.HOME)}
|
|
|
+ className="hover:text-[#EE0434] text-[16px]"
|
|
|
+ >
|
|
|
+ Home
|
|
|
+ </button>
|
|
|
+ <svg
|
|
|
+ className="w-3 h-3"
|
|
|
+ fill="none"
|
|
|
+ stroke="currentColor"
|
|
|
+ viewBox="0 0 24 24"
|
|
|
+ >
|
|
|
+ <path
|
|
|
+ d="M9 5l7 7-7 7"
|
|
|
+ strokeWidth={2.5}
|
|
|
+ strokeLinecap="round"
|
|
|
+ strokeLinejoin="round"
|
|
|
+ />
|
|
|
+ </svg>
|
|
|
+ <button
|
|
|
+ // onClick={() => onViewChange(ViewMode.ORDER_HISTORY)}
|
|
|
+ className="hover:text-[#EE0434] text-[16px] font-bold"
|
|
|
+ >
|
|
|
+ My eSIM
|
|
|
+ </button>
|
|
|
+ </nav>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div className="max-w-5xl mx-auto px-4 py-8">
|
|
|
+ {/* Back Button */}
|
|
|
+ <button
|
|
|
+ onClick={() => navigate(-1)}
|
|
|
+ className="mb-6 flex items-center space-x-2 px-4 py-2 bg-white border border-slate-200 rounded-lg text-slate-600 font-bold hover:bg-slate-50 transition-colors shadow-sm"
|
|
|
+ >
|
|
|
+ <svg
|
|
|
+ className="w-4 h-4"
|
|
|
+ fill="none"
|
|
|
+ stroke="currentColor"
|
|
|
+ viewBox="0 0 24 24"
|
|
|
+ >
|
|
|
+ <path
|
|
|
+ strokeLinecap="round"
|
|
|
+ strokeLinejoin="round"
|
|
|
+ strokeWidth={2}
|
|
|
+ d="M10 19l-7-7 7-7m8 14l-7-7 7-7"
|
|
|
+ />
|
|
|
+ </svg>
|
|
|
+ <span>Back</span>
|
|
|
+ </button>
|
|
|
+
|
|
|
+ {/* Main Info Card */}
|
|
|
+ <div className="bg-white rounded-2xl border border-[#00b0f0]/30 shadow-sm overflow-hidden mb-8">
|
|
|
+ <div className="p-6">
|
|
|
+ {/* Header */}
|
|
|
+ <div className="flex flex-col md:flex-row justify-between items-start md:items-center gap-4 mb-6">
|
|
|
+ <div className="flex items-center gap-4">
|
|
|
+ <div className="w-10 h-10 bg-[#00b0f0] rounded-xl flex items-center justify-center text-white shadow-sm">
|
|
|
+ <svg
|
|
|
+ className="w-6 h-6"
|
|
|
+ fill="none"
|
|
|
+ stroke="currentColor"
|
|
|
+ viewBox="0 0 24 24"
|
|
|
+ >
|
|
|
+ <path
|
|
|
+ strokeLinecap="round"
|
|
|
+ strokeLinejoin="round"
|
|
|
+ strokeWidth={2}
|
|
|
+ d="M3 3h2l.4 2M7 13h10l4-8H5.4M7 13L5.4 5M7 13l-2.293 2.293c-.63.63-.184 1.707.707 1.707H17m0 0a2 2 0 100 4 2 2 0 000-4zm-8 2a2 2 0 11-4 0 2 2 0 014 0z"
|
|
|
+ />
|
|
|
+ </svg>
|
|
|
+ </div>
|
|
|
+ <span className="text-xl md:text-2xl font-bold text-slate-800">
|
|
|
+ {state.orderHistory?.id}
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ {state.orderHistory?.status === 2 ? (
|
|
|
+ <span
|
|
|
+ className={`px-3 py-1 rounded-md text-sm font-bold shadow-sm ${getStatusColor(
|
|
|
+ state.orderHistory?.status
|
|
|
+ )}`}
|
|
|
+ >
|
|
|
+ Success
|
|
|
+ </span>
|
|
|
+ ) : state.orderHistory?.status === 1 ? (
|
|
|
+ <span
|
|
|
+ className={`px-3 py-1 rounded-md text-sm font-bold shadow-sm ${getStatusColor(
|
|
|
+ state.orderHistory?.status
|
|
|
+ )}`}
|
|
|
+ >
|
|
|
+ Pending Payment
|
|
|
+ </span>
|
|
|
+ ) : (
|
|
|
+ <span
|
|
|
+ className={`px-3 py-1 rounded-md text-sm font-bold shadow-sm ${getStatusColor(
|
|
|
+ state.orderHistory?.status
|
|
|
+ )}`}
|
|
|
+ >
|
|
|
+ Failure
|
|
|
+ </span>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {/* Tabs */}
|
|
|
+ <div className="flex space-x-1 mb-8">
|
|
|
+ <button
|
|
|
+ onClick={() => handleTabChange("detail")}
|
|
|
+ className={`px-6 py-2 rounded-lg font-bold text-sm transition-colors text-[16px] ${
|
|
|
+ activeTab === "detail"
|
|
|
+ ? "bg-[#00b0f0] text-white"
|
|
|
+ : "text-[#00b0f0] hover:bg-[#00b0f0]/10"
|
|
|
+ }`}
|
|
|
+ >
|
|
|
+ Detail
|
|
|
+ </button>
|
|
|
+ <button
|
|
|
+ onClick={() => handleTabChange("manage")}
|
|
|
+ className={`px-6 py-2 rounded-lg font-bold text-sm transition-colors text-[16px] ${
|
|
|
+ activeTab === "manage"
|
|
|
+ ? "bg-[#00b0f0] text-white"
|
|
|
+ : "text-[#00b0f0] hover:bg-[#00b0f0]/10"
|
|
|
+ }`}
|
|
|
+ >
|
|
|
+ Manage
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {/* Divider with Total */}
|
|
|
+ <div className="relative flex items-center justify-center border-t border-slate-100 py-8">
|
|
|
+ <span className="bg-white px-4 text-lg md:text-xl font-bold text-slate-800 absolute">
|
|
|
+ Total:{" "}
|
|
|
+ {state.orderHistory?.totalMoney.toLocaleString("vi-VN", {
|
|
|
+ minimumFractionDigits: 2,
|
|
|
+ maximumFractionDigits: 2,
|
|
|
+ })}{" "}
|
|
|
+ <span className="text-slate-500 font-normal">
|
|
|
+ ({state.orderHistory?.curency})
|
|
|
+ </span>
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {/* Customer Info Grid */}
|
|
|
+ <div className="grid grid-cols-1 md:grid-cols-4 gap-6 md:gap-4 mt-4">
|
|
|
+ <div className="flex flex-col">
|
|
|
+ <div className="flex items-center gap-2 text-slate-400 mb-1">
|
|
|
+ <svg
|
|
|
+ className="w-4 h-4"
|
|
|
+ fill="none"
|
|
|
+ stroke="currentColor"
|
|
|
+ viewBox="0 0 24 24"
|
|
|
+ >
|
|
|
+ <path
|
|
|
+ strokeLinecap="round"
|
|
|
+ strokeLinejoin="round"
|
|
|
+ strokeWidth={2}
|
|
|
+ d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"
|
|
|
+ />
|
|
|
+ </svg>
|
|
|
+ <span className="text-xs font-bold text-[16px]">
|
|
|
+ Full name
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ <span className="text-slate-800 font-semibold text-sm text-[16px]">
|
|
|
+ {state?.orderHistory.customerInfo.surName}{" "}
|
|
|
+ {state?.orderHistory.customerInfo.lastName}
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ <div className="flex flex-col">
|
|
|
+ <div className="flex items-center gap-2 text-slate-400 mb-1">
|
|
|
+ <svg
|
|
|
+ className="w-4 h-4"
|
|
|
+ fill="none"
|
|
|
+ stroke="currentColor"
|
|
|
+ viewBox="0 0 24 24"
|
|
|
+ >
|
|
|
+ <path
|
|
|
+ strokeLinecap="round"
|
|
|
+ strokeLinejoin="round"
|
|
|
+ strokeWidth={2}
|
|
|
+ d="M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498a1 1 0 01.684.949V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z"
|
|
|
+ />
|
|
|
+ </svg>
|
|
|
+ <span className="text-xs font-bold text-[16px]">
|
|
|
+ Phone number
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ <span className="text-slate-800 font-semibold text-sm text-[16px]">
|
|
|
+ {state?.orderHistory.customerInfo.phoneNumber}
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ <div className="flex flex-col">
|
|
|
+ <div className="flex items-center gap-2 text-slate-400 mb-1">
|
|
|
+ <svg
|
|
|
+ className="w-4 h-4"
|
|
|
+ fill="none"
|
|
|
+ stroke="currentColor"
|
|
|
+ viewBox="0 0 24 24"
|
|
|
+ >
|
|
|
+ <path
|
|
|
+ strokeLinecap="round"
|
|
|
+ strokeLinejoin="round"
|
|
|
+ strokeWidth={2}
|
|
|
+ d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"
|
|
|
+ />
|
|
|
+ </svg>
|
|
|
+ <span className="text-xs font-bold text-[16px]">Email</span>
|
|
|
+ </div>
|
|
|
+ <span className="text-slate-800 font-semibold text-sm text-[16px] break-all">
|
|
|
+ {state?.orderHistory.customerInfo.email}
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ <div className="flex flex-col">
|
|
|
+ <div className="flex items-center gap-2 text-slate-400 mb-1">
|
|
|
+ <svg
|
|
|
+ className="w-4 h-4"
|
|
|
+ fill="none"
|
|
|
+ stroke="currentColor"
|
|
|
+ viewBox="0 0 24 24"
|
|
|
+ >
|
|
|
+ <path
|
|
|
+ strokeLinecap="round"
|
|
|
+ strokeLinejoin="round"
|
|
|
+ strokeWidth={2}
|
|
|
+ d="M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 00-3 3z"
|
|
|
+ />
|
|
|
+ </svg>
|
|
|
+ <span className="text-xs font-bold text-[16px]">
|
|
|
+ Payment method
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ <span className="text-slate-800 font-semibold text-sm text-[16px]">
|
|
|
+ ONEPAY
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {/* Product Section */}
|
|
|
+ <div className="space-y-4">
|
|
|
+ {orderDetails.length > 0 && (
|
|
|
+ <div className="flex items-center space-x-3">
|
|
|
+ <img
|
|
|
+ src={`${orderDetails[0].areaIconUrl}`}
|
|
|
+ className="w-8 h-8 rounded-full object-cover border border-slate-200"
|
|
|
+ />
|
|
|
+ <h3 className="text-lg font-bold text-slate-900">
|
|
|
+ SIM {orderDetails[0].areaName}
|
|
|
+ </h3>
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+
|
|
|
+ <div
|
|
|
+ className={`rounded-2xl border border-slate-100 shadow-sm p-6 relative ${
|
|
|
+ activeTab === "manage" ? "bg-slate-50/50" : "bg-white"
|
|
|
+ }`}
|
|
|
+ >
|
|
|
+ {activeTab === "detail" ? (
|
|
|
+ // DETAIL TAB CONTENT
|
|
|
+ <div className="space-y-8">
|
|
|
+ {orderDetails.map((pkg, idx) => (
|
|
|
+ <div
|
|
|
+ key={idx}
|
|
|
+ className={`flex flex-col md:flex-row justify-between items-start md:items-center ${
|
|
|
+ idx !== orderDetails.length - 1
|
|
|
+ ? "border-b border-slate-100 pb-8"
|
|
|
+ : ""
|
|
|
+ }`}
|
|
|
+ >
|
|
|
+ <div className="space-y-2">
|
|
|
+ <div className="flex items-center gap-2">
|
|
|
+ <h4 className="text-xl font-bold text-slate-800">
|
|
|
+ {pkg.packageName}
|
|
|
+ </h4>
|
|
|
+ <span className="px-2 py-0.5 rounded bg-slate-100 text-slate-600 text-xs font-bold">
|
|
|
+ {pkg.id}
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ {/* <span className="inline-block bg-[#ff0050] text-white text-[10px] font-bold px-2 py-0.5 rounded">
|
|
|
+ TikTok
|
|
|
+ </span> */}
|
|
|
+ <p className="text-slate-500 text-sm font-bold">
|
|
|
+ Validity period: {pkg.dayDuration}
|
|
|
+ </p>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div className="mt-4 md:mt-0 flex flex-col items-end">
|
|
|
+ <button className="flex items-center text-[#00b0f0] font-bold text-sm mb-2 hover:underline">
|
|
|
+ <svg
|
|
|
+ className="w-4 h-4 mr-1"
|
|
|
+ fill="none"
|
|
|
+ stroke="currentColor"
|
|
|
+ viewBox="0 0 24 24"
|
|
|
+ >
|
|
|
+ <path
|
|
|
+ strokeLinecap="round"
|
|
|
+ strokeLinejoin="round"
|
|
|
+ strokeWidth={2}
|
|
|
+ d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"
|
|
|
+ />
|
|
|
+ <path
|
|
|
+ strokeLinecap="round"
|
|
|
+ strokeLinejoin="round"
|
|
|
+ strokeWidth={2}
|
|
|
+ d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"
|
|
|
+ />
|
|
|
+ </svg>
|
|
|
+ QR Code
|
|
|
+ </button>
|
|
|
+ <div className="text-right">
|
|
|
+ <span className="text-xl font-bold text-slate-800">
|
|
|
+ {pkg.paymentMoney.toLocaleString("vi-VN", {
|
|
|
+ minimumFractionDigits: 2,
|
|
|
+ maximumFractionDigits: 2,
|
|
|
+ })}
|
|
|
+ </span>
|
|
|
+ <span className="text-slate-500 font-medium ml-1 font-bold">
|
|
|
+ {" "}
|
|
|
+ đ
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+ ) : (
|
|
|
+ // MANAGE TAB CONTENT - Grid of Circular Progress
|
|
|
+ <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
|
|
|
+ {dataUsage.map((pkg, idx) => (
|
|
|
+ <div
|
|
|
+ key={idx}
|
|
|
+ className="bg-white p-6 rounded-2xl border border-slate-100 shadow-sm flex flex-col items-center hover:shadow-md transition-shadow"
|
|
|
+ >
|
|
|
+ <h4 className="text-lg font-bold text-slate-800 mb-2">
|
|
|
+ {orderDetails[idx].packageName}
|
|
|
+ </h4>
|
|
|
+ <CircularProgress
|
|
|
+ used={pkg.remainData}
|
|
|
+ total={pkg.totalData}
|
|
|
+ label={pkg.id}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+};
|
|
|
+
|
|
|
+export default OrderDetailView;
|