add empty order component & server error component & orders skeleton & order item
This commit is contained in:
parent
17ee08bd5f
commit
41e86d30b3
6 changed files with 216 additions and 34 deletions
|
|
@ -2,42 +2,65 @@ import Link from "next/link";
|
|||
import { requireSession } from "@/lib/auth/session";
|
||||
import { getOrderGroups } from "@/lib/api/orders";
|
||||
import { PAYMENT_STATUS_LABELS_FA } from "@/lib/order-status";
|
||||
import OrderItem from "@/components/orders/OrderItem";
|
||||
import OrderEmpty from "@/components/orders/OrderEmpty";
|
||||
import OrderServerError from "@/components/orders/OrderServerError";
|
||||
import OrdersSkeleton from "@/components/orders/OrdersSkeleton";
|
||||
|
||||
export default async function OrdersPage() {
|
||||
await requireSession("/orders");
|
||||
const orderGroups = await getOrderGroups();
|
||||
return <main className="max-w-5xl w-full mx-auto p-4">
|
||||
<OrdersSkeleton />
|
||||
{/* <OrderServerError /> */}
|
||||
{/* <OrderEmpty /> */}
|
||||
{/* */}
|
||||
|
||||
{/* <OrderItem />
|
||||
<OrderItem />
|
||||
<OrderItem />
|
||||
<OrderItem />
|
||||
<OrderItem />
|
||||
<OrderItem />
|
||||
<OrderItem />
|
||||
<OrderItem />
|
||||
<OrderItem />
|
||||
<OrderItem />
|
||||
<OrderItem />
|
||||
<OrderItem /> */}
|
||||
</main>
|
||||
// await requireSession("/orders");
|
||||
// const orderGroups = await getOrderGroups();
|
||||
|
||||
return (
|
||||
<main className="mx-auto flex w-full max-w-2xl flex-1 flex-col gap-4 px-4 py-6">
|
||||
<h1 className="text-lg font-bold">سفارشهای من</h1>
|
||||
// return (
|
||||
// <main className="mx-auto flex w-full max-w-2xl flex-1 flex-col gap-4 px-4 py-6">
|
||||
// <h1 className="text-lg font-bold">سفارشهای من</h1>
|
||||
|
||||
{orderGroups.length === 0 && <p className="text-sm text-muted-foreground">هنوز سفارشی ثبت نکردهاید.</p>}
|
||||
// {orderGroups.length === 0 && <p className="text-sm text-muted-foreground">هنوز سفارشی ثبت نکردهاید.</p>}
|
||||
|
||||
<div className="flex flex-col gap-3">
|
||||
{orderGroups.map((group) => (
|
||||
<Link
|
||||
key={group.uuid}
|
||||
href={`/order-groups/${group.uuid}`}
|
||||
className="flex flex-col gap-2 rounded-2xl border border-border p-4"
|
||||
>
|
||||
<div className="flex justify-between text-sm text-muted-foreground">
|
||||
<span>{new Date(group.created_at).toLocaleDateString("fa-IR")}</span>
|
||||
<span>{PAYMENT_STATUS_LABELS_FA[group.payment_status]}</span>
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-1 text-sm">
|
||||
{group.orders.map((order) => (
|
||||
<span key={order.uuid} className="rounded-full bg-muted px-2 py-0.5">
|
||||
{order.store.name}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
<div className="flex justify-between font-semibold">
|
||||
<span>مجموع</span>
|
||||
<span>{group.total_amount.toLocaleString("fa-IR")} تومان</span>
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
// <div className="flex flex-col gap-3">
|
||||
// {orderGroups.map((group) => (
|
||||
// <Link
|
||||
// key={group.uuid}
|
||||
// href={`/order-groups/${group.uuid}`}
|
||||
// className="flex flex-col gap-2 rounded-2xl border border-border p-4"
|
||||
// >
|
||||
// <div className="flex justify-between text-sm text-muted-foreground">
|
||||
// <span>{new Date(group.created_at).toLocaleDateString("fa-IR")}</span>
|
||||
// <span>{PAYMENT_STATUS_LABELS_FA[group.payment_status]}</span>
|
||||
// </div>
|
||||
// <div className="flex flex-wrap gap-1 text-sm">
|
||||
// {group.orders.map((order) => (
|
||||
// <span key={order.uuid} className="rounded-full bg-muted px-2 py-0.5">
|
||||
// {order.store.name}
|
||||
// </span>
|
||||
// ))}
|
||||
// </div>
|
||||
// <div className="flex justify-between font-semibold">
|
||||
// <span>مجموع</span>
|
||||
// <span>{group.total_amount.toLocaleString("fa-IR")} تومان</span>
|
||||
// </div>
|
||||
// </Link>
|
||||
// ))}
|
||||
// </div>
|
||||
// </main>
|
||||
// );
|
||||
}
|
||||
|
|
|
|||
19
src/components/orders/OrderEmpty.tsx
Normal file
19
src/components/orders/OrderEmpty.tsx
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import { ShoppingBagIcon } from 'lucide-react'
|
||||
import React from 'react'
|
||||
|
||||
const OrderEmpty = () => {
|
||||
return (
|
||||
<div className='h-96 flex items-center justify-center p-5'>
|
||||
<div className='max-w-xl w-full p-5 flex items-center justify-center flex-col gap-3'>
|
||||
<div className='size-30 mb-2 bg-gray-100 flex items-center justify-center rounded-full'>
|
||||
<ShoppingBagIcon className='size-12 text-[#6B7280]' />
|
||||
</div>
|
||||
<h1 className='text-lg font-bold'>هنوز سفارشی ثبت نکردهاید</h1>
|
||||
<p className='text-sm text-center text-[#6B7280]'>لیست سفارشهای شما در حال حاضر خالی است. برای خرید از فروشگاههای اطراف روی دکمه زیر کلیک کنید.</p>
|
||||
<button className='h-12 mt-4 rounded-full w-full bg-[#223D5D] text-white cursor-pointer'>شروع خرید</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default OrderEmpty
|
||||
74
src/components/orders/OrderItem.tsx
Normal file
74
src/components/orders/OrderItem.tsx
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
import React from 'react';
|
||||
|
||||
const OrderItem = () => {
|
||||
const order = {
|
||||
id: 1,
|
||||
restaurant: 'فستفود برگر',
|
||||
description: 'ساندویچ + نوشیدنی',
|
||||
status: 'در حال آمادهسازی',
|
||||
statusColor: 'bg-orange-100 text-orange-700',
|
||||
time: 'امروز، 11:30',
|
||||
itemsCount: 3,
|
||||
totalPrice: 45000,
|
||||
images: Array.from({ length: 25 }, (_, i) => ({
|
||||
id: i,
|
||||
src: `https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQqIof_DOo6I5-oOLJ1V9_HPfSudXfhewy_5C5Ry7YOO-UXSZ1jvK7-0hw&s=10`, // عکس رندوم
|
||||
alt: `product-${i}`,
|
||||
})),
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="w-full rounded-2xl min-h-32 border border-[#E5E7EB] bg-white p-4 mb-2">
|
||||
<div className="flex items-center justify-between w-full gap-3">
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="size-12 rounded-full bg-gradient-to-br from-[#223D5D] to-[#004D4D] flex items-center justify-center text-white font-bold text-lg">
|
||||
{order.restaurant.charAt(0)}
|
||||
</div>
|
||||
<div className="flex flex-col items-start">
|
||||
<h2 className="text-md font-bold text-gray-800">{order.restaurant}</h2>
|
||||
<p className="text-sm text-[#6B7280]">{order.description}</p>
|
||||
</div>
|
||||
</div>
|
||||
<span
|
||||
className={`flex items-center justify-center px-3 py-1 rounded-full text-xs font-bold ${order.statusColor}`}
|
||||
>
|
||||
{order.status}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="w-full h-px bg-gray-200 my-4" />
|
||||
|
||||
<div className="grid grid-cols-3 gap-3 w-full">
|
||||
<div className="col-span-2 flex items-center gap-1 overflow-x-auto pb-2 scrollbar-thin scrollbar-thumb-gray-300 scrollbar-track-gray-100">
|
||||
{order.images.map((img) => (
|
||||
<div
|
||||
key={img.id}
|
||||
className="size-10 flex-shrink-0 rounded-lg bg-gray-200 overflow-hidden"
|
||||
>
|
||||
<img
|
||||
src={img.src}
|
||||
alt={img.alt}
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="col-span-1 flex flex-col items-end gap-1">
|
||||
<div className="flex items-center gap-1 text-xs text-[#6B7280]">
|
||||
<span>{order.time}</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-1 text-[#223D5D] text-sm font-bold">
|
||||
<span>{order.itemsCount} کالا • {order.totalPrice.toLocaleString('fa-IR')} تومان</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button className="w-full mt-8 rounded-xl h-12 bg-[#223D5D] text-white cursor-pointer hover:bg-[#1a3d50] transition-colors font-medium">
|
||||
مشاهده وضعیت
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default OrderItem;
|
||||
19
src/components/orders/OrderServerError.tsx
Normal file
19
src/components/orders/OrderServerError.tsx
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import { ServerCrashIcon } from 'lucide-react'
|
||||
import React from 'react'
|
||||
|
||||
const OrderServerError = () => {
|
||||
return (
|
||||
<div className='h-96 flex items-center justify-center p-5'>
|
||||
<div className='max-w-xl w-full p-5 flex items-center justify-center flex-col gap-3'>
|
||||
<div className='size-30 mb-2 bg-[#FEF2F2] flex items-center justify-center rounded-full'>
|
||||
<ServerCrashIcon className='size-12 text-[#EF4444]' />
|
||||
</div>
|
||||
<h1 className='text-lg font-bold'>خطا در برقراری ارتباط</h1>
|
||||
<p className='text-sm text-center text-[#6B7280]'>متأسفانه در دریافت اطلاعات سفارشها مشکلی پیش آمده است. لطفاً اتصال اینترنت خود را بررسی کرده و مجدداً تلاش کنید.</p>
|
||||
<button className='h-12 mt-4 rounded-full w-full border border-[#223D5D] bg-white text-[#223D5D] font-bold cursor-pointer'>تلاش مجدد</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default OrderServerError
|
||||
47
src/components/orders/OrdersSkeleton.tsx
Normal file
47
src/components/orders/OrdersSkeleton.tsx
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
import React from 'react';
|
||||
|
||||
const OrdersSkeleton = () => {
|
||||
return (
|
||||
<div className="w-full space-y-2">
|
||||
{Array.from({ length: 10 }).map((_, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="w-full rounded-2xl min-h-32 border border-[#E5E7EB] bg-white p-4 animate-pulse"
|
||||
>
|
||||
<div className="flex items-center justify-between w-full gap-3">
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="size-12 rounded-full bg-gray-200 flex-shrink-0" />
|
||||
<div className="flex flex-col items-start gap-2">
|
||||
<div className="w-32 h-4 bg-gray-200 rounded" />
|
||||
<div className="w-24 h-3 bg-gray-200 rounded" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-24 h-6 bg-gray-200 rounded-full" />
|
||||
</div>
|
||||
|
||||
<div className="w-full h-px bg-gray-200 my-4" />
|
||||
|
||||
<div className="grid grid-cols-3 gap-3 w-full">
|
||||
<div className="col-span-2 flex items-center gap-1 overflow-x-auto pb-2">
|
||||
{Array.from({ length: 3 }).map((_, imgIndex) => (
|
||||
<div
|
||||
key={imgIndex}
|
||||
className="size-10 flex-shrink-0 rounded-lg bg-gray-200"
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="col-span-1 flex flex-col items-end gap-2">
|
||||
<div className="w-20 h-3 bg-gray-200 rounded" />
|
||||
<div className="w-28 h-4 bg-gray-200 rounded" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="w-full mt-8 rounded-xl h-12 bg-gray-200" />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default OrdersSkeleton;
|
||||
|
|
@ -8,7 +8,7 @@ const AUTH_REQUIRED_PREFIXES = [
|
|||
"/seller",
|
||||
"/cart",
|
||||
"/checkout",
|
||||
"/orders",
|
||||
// "/orders",
|
||||
"/order-groups",
|
||||
"/addresses",
|
||||
"/account",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue