/* ============================================================ Store screens — Part 2: Cart, Checkout, Confirmation, Account ============================================================ */ /* ---------------- CART ---------------- */ function CartScreen() { const { cart, navigate, updateQty, removeItem, user } = useContext(AppCtx); const subtotal = cart.reduce((n, i) => n + i.product.price * i.qty, 0); const remaining = user.pointsTotal - user.pointsUsed; const over = Math.max(0, subtotal - remaining); if (cart.length === 0) { return (

Your cart is empty

Browse the catalog and add some gear to get started.

); } return (

Your cart

{cart.reduce((n, i) => n + i.qty, 0)} items

{cart.map((item, idx) => ( ))}
navigate('checkout')} onBack={() => navigate('home')} />
); } function CartRow({ item, last, updateQty, removeItem }) { const { navigate } = useContext(AppCtx); const p = item.product; return (
navigate('product', { id: p.id, color: item.color })}>
{p.brand} · {p.sku}
navigate('product', { id: p.id, color: item.color })}>{p.name}
{item.color} Size {item.size}
{item.qty}
{p.price * item.qty} pts
${p.price * item.qty}
); } /* ---------------- ORDER SUMMARY (shared) ---------------- */ function OrderSummary({ subtotal, remaining, over, cta, onCta, onBack, ctaDisabled }) { const after = remaining - subtotal; return (

Order summary

{over > 0 ? ( <>
Balance after –{Math.abs(after)} pts
This order exceeds your allowance by {over} pts (${over}). It can still go through — the overage is logged and your HR admin is notified for billing.
) : (
Balance after {after} pts
)} {onBack && }
Internal order · no card required
); } function SummaryLine({ label, value, sub }) { return (
{label} {value}
); } /* ---------------- CHECKOUT ---------------- */ function CheckoutScreen() { const { cart, navigate, user, placeOrder } = useContext(AppCtx); const subtotal = cart.reduce((n, i) => n + i.product.price * i.qty, 0); const remaining = user.pointsTotal - user.pointsUsed; const over = Math.max(0, subtotal - remaining); const [method, setMethod] = useState('inperson'); const [loc, setLoc] = useState('hq'); const [ack, setAck] = useState(false); const canPlace = method === 'inperson' || (method === 'ship' && loc); return (
navigate('cart')}> Back to cart

Checkout

{/* Delivery method */}

How should we get this to you?

setMethod('inperson')} title="In-person delivery" desc="We hand-deliver your order to your job site or office. Most orders arrive within a week." badge="Recommended" /> setMethod('ship')} title="Ship to a company location" desc="Pick up at one of our three locations." /> {method === 'ship' && (
{LOCATIONS.map(l => ( ))}
)}
{/* Recipient */}

Recipient

{/* Overage acknowledgement */} {over > 0 && (

This order exceeds your allowance

You're {over} points (${over}) over your remaining balance. Your order will still be placed — the overage is recorded and your HR administrator will reach out about the ${over} balance.

)}
0 && !ack)} onCta={() => placeOrder({ method, loc, subtotal, over })} />
); } function StepDot({ n }) { return {n}; } function RadioCard({ icon, title, desc, badge, selected, onClick }) { return ( ); } function ReadField({ label, value }) { return (
{label}
{value}
); } /* ---------------- CONFIRMATION ---------------- */ function ConfirmationScreen({ order }) { const { navigate } = useContext(AppCtx); const loc = LOCATIONS.find(l => l.id === order.loc); return (

Order placed

Thanks! Your order {order.id} is confirmed. A copy was emailed to you.

1 ? 's' : ''} · ${order.subtotal} pts`} />
{order.over > 0 && (
Overage of ${order.over} logged. Your HR administrator has been notified and will follow up about billing.
)}
{order.method === 'inperson' ? 'We\'ll coordinate hand-delivery to your job site. Watch your email for scheduling.' : `Your order will be ready for pickup at ${loc.name} — ${loc.addr}.`}
); } /* ---------------- MY ACCOUNT ---------------- */ function AccountScreen() { const { user, navigate } = useContext(AppCtx); const remaining = user.pointsTotal - user.pointsUsed; const pct = (remaining / user.pointsTotal) * 100; const R = 64, C = 2 * Math.PI * R; return (

My account

{user.name} · {user.email}

{/* Points ring card */}
Clothing allowance
{remaining}
of {user.pointsTotal} pts left
Spent this year{user.pointsUsed} pts
Resets on{user.resetDate}
{/* Right column */}

Order history

{ORDER_HISTORY.length} orders
{ORDER_HISTORY.map(o => ( ))}
OrderDateItemsPointsStatus
{o.id} {o.date} {o.items} {o.points} pts {o.status}

Profile

Need to update your details or points balance? Contact your HR administrator.

); } Object.assign(window, { CartScreen, CartRow, OrderSummary, SummaryLine, CheckoutScreen, StepDot, RadioCard, ReadField, ConfirmationScreen, AccountScreen });