Show Order History on the Account Page
Adds an endpoint that returns a customer's recent orders with their items, a status column on orders, and the Order History list on the account page.
Mapi/routes/orders.ts1 of 3
Files Changed
api/routes/
db/migrations/
web/src/account/
api/routes/orders.ts
TypeScript · Click a line number to comment · Tap a line to comment@@ -7,8 +7,26 @@ export const router = Router();
router.get("/orders/:id", requireAuth, async (req, res) => {
const { rows } = await db.query(
"SELECT * FROM orders WHERE id = $1 AND user_id = $2",
[req.params.id, req.user.id],
);
if (rows.length === 0) return res.sendStatus(404);
res.json(rows[0]);
});
Added:
Added: router.get("/users/:userId/orders", requireAuth, async (req, res) => {
Added: const userId = req.params.userId;
Added: const limit = Number(req.query.limit ?? 20);
Added: const orders = await db.query(
Added: `SELECT id, total_cents, status, created_at FROM orders
Added: WHERE user_id = $1 ORDER BY created_at DESC LIMIT ${limit}`,
Added: [userId],
Added: );
Added: for (const order of orders.rows) {
Added: const items = await db.query(
Added: "SELECT sku, name, quantity FROM order_items WHERE order_id = $1",
Added: [order.id],
Added: );
Added: order.items = items.rows;
Added: }
Added: res.json(orders.rows);
Added: });
db/migrations/0042_add_order_status.sql
SQL · Click a line number to comment · Tap a line to comment@@ -0,0 +1,7 @@
Added: ALTER TABLE orders ADD COLUMN status text NOT NULL DEFAULT 'placed';
Added:
Added: UPDATE orders SET status = 'shipped' WHERE shipped_at IS NOT NULL;
Added: UPDATE orders SET status = 'cancelled' WHERE cancelled_at IS NOT NULL;
Added:
Added: CREATE INDEX orders_user_id_created_at_idx
Added: ON orders (user_id, created_at DESC);
web/src/account/OrderHistory.tsx
TypeScript · Click a line number to comment · Tap a line to comment@@ -0,0 +1,25 @@
Added: import { useEffect, useState } from "react";
Added: import { formatCents } from "../money";
Added: import type { Order } from "../types";
Added:
Added: export function OrderHistory({ userId }: { userId: string }) {
Added: const [orders, setOrders] = useState<Order[]>([]);
Added:
Added: useEffect(() => {
Added: fetch(`/api/users/${userId}/orders?limit=20`)
Added: .then((res) => res.json())
Added: .then(setOrders);
Added: }, [userId]);
Added:
Added: return (
Added: <ul className="order-history">
Added: {orders.map((order) => (
Added: <li>
Added: <span>{new Date(order.created_at).toLocaleDateString()}</span>
Added: <span>{order.status}</span>
Added: <span>{formatCents(order.total_cents)}</span>
Added: </li>
Added: ))}
Added: </ul>
Added: );
Added: }