diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 37163e1..5cbe86c 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -87,7 +87,8 @@ "Bash(git commit -m 'Refactor: Move start design server action to separate file *)", "Bash(git commit -m 'Add: Prominent '\\\\''Shop plain items'\\\\'' section to homepage *)", "Bash(git commit -m 'Feature: Royal Mail shipping integration with weight-based postage *)", - "Bash(git commit -m 'Add: Weight field to product admin pages *)" + "Bash(git commit -m 'Add: Weight field to product admin pages *)", + "Bash(git commit -m 'Add: Shipping selector component and checkout integration *)" ] } } diff --git a/src/app/checkout/client.tsx b/src/app/checkout/client.tsx index 76dd7fc..6a8574b 100644 --- a/src/app/checkout/client.tsx +++ b/src/app/checkout/client.tsx @@ -5,6 +5,7 @@ import Link from 'next/link'; import { useCart } from '@/lib/cartStore'; import { loginCustomer } from '@/app/account/actions'; import Price from '@/components/Price'; +import ShippingSelector from '@/components/ShippingSelector'; interface CheckoutPageClientProps { isLoggedIn: boolean; @@ -16,6 +17,9 @@ export default function CheckoutPageClient({ isLoggedIn, customer }: CheckoutPag const [mode, setMode] = useState<'logged-in' | 'login' | 'guest' | null>(isLoggedIn ? 'logged-in' : null); const [checkingOut, setCheckingOut] = useState(false); const [checkoutError, setCheckoutError] = useState(null); + const [shippingCountry, setShippingCountry] = useState('GB'); + const [shippingService, setShippingService] = useState(null); + const [shippingCost, setShippingCost] = useState(0); const [guestData, setGuestData] = useState({ fullName: '', email: '', @@ -24,7 +28,8 @@ export default function CheckoutPageClient({ isLoggedIn, customer }: CheckoutPag }); const items = useCart((s) => s.items); - const total = useCart((s) => s.total()); + const subtotal = useCart((s) => s.total()); + const total = subtotal + shippingCost; useEffect(() => setMounted(true), []); @@ -51,6 +56,10 @@ export default function CheckoutPageClient({ isLoggedIn, customer }: CheckoutPag setCheckoutError('Please fill in all fields.'); return; } + if (!shippingService) { + setCheckoutError('Please select a shipping method.'); + return; + } setCheckingOut(true); setCheckoutError(null); @@ -71,6 +80,8 @@ export default function CheckoutPageClient({ isLoggedIn, customer }: CheckoutPag phone: guestData.phone, address: guestData.address, }, + shippingCountry, + shippingService, }), }); const data = await res.json(); @@ -106,8 +117,18 @@ export default function CheckoutPageClient({ isLoggedIn, customer }: CheckoutPag ))} -
-
+
+
+ Subtotal + +
+ {shippingCost > 0 && ( +
+ Shipping ({shippingService}) + +
+ )} +
Total
@@ -117,11 +138,28 @@ export default function CheckoutPageClient({ isLoggedIn, customer }: CheckoutPag {/* Checkout options */}
{mode === 'logged-in' ? ( -
-

Ready to checkout

-

Logged in as {customer?.email}

+
+
+

Ready to checkout

+

Logged in as {customer?.email}

+
+ + { + setShippingCountry(country); + setShippingService(service); + setShippingCost(cost); + }} + /> +
+ + { + setShippingCountry(country); + setShippingService(service); + setShippingCost(cost); + }} + /> +