"use client"; import { useEffect, useState } from "react"; import Image from "next/image"; import { HiOutlineChevronDoubleLeft, HiOutlineChevronLeft, HiOutlineChevronRight, HiOutlineChevronDoubleRight, } from "react-icons/hi2"; import { IconButton } from "@/components/IconButton"; import { formatDisplayName } from "@/lib/variants"; const PAGE_SIZE = 5; type OrderItem = { id: string; title: string; product_title: string; variant_title: string; variant_sku?: string; variant?: { sku?: string }; quantity: number; unit_price: number; total: number; subtotal?: number; tax_total?: number; thumbnail: string | null; }; type Order = { id: string; display_id: number; created_at: string; total: number; subtotal?: number; shipping_total?: number; tax_total?: number; currency_code: string; items: OrderItem[]; }; function formatPrice(amount: number, currencyCode: string) { return new Intl.NumberFormat("en-US", { style: "currency", currency: currencyCode, minimumFractionDigits: 2, }).format(amount); } function variantLabel(item: OrderItem): string { const sku = item.variant_sku ?? item.variant?.sku; if (sku) { const friendly = formatDisplayName(sku); if (friendly) return friendly; } return item.variant_title || item.title; } export function OrdersTab() { const [orders, setOrders] = useState([]); const [loading, setLoading] = useState(true); const [page, setPage] = useState(1); useEffect(() => { async function fetchOrders() { try { const res = await fetch("/api/account/orders"); if (res.ok) { const data = await res.json(); // Sort newest first (fallback in case API doesn't sort) const sorted = [...(data.orders ?? [])].sort( (a: Order, b: Order) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime(), ); setOrders(sorted); } } catch { // Silently fail — empty state will show } finally { setLoading(false); } } fetchOrders(); }, []); if (loading) { return (

Loading orders…

); } if (orders.length === 0) { return (

You haven't placed any orders yet.

); } const totalPages = Math.max(1, Math.ceil(orders.length / PAGE_SIZE)); const safePage = Math.min(page, totalPages); const start = (safePage - 1) * PAGE_SIZE; const paginatedOrders = orders.slice(start, start + PAGE_SIZE); return (

{orders.length} order{orders.length !== 1 ? "s" : ""}

{paginatedOrders.map((order) => { const currency = order.currency_code ?? "eur"; const subtotal = order.subtotal ?? order.items?.reduce((sum, i) => sum + (i.subtotal ?? 0), 0) ?? 0; const taxTotal = order.tax_total ?? order.items?.reduce((sum, i) => sum + (i.tax_total ?? 0), 0) ?? 0; const shippingTotal = order.shipping_total ?? Math.max(0, order.total - subtotal - taxTotal); return (
{/* Order header */}
Order #{order.display_id} {new Date(order.created_at).toLocaleDateString("en-GB", { day: "numeric", month: "short", year: "numeric", })}
{/* Item cards */} {order.items?.length > 0 && (
{order.items.map((item) => (
{/* Thumbnail */}
{item.thumbnail ? ( {item.product_title ) : (
No img
)}
{/* Info */}

{item.product_title ?? item.title}

{variantLabel(item)} {item.quantity >= 2 && ( x {item.quantity} )}

))}
{/* Price breakdown */}
Subtotal {formatPrice(subtotal, currency)}
{shippingTotal > 0 && (
Shipping {formatPrice(shippingTotal, currency)}
)} {taxTotal > 0 && (
Tax {formatPrice(taxTotal, currency)}
)} {taxTotal > 0 && (
Total {formatPrice(order.total, currency)}
)}
)}
); })}
{totalPages > 1 && ( )}
); } // ── Pagination ────────────────────────────────────────────────────── function Pagination({ page, totalPages, onPageChange, }: { page: number; totalPages: number; onPageChange: (p: number) => void; }) { const hasPrev = page > 1; const hasNext = page < totalPages; return ( ); }