templates2.Store.Next/app/admin/orders/page.tsx
w4c-templates bb75e7c742
Some checks are pending
CI / quality (push) Waiting to run
chore(template): publish Store.Next
2026-10-11 23:24:13 +03:00

75 lines
2.3 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use client';
import { useEffect, useState } from 'react';
type Order = {
id: string;
email: string;
status: string;
total: number;
createdAt: string;
items: { id: string; name: string; quantity: number }[];
};
const STATUSES = ['pending', 'paid', 'shipped', 'canceled'];
export default function AdminOrdersPage() {
const [orders, setOrders] = useState<Order[]>([]);
async function load() {
const res = await fetch('/api/admin/orders');
const data = (await res.json().catch(() => ({}))) as { orders?: Order[] };
setOrders(data.orders ?? []);
}
useEffect(() => {
void load();
}, []);
async function setStatus(id: string, status: string) {
await fetch(`/api/admin/orders/${id}`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ status }) });
await load();
}
return (
<div className="space-y-6">
<h1 className="text-2xl font-bold">Orders</h1>
{orders.length === 0 ? (
<p className="muted py-6 text-center text-sm">No orders yet.</p>
) : (
<div className="space-y-4">
{orders.map((o) => (
<div key={o.id} className="card">
<div className="flex flex-wrap items-center justify-between gap-3">
<div>
<p className="font-mono text-sm">{o.id.slice(0, 8)}</p>
<p className="muted text-xs">
{o.email} · {new Date(o.createdAt).toLocaleDateString('en-US')}
</p>
</div>
<div className="flex items-center gap-3">
<span className="font-bold">${(o.total / 100).toFixed(2)}</span>
<select className="input w-36" value={o.status} onChange={(e) => setStatus(o.id, e.target.value)} aria-label={`Status for order ${o.id}`}>
{STATUSES.map((s) => (
<option key={s} value={s}>
{s}
</option>
))}
</select>
</div>
</div>
<ul className="muted mt-3 space-y-1 text-sm">
{o.items.map((i) => (
<li key={i.id}>
{i.quantity}× {i.name}
</li>
))}
</ul>
</div>
))}
</div>
)}
</div>
);
}