From f4259dee2633cb3f5f8b45508ec058bd1f0e8221 Mon Sep 17 00:00:00 2001 From: Mohammadali Date: Tue, 1 Sep 2026 09:43:44 +0330 Subject: [PATCH] feat: add order components and server error handling --- public/server-error-icon.svg | 3 + .../(shop)/orders/(routes)/(landing)/page.tsx | 2 +- .../(shop)/orders/(routes)/[orderId]/page.tsx | 13 +++- src/app/(customer)/(shop)/orders/layout.tsx | 2 +- src/components/orders/order-header.tsx | 59 ++++++++------- src/components/orders/order-item.tsx | 38 ++++++---- src/components/orders/order-items.tsx | 20 +++++ .../orders/order-payment-sticky.tsx | 34 +++++++++ src/components/orders/order-server-error.tsx | 19 +++-- .../orders/order-stepper-status.tsx | 17 ++--- .../orders/order-time-address-info-alert.tsx | 23 ++++++ src/components/orders/orders-skeleton.tsx | 74 +++++++++---------- 12 files changed, 205 insertions(+), 99 deletions(-) create mode 100644 public/server-error-icon.svg create mode 100644 src/components/orders/order-items.tsx create mode 100644 src/components/orders/order-payment-sticky.tsx create mode 100644 src/components/orders/order-time-address-info-alert.tsx diff --git a/public/server-error-icon.svg b/public/server-error-icon.svg new file mode 100644 index 0000000..e3a5791 --- /dev/null +++ b/public/server-error-icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/app/(customer)/(shop)/orders/(routes)/(landing)/page.tsx b/src/app/(customer)/(shop)/orders/(routes)/(landing)/page.tsx index 3a83cda..a348c2e 100644 --- a/src/app/(customer)/(shop)/orders/(routes)/(landing)/page.tsx +++ b/src/app/(customer)/(shop)/orders/(routes)/(landing)/page.tsx @@ -11,7 +11,7 @@ import OrderHeader from "@/components/orders/order-header"; export default async function OrdersPage() { return
{/* */} - + {/* */} { Array.from({ length: 20 }, (_, index) => ) } diff --git a/src/app/(customer)/(shop)/orders/(routes)/[orderId]/page.tsx b/src/app/(customer)/(shop)/orders/(routes)/[orderId]/page.tsx index fbeef54..790f486 100644 --- a/src/app/(customer)/(shop)/orders/(routes)/[orderId]/page.tsx +++ b/src/app/(customer)/(shop)/orders/(routes)/[orderId]/page.tsx @@ -1,11 +1,18 @@ +import OrderItems from '@/components/orders/order-items' +import OrderPaymentSticky from '@/components/orders/order-payment-sticky' import OrderStepperStatus from '@/components/orders/order-stepper-status' +import OrderTimeAddressInfoAlert from '@/components/orders/order-time-address-info-alert' import React from 'react' const OrderDetail = () => { - return
- -

در حال آماده‌سازی

+ return
+ +

در حال آماده‌سازی

+ + + +
} diff --git a/src/app/(customer)/(shop)/orders/layout.tsx b/src/app/(customer)/(shop)/orders/layout.tsx index a4562ae..3bff83a 100644 --- a/src/app/(customer)/(shop)/orders/layout.tsx +++ b/src/app/(customer)/(shop)/orders/layout.tsx @@ -6,7 +6,7 @@ interface OrderLayoutInterface { } const OrderLayout = async ({ children }: OrderLayoutInterface) => { - return
+ return
{children}
diff --git a/src/components/orders/order-header.tsx b/src/components/orders/order-header.tsx index bc46b24..cd6ea49 100644 --- a/src/components/orders/order-header.tsx +++ b/src/components/orders/order-header.tsx @@ -1,39 +1,44 @@ 'use client'; -import { ArrowRight, ShoppingBagIcon } from 'lucide-react' +import { ArrowRight, ShoppingBagIcon } from 'lucide-react'; import { usePathname, useRouter } from 'next/navigation'; const OrderHeader = () => { + const router = useRouter(); + const pathname = usePathname(); + const isExactOrders = pathname === '/orders'; - const router = useRouter(); - const pathname = usePathname(); - const isExactOrders = pathname === '/orders' + const onBackHandler = () => { + router.back(); + }; - const onBackHandler = () => { - router.back(); - } + const goToCartPage = () => { + router.push('/cart'); + }; - const goToCartPage = () => { - router.push('/cart'); - } + return ( +
+
+ +

سفارش‌ها

+
- return
-
- -

سفارش‌ها

+ {isExactOrders && ( +
+
+ +
+ + + 90 +
- {isExactOrders && -
-
- -
- - - 90 - -
- } + )}
-} + ); +}; -export default OrderHeader \ No newline at end of file +export default OrderHeader; \ No newline at end of file diff --git a/src/components/orders/order-item.tsx b/src/components/orders/order-item.tsx index 2aecb68..6dd23b9 100644 --- a/src/components/orders/order-item.tsx +++ b/src/components/orders/order-item.tsx @@ -6,38 +6,48 @@ import React from 'react'; const OrderItem = () => { const router = useRouter(); - const goToOrderDetail = () => router.push(`/orders/uuid`) + const goToOrderDetail = () => router.push(`/orders/uuid`); + + const statusClasses: Record = { + 'ارسال شد': 'bg-teal-bg text-primary-action', + 'در حال آماده‌سازی': 'bg-[#E5F3FF] text-[#007BFF]', + 'در انتظار تأیید': 'bg-[#FFF4E5] text-[#E67E22]', + 'آماده تحویل حضوری': 'bg-[#EBE5FF] text-[#734DBF]', + 'لغو شد': 'bg-[#FCE8E8] text-error', + 'تحویل داده شد': 'bg-emerald-bg text-success', + }; const order = { id: 1, restaurant: 'فست‌فود برگر', description: 'ساندویچ + نوشیدنی', - status: 'در حال آماده‌سازی', - statusColor: 'bg-orange-100 text-orange-700', + status: 'آماده تحویل حضوری', time: 'امروز، 11:30', itemsCount: 3, totalPrice: 45000, - images: Array.from({ length: 25 }, (_, i) => ({ + images: Array.from({ length: 5 }, (_, i) => ({ id: i, - src: `https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQqIof_DOo6I5-oOLJ1V9_HPfSudXfhewy_5C5Ry7YOO-UXSZ1jvK7-0hw&s=10`, // عکس رندوم + src: `https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQqIof_DOo6I5-oOLJ1V9_HPfSudXfhewy_5C5Ry7YOO-UXSZ1jvK7-0hw&s=10`, alt: `product-${i}`, })), }; return ( -
+
-
+
{order.restaurant.charAt(0)}

{order.restaurant}

-

{order.description}

+

{order.description}

+ {order.status} @@ -62,17 +72,19 @@ const OrderItem = () => {
-
+
{order.time}
-
- {order.itemsCount} کالا • {order.totalPrice.toLocaleString('fa-IR')} تومان +
+ + {order.itemsCount} کالا • {order.totalPrice.toLocaleString('fa-IR')} تومان +
+
+ +
+
+
+
+ ) +} + +export default OrderPaymentSticky \ No newline at end of file diff --git a/src/components/orders/order-server-error.tsx b/src/components/orders/order-server-error.tsx index afde5c6..d9764ba 100644 --- a/src/components/orders/order-server-error.tsx +++ b/src/components/orders/order-server-error.tsx @@ -3,14 +3,19 @@ import React from 'react' const OrderServerError = () => { return ( -
-
-
- +
+
+
+ {/* */} + وینسو
-

خطا در برقراری ارتباط

-

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

- +

خطا در برقراری ارتباط

+

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

+
) diff --git a/src/components/orders/order-stepper-status.tsx b/src/components/orders/order-stepper-status.tsx index 8d0cba9..e21217e 100644 --- a/src/components/orders/order-stepper-status.tsx +++ b/src/components/orders/order-stepper-status.tsx @@ -34,15 +34,13 @@ const OrderStepperStatus = ({ return (
- {/* ردیف دایره‌ها و خطوط — خط دقیقاً به لبه دایره می‌چسبد */}
{computedSteps.map((step, index) => { const isLast = index === computedSteps.length - 1 const isCompleted = step.status === 'completed' const isCurrent = step.status === 'current' - const isUpcoming = step.status === 'upcoming' - const circleBg = isUpcoming ? 'bg-gray-300' : 'bg-primary-action' + const circleBg = step.status === 'upcoming' ? 'bg-gray-300' : 'bg-primary-action' const nextLineBg = index < currentStep ? 'bg-primary-action' : 'bg-gray-300' @@ -55,10 +53,10 @@ const OrderStepperStatus = ({ `} > {isCompleted && ( - + )} {isCurrent && ( -
+
)}
@@ -70,14 +68,13 @@ const OrderStepperStatus = ({ })}
- {/* ردیف لیبل‌ها — دقیقاً زیر هر دایره */}
{computedSteps.map((step, index) => { const isLast = index === computedSteps.length - 1 - const isUpcoming = step.status === 'upcoming' - const textColor = isUpcoming - ? 'text-gray-500' - : 'text-primary-action' + const textColor = + step.status === 'upcoming' + ? 'text-gray-500' + : 'text-primary-action' return ( diff --git a/src/components/orders/order-time-address-info-alert.tsx b/src/components/orders/order-time-address-info-alert.tsx new file mode 100644 index 0000000..a005d76 --- /dev/null +++ b/src/components/orders/order-time-address-info-alert.tsx @@ -0,0 +1,23 @@ +import { ClockIcon, MapPinIcon } from 'lucide-react' +import React from 'react' + +const OrderTimeAddressInfoAlert = () => { + return ( +
+
+ +

+ زمان تخمینی تحویل: ۳۰–۴۵ دقیقه دیگر +

+
+
+ +

+ نارمک، خیابان شهید دستغیب، پلاک ۱۲، واحد ۳ +

+
+
+ ) +} + +export default OrderTimeAddressInfoAlert \ No newline at end of file diff --git a/src/components/orders/orders-skeleton.tsx b/src/components/orders/orders-skeleton.tsx index ebf3b7f..233ec2e 100644 --- a/src/components/orders/orders-skeleton.tsx +++ b/src/components/orders/orders-skeleton.tsx @@ -1,47 +1,47 @@ import React from 'react'; const OrdersSkeleton = () => { - return ( -
- {Array.from({ length: 10 }).map((_, index) => ( + return ( +
+ {Array.from({ length: 10 }).map((_, index) => ( +
+
+
+
+
+
+
+
+
+
+
+ +
+ +
+
+ {Array.from({ length: 3 }).map((_, imgIndex) => (
-
-
-
-
-
-
-
-
-
-
+ key={imgIndex} + className="size-10 flex-shrink-0 rounded-lg bg-gray-200" + /> + ))} +
-
+
+
+
+
+
-
-
- {Array.from({ length: 3 }).map((_, imgIndex) => ( -
- ))} -
- -
-
-
-
-
- -
-
- ))} +
- ); + ))} +
+ ); }; export default OrdersSkeleton; \ No newline at end of file