fix(spa): complete checkout flow, UI standardization, and tailwind v4 styling fixes

This commit is contained in:
Your Name committed 2026-06-06 19:10:19 +07:00
1 parent 83df238bab
commit d8bff72e4e
24 files changed
+1169 -402

No files matched your search

+49 -49
View File
@@ -73,10 +73,10 @@ export default function OrderSuccessPage() {
if (loading) {
return (
<div className="min-h-screen">
<div className="min-h-screen bg-pop-bg">
<Navbar categories={categories} />
<div className="flex items-center justify-center pt-40">
<Loader2 className="w-8 h-8 text-cyan-glow animate-spin" />
<Loader2 className="w-8 h-8 text-spa-forest animate-spin" />
</div>
</div>
)
@@ -84,119 +84,119 @@ export default function OrderSuccessPage() {
if (!order || (order as any).error) {
return (
<div className="min-h-screen text-center pt-40">
<div className="min-h-screen bg-pop-bg text-center pt-40">
<Navbar categories={categories} />
<h1 className="text-2xl font-bold mb-4">Order Not Found</h1>
<Link to="/shop" className="text-cyan-glow hover:underline">Return to Shop</Link>
<h1 className="text-2xl font-bold mb-4 text-pop-black">Order Not Found</h1>
<Link to="/shop" className="text-spa-forest hover:underline font-bold">Return to Shop</Link>
</div>
)
}
return (
<div className="min-h-screen">
<div className="min-h-screen bg-pop-bg">
<Navbar categories={categories} />
<main className="max-w-3xl mx-auto px-6 pt-32 pb-24 space-y-12 animate-fade-in">
<main className="max-w-3xl mx-auto px-6 pt-32 pb-24 space-y-12 animate-fade-in text-pop-black">
{/* Header */}
<div className="text-center space-y-6">
<div className="w-20 h-20 bg-cyan-glow/10 rounded-full flex items-center justify-center mx-auto border border-cyan-glow/20">
<CheckCircle2 className="w-10 h-10 text-cyan-glow" />
<div className="w-20 h-20 bg-spa-sage/30 rounded-full flex items-center justify-center mx-auto border border-spa-stone/10 shadow-sm">
<CheckCircle2 className="w-10 h-10 text-spa-forest" />
</div>
<div>
<h1 className="text-4xl font-bold">Order Received</h1>
<p className="text-slate-400 mt-2">Thank you! Your order #{order.id.toString().padStart(4, '0')} has been placed.</p>
<h1 className="text-4xl font-bold text-pop-black">Order Received</h1>
<p className="text-spa-stone mt-2">Thank you! Your order #{order.id.toString().padStart(4, '0')} has been placed.</p>
</div>
</div>
{/* Order Summary */}
<div className="bg-night-900/50 p-8 rounded-2xl border border-white/5 space-y-6">
<h2 className="text-sm font-bold uppercase tracking-widest text-cyan-glow border-b border-white/10 pb-4">Order Items</h2>
<div className="bg-white p-8 rounded-2xl border border-spa-stone/10 space-y-6 shadow-sm">
<h2 className="text-sm font-bold uppercase tracking-widest text-spa-forest border-b border-spa-stone/10 pb-4">Order Items</h2>
<div className="space-y-4">
{order.items.map(item => (
<div key={item.id} className="flex items-center gap-4 text-sm">
<div className="w-12 h-12 rounded-lg bg-white/5 flex-shrink-0 overflow-hidden">
<div className="w-12 h-12 rounded-lg bg-spa-stone/10 flex-shrink-0 overflow-hidden border border-spa-stone/10">
<img src={item.productImage || '/images/oil_ozone.png'} alt="Product" className="w-full h-full object-cover" />
</div>
<div className="flex-1">
<p className="font-bold">{item.productName}</p>
<p className="text-slate-400 text-xs mt-0.5">{item.variantSize} x {item.quantity}</p>
<p className="font-bold text-pop-black">{item.productName}</p>
<p className="text-spa-stone/80 text-xs mt-0.5">{item.variantSize} x {item.quantity}</p>
</div>
<p className="font-medium text-cyan-glow">{formatPrice(item.priceAtPurchase * item.quantity)}</p>
<p className="font-bold text-rose-500">{formatPrice(item.priceAtPurchase * item.quantity)}</p>
</div>
))}
</div>
<div className="border-t border-white/10 pt-4 space-y-3 font-medium text-sm text-slate-300">
<div className="flex justify-between">
<div className="border-t border-spa-stone/10 pt-4 space-y-3 font-medium text-sm text-pop-black">
<div className="flex justify-between text-spa-stone">
<span>Subtotal</span>
<span>{formatPrice(order.totalAmount - order.shippingFee)}</span>
</div>
<div className="flex justify-between">
<div className="flex justify-between text-spa-stone">
<span>Shipping Fee</span>
<span>{formatPrice(order.shippingFee)}</span>
</div>
<div className="border-t border-white/10 pt-3 mt-3 flex justify-between text-lg font-bold text-white">
<div className="border-t border-spa-stone/10 pt-3 mt-3 flex justify-between text-lg font-bold text-pop-black">
<span>Total</span>
<span className="text-cyan-glow">{formatPrice(order.totalAmount)}</span>
<span className="text-rose-500">{formatPrice(order.totalAmount)}</span>
</div>
</div>
</div>
{/* Banking Details */}
{settings && order.status === 'PENDING_PAYMENT' && (
<div className="bg-night-900/50 p-8 rounded-2xl border border-white/5 text-center space-y-6 relative overflow-hidden">
<div className="absolute top-0 inset-x-0 h-1 bg-gradient-to-r from-transparent via-cyan-glow to-transparent opacity-50" />
<div className="bg-white p-8 rounded-2xl border border-spa-stone/10 text-center space-y-6 relative overflow-hidden shadow-sm">
<div className="absolute top-0 inset-x-0 h-1 bg-gradient-to-r from-transparent via-spa-forest to-transparent opacity-50" />
<h2 className="text-xs uppercase font-bold tracking-widest text-slate-400">Payment Required</h2>
<div className="text-3xl font-bold text-cyan-glow">
<h2 className="text-xs uppercase font-bold tracking-widest text-spa-stone/80">Payment Required</h2>
<div className="text-3xl font-bold text-spa-forest">
{formatPrice(order.totalAmount)}
</div>
<div className="bg-night-950 p-6 rounded-xl border border-white/5 inline-block text-left w-full max-w-md mx-auto space-y-4">
<div className="bg-spa-light p-6 rounded-xl border border-spa-stone/20 inline-block text-left w-full max-w-md mx-auto space-y-4 shadow-inner">
<div>
<p className="text-xs text-slate-500 uppercase tracking-widest">Bank</p>
<p className="font-bold">{settings.bankName}</p>
<p className="text-xs text-spa-stone/80 uppercase tracking-widest font-bold">Bank</p>
<p className="font-bold text-pop-black">{settings.bankName}</p>
</div>
<div className="flex items-center justify-between gap-4">
<div>
<p className="text-xs text-slate-500 uppercase tracking-widest">Account Number</p>
<p className="font-mono text-xl font-bold tracking-widest text-cyan-glow">{settings.bankAccountNumber}</p>
<p className="text-xs text-spa-stone/80 uppercase tracking-widest font-bold">Account Number</p>
<p className="font-mono text-xl font-bold tracking-widest text-spa-forest">{settings.bankAccountNumber}</p>
</div>
<button
onClick={copyToClipboard}
className="p-2 glass rounded-lg hover:bg-white/10 transition-colors shrink-0"
className="p-2 bg-white rounded-lg hover:bg-spa-stone/10 border border-spa-stone/20 transition-colors shrink-0 shadow-sm"
title="Copy account number"
>
{copied ? <CheckCircle2 className="w-5 h-5 text-emerald-400" /> : <Copy className="w-5 h-5 text-slate-300" />}
{copied ? <CheckCircle2 className="w-5 h-5 text-emerald-500" /> : <Copy className="w-5 h-5 text-spa-stone/80" />}
</button>
</div>
<div>
<p className="text-xs text-slate-500 uppercase tracking-widest">Account Name</p>
<p className="font-bold">{settings.bankAccountName}</p>
<p className="text-xs text-spa-stone/80 uppercase tracking-widest font-bold">Account Name</p>
<p className="font-bold text-pop-black">{settings.bankAccountName}</p>
</div>
</div>
<p className="text-xs text-slate-500">Please transfer the exact amount and upload your slip below.</p>
<p className="text-xs text-spa-stone font-medium">Please transfer the exact amount and upload your slip below.</p>
</div>
)}
{/* Upload Status */}
<div className="bg-night-900/50 p-8 rounded-2xl border border-white/5 space-y-6">
<h2 className="text-sm font-bold uppercase tracking-widest text-cyan-glow border-b border-white/10 pb-4">Payment Slip Verification</h2>
<div className="bg-white p-8 rounded-2xl border border-spa-stone/10 space-y-6 shadow-sm">
<h2 className="text-sm font-bold uppercase tracking-widest text-spa-forest border-b border-spa-stone/10 pb-4">Payment Slip Verification</h2>
{order.paymentSlipUrl ? (
<div className="flex flex-col items-center justify-center space-y-4 py-4">
<div className="w-16 h-16 bg-emerald-500/10 rounded-full flex items-center justify-center">
<CheckCircle2 className="w-8 h-8 text-emerald-400" />
<div className="w-16 h-16 bg-emerald-500/10 rounded-full flex items-center justify-center border border-emerald-500/20">
<CheckCircle2 className="w-8 h-8 text-emerald-500" />
</div>
<div className="text-center">
<p className="font-bold text-lg text-emerald-400">Slip Uploaded Successfully</p>
<p className="text-sm text-slate-400 mt-1">Status: {order.status}</p>
<p className="text-xs mt-2 text-slate-500">We will verify your payment and process your order shortly.</p>
<p className="font-bold text-lg text-emerald-600">Slip Uploaded Successfully</p>
<p className="text-sm text-spa-stone mt-1 font-medium">Status: {order.status}</p>
<p className="text-xs mt-2 text-spa-stone/80">We will verify your payment and process your order shortly.</p>
</div>
<img src={order.paymentSlipUrl} alt="Slip" className="w-48 rounded-xl border border-white/10 mt-4 opacity-50 hover:opacity-100 transition-opacity" />
<img src={order.paymentSlipUrl} alt="Slip" className="w-48 rounded-xl border border-spa-stone/20 mt-4 opacity-80 hover:opacity-100 transition-opacity shadow-sm" />
</div>
) : (
<div className="relative border-2 border-dashed border-white/10 rounded-xl p-10 hover:border-cyan-glow/50 transition-colors group cursor-pointer overflow-hidden">
<div className="relative border-2 border-dashed border-spa-stone/30 bg-spa-light rounded-xl p-10 hover:border-spa-forest transition-colors group cursor-pointer overflow-hidden">
<input
type="file"
accept="image/*"
@@ -206,13 +206,13 @@ export default function OrderSuccessPage() {
/>
<div className="text-center space-y-4">
{uploading ? (
<Loader2 className="w-12 h-12 text-cyan-glow animate-spin mx-auto" />
<Loader2 className="w-12 h-12 text-spa-forest animate-spin mx-auto" />
) : (
<UploadCloud className="w-12 h-12 text-slate-500 group-hover:text-cyan-glow transition-colors mx-auto" />
<UploadCloud className="w-12 h-12 text-spa-stone/60 group-hover:text-spa-forest transition-colors mx-auto" />
)}
<div>
<p className="font-bold">{uploading ? 'Uploading...' : 'Click or drag to upload slip'}</p>
<p className="text-xs text-slate-500 mt-1">Supports JPG, PNG (Max 5MB)</p>
<p className="font-bold text-pop-black">{uploading ? 'Uploading...' : 'Click or drag to upload slip'}</p>
<p className="text-xs text-spa-stone font-medium mt-1">Supports JPG, PNG (Max 5MB)</p>
</div>
</div>
</div>