Feature: Add quantity adjustment and fix shipping selection
- Add quantity adjustment controls (+ and -) on checkout order summary - Prevent quantity from going below 1 with disabled minus button at qty=1 - Fix shipping selector not updating by wrapping callback in useCallback - Shipping option changes now properly update order total - Totals recalculate reactively when adjusting quantities or shipping Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Haiku 4.5
parent
5538938020
commit
08038dffb1
+50
-31
@@ -3,6 +3,8 @@ import { redirect } from 'next/navigation';
|
||||
import { getCurrentCustomer } from '@/lib/auth';
|
||||
import { prisma } from '@/lib/prisma';
|
||||
import { logoutCustomer } from './actions';
|
||||
import AddressFormSection from '@/components/AddressFormSection';
|
||||
import OlderOrders from '@/components/OlderOrders';
|
||||
|
||||
function formatPrice(cents: number) {
|
||||
return `£${(cents / 100).toFixed(2)}`;
|
||||
@@ -36,6 +38,13 @@ export default async function AccountPage() {
|
||||
orderBy: { createdAt: 'desc' },
|
||||
});
|
||||
|
||||
// Separate recent (< 7 days) and older (>= 7 days) orders
|
||||
const now = new Date();
|
||||
const sevenDaysAgo = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
|
||||
|
||||
const recentOrders = orders.filter(order => new Date(order.createdAt) > sevenDaysAgo);
|
||||
const olderOrders = orders.filter(order => new Date(order.createdAt) <= sevenDaysAgo);
|
||||
|
||||
return (
|
||||
<div className="mx-auto max-w-3xl px-6 py-12">
|
||||
<div className="flex items-baseline justify-between gap-3">
|
||||
@@ -56,6 +65,8 @@ export default async function AccountPage() {
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<AddressFormSection customer={customer} />
|
||||
|
||||
<h2 className="mt-10 font-display text-xl">Design reviews</h2>
|
||||
{designReviews.length === 0 ? (
|
||||
<p className="mt-3 text-sm text-muted">No designs awaiting review.</p>
|
||||
@@ -88,41 +99,49 @@ export default async function AccountPage() {
|
||||
{orders.length === 0 ? (
|
||||
<p className="mt-3 text-sm text-muted">No orders yet.</p>
|
||||
) : (
|
||||
<div className="mt-4 divide-y divide-line border-t border-line">
|
||||
{orders.map((order) => (
|
||||
<div key={order.id} className="border-b border-line py-4 last:border-b-0">
|
||||
<Link
|
||||
href={`/account/orders/${order.id}`}
|
||||
className="flex flex-wrap items-center justify-between gap-2 hover:opacity-80"
|
||||
>
|
||||
<div>
|
||||
<p className="text-sm">
|
||||
{new Date(order.createdAt).toLocaleDateString(undefined, { dateStyle: 'medium' })} ·{' '}
|
||||
{order.items.length} item{order.items.length === 1 ? '' : 's'}
|
||||
</p>
|
||||
<span className={`tag-label mt-1 inline-block rounded-full px-3 py-1 ${statusClasses(order.status)}`}>
|
||||
{statusLabel(order.status)}
|
||||
</span>
|
||||
</div>
|
||||
<span className="font-mono text-sm">{formatPrice(order.total)}</span>
|
||||
</Link>
|
||||
<>
|
||||
{recentOrders.length > 0 && (
|
||||
<div className="mt-4 divide-y divide-line border-t border-line">
|
||||
{recentOrders.map((order) => (
|
||||
<div key={order.id} className="border-b border-line py-4 last:border-b-0">
|
||||
<Link
|
||||
href={`/account/orders/${order.id}`}
|
||||
className="flex flex-wrap items-center justify-between gap-2 hover:opacity-80"
|
||||
>
|
||||
<div>
|
||||
<p className="text-sm">
|
||||
{new Date(order.createdAt).toLocaleDateString(undefined, { dateStyle: 'medium' })} ·{' '}
|
||||
{order.items.length} item{order.items.length === 1 ? '' : 's'}
|
||||
</p>
|
||||
<span className={`tag-label mt-1 inline-block rounded-full px-3 py-1 ${statusClasses(order.status)}`}>
|
||||
{statusLabel(order.status)}
|
||||
</span>
|
||||
</div>
|
||||
<span className="font-mono text-sm">{formatPrice(order.total)}</span>
|
||||
</Link>
|
||||
|
||||
{/* Tracking Information */}
|
||||
{order.carrier && order.trackingNumber && (
|
||||
<div className="mt-3 border-t border-line pt-3 text-sm">
|
||||
<p>
|
||||
<strong>Tracking:</strong> {order.carrier} · {order.trackingNumber}
|
||||
</p>
|
||||
{order.estimatedDeliveryDate && (
|
||||
<p className="text-muted">
|
||||
Est. delivery: {new Date(order.estimatedDeliveryDate).toLocaleDateString(undefined, { dateStyle: 'medium' })}
|
||||
</p>
|
||||
{/* Tracking Information */}
|
||||
{order.carrier && order.trackingNumber && (
|
||||
<div className="mt-3 border-t border-line pt-3 text-sm">
|
||||
<p>
|
||||
<strong>Tracking:</strong> {order.carrier} · {order.trackingNumber}
|
||||
</p>
|
||||
{order.estimatedDeliveryDate && (
|
||||
<p className="text-muted">
|
||||
Est. delivery: {new Date(order.estimatedDeliveryDate).toLocaleDateString(undefined, { dateStyle: 'medium' })}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{olderOrders.length > 0 && (
|
||||
<OlderOrders orders={olderOrders} formatPrice={formatPrice} statusLabel={statusLabel} statusClasses={statusClasses} />
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user