feat: paginate customer orders and polish the dashboard hero
Add paged orders API and infinite scroll, short order numbers, and align the guest invite card with the logged-in hero shell. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -7,7 +7,10 @@ export function useCachedReads() {
|
||||
const cache = useQueryCache()
|
||||
return {
|
||||
me: (o?: FetchOptions) => cache.fetch(KEYS.profile, api.getMe, o),
|
||||
myOrders: (o?: FetchOptions) => cache.fetch(KEYS.orders, api.getMyOrders, o),
|
||||
// Orders are paged (infinite scroll). The list screen calls api.getMyOrders
|
||||
// directly; this helper only covers a rare full-first-page peek/invalidate.
|
||||
myOrders: (o?: FetchOptions) =>
|
||||
cache.fetch(KEYS.orders, () => api.getMyOrders({ page: 1 }).then((p) => p.result), o),
|
||||
accountingBalance: (o?: FetchOptions) => cache.fetch(KEYS.balance, api.getAccountingBalance, o),
|
||||
myLedgerEntries: (o?: FetchOptions) => cache.fetch(KEYS.ledger, api.getMyLedgerEntries, o),
|
||||
goldPrice: (o?: FetchOptions) => cache.fetch(KEYS.goldPrice, () => api.getLatestGoldPrice(), o),
|
||||
|
||||
@@ -241,6 +241,14 @@ export interface OrderItemDetail {
|
||||
} | null;
|
||||
}
|
||||
|
||||
export interface OrderStatusEvent {
|
||||
id: string;
|
||||
fromStatus: string | null;
|
||||
toStatus: string;
|
||||
note: string | null;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
export interface OrderDetail {
|
||||
id: string;
|
||||
orderNumber: string;
|
||||
@@ -252,6 +260,25 @@ export interface OrderDetail {
|
||||
deliveredAt: string | null;
|
||||
createdAt: string;
|
||||
items: OrderItemDetail[];
|
||||
/** Chronological status changes (oldest first). May be empty on older rows. */
|
||||
statusEvents?: OrderStatusEvent[];
|
||||
}
|
||||
|
||||
/** One page of GET /customer/me/orders — same envelope as the report endpoints. */
|
||||
export interface OrdersPage {
|
||||
result: OrderDetail[];
|
||||
count: number;
|
||||
page: number;
|
||||
limit: number;
|
||||
}
|
||||
|
||||
export interface OrdersQuery {
|
||||
page?: number;
|
||||
limit?: number;
|
||||
/** OrderStatus, or omit / ALL for every status. */
|
||||
status?: string;
|
||||
/** Substring of orderNumber. */
|
||||
q?: string;
|
||||
}
|
||||
|
||||
export interface CustomerDetail {
|
||||
@@ -525,7 +552,15 @@ export const api = {
|
||||
getMe: () => request<CustomerDetail>('/customer/me'),
|
||||
/** D27 §12 — this customer's balance, read from the accounting software on every call. */
|
||||
getAccountingBalance: () => request<AccountingBalance>('/customer/me/accounting-balance'),
|
||||
getMyOrders: () => request<OrderDetail[]>('/customer/me/orders'),
|
||||
getMyOrders: (query: OrdersQuery = {}) => {
|
||||
const params = new URLSearchParams();
|
||||
if (query.page) params.set('page', String(query.page));
|
||||
if (query.limit) params.set('limit', String(query.limit));
|
||||
if (query.status && query.status !== 'ALL') params.set('status', query.status);
|
||||
if (query.q?.trim()) params.set('q', query.q.trim());
|
||||
const qs = params.toString();
|
||||
return request<OrdersPage>(`/customer/me/orders${qs ? `?${qs}` : ''}`);
|
||||
},
|
||||
getMyLedgerEntries: () => request<LedgerEntrySummary[]>('/customer/me/ledger-entries'),
|
||||
/** The making charge the server will charge for these variants (MON-08). */
|
||||
getWageQuotes: (variantIds: string[]) =>
|
||||
|
||||
Reference in New Issue
Block a user