katheryn-website/frontend/src/app/order-confirmation/page.tsx

140 lines
5.5 KiB
TypeScript

import Link from 'next/link';
import { createDirectus, rest, staticToken, readItem, readItems } from '@directus/sdk';
import type { Order, OrderItem } from '@/lib/directus';
const directusUrl = process.env.DIRECTUS_INTERNAL_URL || process.env.NEXT_PUBLIC_DIRECTUS_URL || 'https://katheryn-cms.jeffemmett.com';
const storeToken = process.env.DIRECTUS_STORE_TOKEN || process.env.DIRECTUS_API_TOKEN || '';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const client = createDirectus<any>(directusUrl)
.with(staticToken(storeToken))
.with(rest());
export default async function OrderConfirmationPage({
searchParams,
}: {
searchParams: Promise<{ id?: string }>;
}) {
const params = await searchParams;
const orderId = params.id;
if (!orderId) {
return (
<div className="min-h-screen flex flex-col items-center justify-center py-20 pt-32">
<h1 className="font-serif text-2xl">Order not found</h1>
<Link href="/store" className="mt-8 btn btn-primary">
Browse Store
</Link>
</div>
);
}
let order: Order;
let orderItems: OrderItem[];
try {
order = await client.request(readItem('orders', orderId)) as Order;
orderItems = await client.request(
readItems('order_items', {
filter: { order_id: { _eq: parseInt(orderId) } },
fields: ['*'],
})
) as OrderItem[];
} catch {
return (
<div className="min-h-screen flex flex-col items-center justify-center py-20 pt-32">
<h1 className="font-serif text-2xl">Order not found</h1>
<p className="mt-4 text-gray-600">We couldn&apos;t find this order. Please check your email for confirmation.</p>
<Link href="/store" className="mt-8 btn btn-primary">
Browse Store
</Link>
</div>
);
}
const currencySymbol = order.currency === 'GBP' ? '\u00a3' : '$';
const customerName = [order.customer_first_name, order.customer_last_name].filter(Boolean).join(' ') || 'there';
return (
<div className="min-h-screen bg-white pt-24">
<div className="mx-auto max-w-2xl px-4 py-16 text-center">
<div className="mb-8">
<div className="mx-auto h-16 w-16 rounded-full bg-green-100 flex items-center justify-center mb-6">
<svg className="h-8 w-8 text-green-600" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
</svg>
</div>
<h1 className="font-serif text-3xl">Thank you, {customerName}!</h1>
<p className="mt-4 text-gray-600">
Your order has been confirmed and a receipt has been sent to {order.customer_email}.
</p>
</div>
<div className="bg-gray-50 p-8 text-left mt-12">
<div className="flex justify-between items-start mb-6">
<div>
<p className="text-sm text-gray-500 uppercase tracking-wider">Order Number</p>
<p className="text-lg font-medium">#{order.id}</p>
</div>
<div className="text-right">
<p className="text-sm text-gray-500 uppercase tracking-wider">Total</p>
<p className="text-lg font-medium">{currencySymbol}{Number(order.total).toLocaleString()}</p>
</div>
</div>
<div className="border-t border-gray-200 pt-6">
<h2 className="text-sm font-medium uppercase tracking-wider text-gray-500 mb-4">Items</h2>
<ul className="space-y-3">
{orderItems.map((item) => (
<li key={item.id} className="flex justify-between text-sm">
<span>{item.artwork_name}</span>
<span className="font-medium">
{(item.currency === 'GBP' ? '\u00a3' : '$')}{Number(item.price).toLocaleString()}
</span>
</li>
))}
</ul>
</div>
<div className="border-t border-gray-200 pt-6 mt-6 space-y-2">
<div className="flex justify-between text-sm">
<span>Subtotal</span>
<span>{currencySymbol}{Number(order.subtotal).toLocaleString()}</span>
</div>
{order.shipping_cost != null && Number(order.shipping_cost) > 0 && (
<div className="flex justify-between text-sm">
<span>Shipping</span>
<span>{currencySymbol}{Number(order.shipping_cost).toLocaleString()}</span>
</div>
)}
<div className="flex justify-between text-sm font-medium border-t border-gray-200 pt-2">
<span>Total</span>
<span>{currencySymbol}{Number(order.total).toLocaleString()}</span>
</div>
</div>
{(order.shipping_address || order.shipping_city) && (
<div className="border-t border-gray-200 pt-6 mt-6">
<h2 className="text-sm font-medium uppercase tracking-wider text-gray-500 mb-2">Shipping To</h2>
<p className="text-sm text-gray-700">
{[order.shipping_address, order.shipping_city, order.shipping_postcode, order.shipping_country]
.filter(Boolean)
.join(', ')}
</p>
</div>
)}
</div>
<div className="mt-8 space-y-4">
<p className="text-sm text-gray-500">
Katheryn will be in touch regarding delivery details.
</p>
<Link href="/store" className="inline-block btn btn-primary">
Continue Shopping
</Link>
</div>
</div>
</div>
);
}