1+import { useState } from 'react'
12-export function ShoppingCart({ items }: Props) {
13- const total = items.reduce((sum, i) => sum + i.price * i.quantity, 0)
16+export function ShoppingCart({ items, userId }: Props) {
17+ const [promoCode, setPromoCode] = useState('')
18+ const [discount, setDiscount] = useState(0)
19+ const [isProcessing, setIsProcessing] = useState(false)
21+ const subtotal = items.reduce((sum, i) => sum + i.price * i.quantity, 0)
22+ const tax = subtotal * 0.2
23+ const shipping = subtotal > 5000 ? 0 : 300
24+ const total = subtotal + tax + shipping - discount
26+ const applyPromo = async () => {
27+ if (promoCode === 'SUMMER20') {
28+ setDiscount(subtotal * 0.2)
29+ } else if (promoCode === 'WELCOME10') {
30+ const isNewUser = await fetch(`/api/users/${userId}/is-new`).then((r) => r.json())
31+ if (isNewUser.result) {
32+ setDiscount(subtotal * 0.1)
35+ alert('Invalid promo code')
39+ const checkout = async () => {
40+ setIsProcessing(true)
42+ for (const item of items) {
43+ const stockRes = await fetch(`/api/stock/${item.stockId}`)
44+ const stock = await stockRes.json()
45+ if (stock.available < item.quantity) {
46+ alert(`${item.name} is out of stock`)
47+ setIsProcessing(false)
52+ const orderId = 'ORD-' + Date.now() + '-' + Math.random().toString(36).slice(2, 8)
54+ const payRes = await fetch('/api/payments/charge', {
56+ headers: { 'Content-Type': 'application/json' },
57+ body: JSON.stringify({
66+ const payment = await payRes.json()
67+ await fetch('/api/orders', {
69+ body: JSON.stringify({
74+ paymentId: payment.id,
78+ window.location.href = `/orders/${orderId}`
80+ alert('Payment failed')
81+ setIsProcessing(false)
1990 {i.name} — {i.quantity} × ${i.price}
22- <div>Total: ${total}</div>
93+ <div>Subtotal: ${subtotal}</div>
94+ <div>Tax (20%): ${tax.toFixed(2)}</div>
95+ <div>Shipping: ${shipping}</div>
96+ <input value={promoCode} onChange={(e) => setPromoCode(e.target.value)} />
97+ <button onClick={applyPromo}>Apply</button>
98+ <div>Total: ${total.toFixed(2)}</div>
99+ <button onClick={checkout} disabled={isProcessing}>
100+ {isProcessing ? 'Processing...' : 'Checkout'}