File size: 7,337 Bytes
94c9882
 
 
 
 
bea55e2
94c9882
 
 
bea55e2
94c9882
bea55e2
94c9882
bea55e2
94c9882
bea55e2
94c9882
 
bea55e2
94c9882
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bea55e2
94c9882
 
 
 
 
bea55e2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94c9882
 
 
 
 
bea55e2
 
 
 
 
 
 
 
94c9882
bea55e2
94c9882
 
 
bea55e2
94c9882
 
 
bea55e2
94c9882
 
bea55e2
94c9882
bea55e2
 
94c9882
 
 
bea55e2
 
94c9882
 
 
bea55e2
94c9882
 
 
bea55e2
94c9882
 
 
bea55e2
94c9882
 
 
 
 
bea55e2
94c9882
 
 
 
bea55e2
94c9882
 
 
 
bea55e2
94c9882
 
bea55e2
94c9882
 
 
 
 
 
 
 
 
 
 
bea55e2
 
94c9882
 
 
 
 
 
 
 
 
 
 
bea55e2
94c9882
bea55e2
94c9882
 
 
 
bea55e2
94c9882
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
'use client';

import { useEffect, useState } from 'react';
import { api, formatPrice, timeAgo } from '@/lib/api';
import { useAuth } from '@/components/auth-provider';
import { Package, ChevronRight, ChevronLeft, Store } from 'lucide-react';
import Link from 'next/link';
import { useRouter } from 'next/navigation';
import { EmptyState } from '@/components/product-card';
import { PageSkeleton } from '@/components/page-skeleton';

const STATUS_STYLES: Record<string, string> = {
  pending: 'bg-amber-100 text-amber-700',
  confirmed: 'bg-white/5 text-slate-300',
  paid: 'bg-green-100 text-green-700',
  shipped: 'bg-white/5 text-slate-300',
  delivered: 'bg-green-100 text-green-700',
  cancelled: 'bg-red-100 text-red-700',
  pending_payment_sent: 'bg-white/5 text-slate-300',
};

export default function OrdersPage() {
  const { user, loading: authLoading } = useAuth();
  const router = useRouter();
  const [orders, setOrders] = useState<any[]>([]);
  const [loading, setLoading] = useState(true);
  const [expanded, setExpanded] = useState<string | null>(null);

  useEffect(() => {
    if (!authLoading && !user) {
      router.push('/login?next=/orders');
      return;
    }
    if (user) {
      (async () => {
        const result = await api.orders.list();
        if (result.success) setOrders(result.orders || []);
        setLoading(false);
      })();
    }
  }, [user, authLoading, router]);

  if (authLoading || loading) {
    return (
      <PageSkeleton variant="orders" />
    );
  }

  if (orders.length === 0) {
    return (
      <div className="ig-container min-h-screen ig-topbar-offset">
        <div className="fx-topbar ig-topbar">
          <button onClick={() => router.back()} className="ig-icon-btn" aria-label="Back">
            <ChevronLeft className="w-6 h-6" />
          </button>
          <h1 className="text-base font-semibold flex-1 ml-2">My Orders</h1>
        </div>
        <div className="px-4 py-10">
          <EmptyState
            icon={<Package className="w-8 h-8" />}
            title="No orders yet"
            message="When you place your first order, it will appear here."
            action={
              <Link href="/categories">
                <button className="bg-indigo-600 text-white font-semibold rounded-md px-4 py-2.5 hover:bg-white/10">
                  Start shopping
                </button>
              </Link>
            }
          />
        </div>
      </div>
    );
  }

  return (
    <div className="ig-container min-h-screen">
      {/* Top bar */}
      <div className="fx-topbar ig-topbar">
        <button onClick={() => router.back()} className="ig-icon-btn" aria-label="Back">
          <ChevronLeft className="w-6 h-6" />
        </button>
        <h1 className="text-base font-semibold flex-1 ml-2">My Orders</h1>
      </div>

      <div className="divide-y divide-white/5">
        {orders.map((order) => {
          const isExpanded = expanded === order.id;
          const status = (order.status || 'pending').toLowerCase();
          const statusStyle = STATUS_STYLES[status] || 'bg-white/5 text-slate-300';
          const isPendingPayment = status === 'pending' || status === 'pending_payment_sent' || status === 'confirmed';

          return (
            <div key={order.id}>
              <button
                onClick={() => setExpanded(isExpanded ? null : order.id)}
                className="w-full p-4 text-left flex items-center gap-3 hover:bg-white/5"
              >
                <div className="w-10 h-10 rounded-md bg-white/5 flex items-center justify-center shrink-0">
                  <Package className="w-5 h-5 text-slate-400" />
                </div>
                <div className="flex-1 min-w-0">
                  <div className="flex items-center gap-2 flex-wrap">
                    <span className="font-semibold text-sm">#{order.id?.slice(0, 8)}</span>
                    <span className={`text-[10px] px-2 py-0.5 rounded-full font-bold uppercase ${statusStyle}`}>
                      {status.replace(/_/g, ' ')}
                    </span>
                  </div>
                  <div className="text-xs text-slate-400 mt-0.5">
                    {order.item_count || 0} item(s) · {formatPrice(order.total)} · {timeAgo(order.created_at)}
                  </div>
                </div>
                <ChevronRight className={`w-4 h-4 text-slate-600 transition-transform ${isExpanded ? 'rotate-90' : ''}`} />
              </button>

              {isExpanded && (
                <div className="px-4 pb-4 space-y-3">
                  {/* Items */}
                  {order.items && order.items.length > 0 && (
                    <div className="space-y-2">
                      {order.items.map((item: any, i: number) => (
                        <div key={i} className="flex gap-3 items-center">
                          <div className="w-12 h-12 rounded-md bg-white/5 overflow-hidden shrink-0">
                            {item.products?.image_url ? (
                              <img src={item.products.image_url} alt="" className="w-full h-full object-cover" />
                            ) : (
                              <div className="w-full h-full flex items-center justify-center">
                                <Store className="w-4 h-4 text-slate-600" />
                              </div>
                            )}
                          </div>
                          <div className="flex-1 min-w-0">
                            <Link href={`/product?id=${item.product_id}`} className="text-sm font-medium hover:opacity-70 line-clamp-1">
                              {item.product_name || item.products?.name}
                            </Link>
                            <div className="text-xs text-slate-400">
                              Qty {item.quantity} × {formatPrice(item.price)}
                            </div>
                          </div>
                          <div className="text-sm font-bold">{formatPrice(item.price * item.quantity)}</div>
                        </div>
                      ))}
                    </div>
                  )}

                  {/* Shipping */}
                  {order.shipping_address && (
                    <div className="bg-white/5 rounded-md p-3 text-xs text-slate-300">
                      <div className="font-semibold mb-1">Shipping to:</div>
                      <div>
                        {typeof order.shipping_address === 'string'
                          ? order.shipping_address
                          : `${order.shipping_address.full_name || ''} ${order.shipping_address.address || ''} ${order.shipping_address.city || ''} ${order.shipping_address.state || ''}`.trim()}
                      </div>
                    </div>
                  )}

                  {/* Action */}
                  {isPendingPayment && (
                    <Link href={`/payment?order=${order.id}`}>
                      <button className="w-full bg-indigo-600 text-white font-semibold rounded-md py-2.5 hover:bg-white/10">
                        Complete payment
                      </button>
                    </Link>
                  )}
                </div>
              )}
            </div>
          );
        })}
      </div>
    </div>
  );
}