Update src/app/checkout/page.tsx

This commit is contained in:
2026-03-09 09:47:54 +00:00
parent 3444d48c46
commit ca29ff87a8

View File

@@ -1,78 +1,18 @@
'use client';
import { ThemeProvider } from '@/components/theme-provider';
import NavbarStyleApple from '@/components/navbar/NavbarStyleApple/NavbarStyleApple';
import ReactLenis from 'lenis/react';
import { ThemeProvider } from '@/providers/themeProvider/ThemeProvider';
import NavbarLayoutFloatingInline from '@/components/navbar/NavbarLayoutFloatingInline';
import { useState } from 'react';
import { CreditCard, Wallet, DollarSign } from 'lucide-react';
const navItems = [
{ name: 'Home', id: '/' },
{ name: 'Checkout', id: '/checkout' },
{ name: 'Products', id: '/products' },
{ name: 'Cart', id: '/cart' },
{ name: 'Sign In', id: '/login' },
];
interface ShippingFormData {
firstName: string;
lastName: string;
email: string;
phone: string;
street: string;
city: string;
state: string;
zipCode: string;
country: string;
}
interface OrderItem {
id: string;
name: string;
price: number;
quantity: number;
}
export default function CheckoutPage() {
const [shippingData, setShippingData] = useState<ShippingFormData>({
firstName: '',
lastName: '',
email: '',
phone: '',
street: '',
city: '',
state: '',
zipCode: '',
country: '',
});
const [selectedPaymentMethod, setSelectedPaymentMethod] = useState<string>('ideal');
const [currentStep, setCurrentStep] = useState<'shipping' | 'order' | 'payment'>('shipping');
const orderItems: OrderItem[] = [
{ id: '1', name: 'Premium Subscription (1 Year)', price: 99.99, quantity: 1 },
{ id: '2', name: 'Support Package', price: 49.99, quantity: 1 },
];
const subtotal = orderItems.reduce((sum, item) => sum + item.price * item.quantity, 0);
const shipping = 10.0;
const tax = (subtotal + shipping) * 0.21; // 21% VAT
const total = subtotal + shipping + tax;
const handleShippingChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>) => {
const { name, value } = e.target;
setShippingData(prev => ({
...prev,
[name]: value,
}));
};
const handleShippingSubmit = (e: React.FormEvent) => {
e.preventDefault();
setCurrentStep('order');
};
const handlePaymentSubmit = () => {
console.log('Processing payment with method:', selectedPaymentMethod);
alert(`Payment processing with ${selectedPaymentMethod.toUpperCase()}`);
};
const [step, setStep] = useState<'shipping' | 'order' | 'payment'>('shipping');
return (
<ThemeProvider
@@ -81,369 +21,43 @@ export default function CheckoutPage() {
borderRadius="rounded"
contentWidth="medium"
sizing="medium"
background="aurora"
background="circleGradient"
cardStyle="glass-elevated"
primaryButtonStyle="gradient"
secondaryButtonStyle="glass"
headingFontWeight="semibold"
headingFontWeight="bold"
>
<ReactLenis root>
<NavbarStyleApple navItems={navItems} brandName="Webild" />
<div className="min-h-screen bg-gradient-to-b from-background to-background/50 pt-20 pb-16">
<div className="max-w-6xl mx-auto px-4">
{/* Progress Steps */}
<div className="mb-12">
<div className="flex justify-between items-center max-w-2xl mx-auto">
<div className="flex flex-col items-center">
<div className={`w-12 h-12 rounded-full flex items-center justify-center font-semibold transition-all ${
currentStep === 'shipping' || (currentStep !== 'shipping')
? 'bg-primary-cta text-white'
: 'bg-background-accent text-foreground'
}`}>
1
</div>
<p className="text-sm mt-2 font-medium">Shipping</p>
</div>
<div className={`flex-1 h-1 mx-4 transition-all ${
currentStep !== 'shipping' ? 'bg-primary-cta' : 'bg-background-accent'
}`} />
<div className="flex flex-col items-center">
<div className={`w-12 h-12 rounded-full flex items-center justify-center font-semibold transition-all ${
currentStep === 'order' || currentStep === 'payment'
? 'bg-primary-cta text-white'
: 'bg-background-accent text-foreground'
}`}>
2
</div>
<p className="text-sm mt-2 font-medium">Order Summary</p>
</div>
<div className={`flex-1 h-1 mx-4 transition-all ${
currentStep === 'payment' ? 'bg-primary-cta' : 'bg-background-accent'
}`} />
<div className="flex flex-col items-center">
<div className={`w-12 h-12 rounded-full flex items-center justify-center font-semibold transition-all ${
currentStep === 'payment'
? 'bg-primary-cta text-white'
: 'bg-background-accent text-foreground'
}`}>
3
</div>
<p className="text-sm mt-2 font-medium">Payment</p>
</div>
<div id="nav" data-section="nav">
<NavbarLayoutFloatingInline
navItems={navItems}
brandName="Webild"
/>
</div>
<div className="min-h-screen bg-gradient-to-br from-background to-card pt-24">
<div className="max-w-4xl mx-auto px-4 py-12">
<h1 className="text-4xl font-bold text-foreground mb-8">Checkout</h1>
<div className="bg-card border border-foreground/10 rounded-lg p-8">
{step === 'shipping' && (
<div>
<h2 className="text-2xl font-bold text-foreground mb-4">Shipping Information</h2>
<p className="text-foreground/60">Enter your shipping details.</p>
</div>
</div>
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
{/* Main Content */}
<div className="lg:col-span-2">
{/* Shipping Form */}
{currentStep === 'shipping' && (
<div className="bg-card rounded-lg p-8 backdrop-blur-md border border-primary-cta/10">
<h2 className="text-2xl font-bold mb-6 text-foreground">Shipping Information</h2>
<form onSubmit={handleShippingSubmit} className="space-y-6">
<div className="grid grid-cols-2 gap-4">
<div>
<label className="block text-sm font-medium text-foreground mb-2">First Name</label>
<input
type="text"
name="firstName"
value={shippingData.firstName}
onChange={handleShippingChange}
required
className="w-full px-4 py-2 rounded-lg border border-primary-cta/20 bg-background/50 text-foreground placeholder-foreground/50 focus:outline-none focus:border-primary-cta/50 transition-colors"
placeholder="John"
/>
</div>
<div>
<label className="block text-sm font-medium text-foreground mb-2">Last Name</label>
<input
type="text"
name="lastName"
value={shippingData.lastName}
onChange={handleShippingChange}
required
className="w-full px-4 py-2 rounded-lg border border-primary-cta/20 bg-background/50 text-foreground placeholder-foreground/50 focus:outline-none focus:border-primary-cta/50 transition-colors"
placeholder="Doe"
/>
</div>
</div>
<div className="grid grid-cols-2 gap-4">
<div>
<label className="block text-sm font-medium text-foreground mb-2">Email</label>
<input
type="email"
name="email"
value={shippingData.email}
onChange={handleShippingChange}
required
className="w-full px-4 py-2 rounded-lg border border-primary-cta/20 bg-background/50 text-foreground placeholder-foreground/50 focus:outline-none focus:border-primary-cta/50 transition-colors"
placeholder="john@example.com"
/>
</div>
<div>
<label className="block text-sm font-medium text-foreground mb-2">Phone</label>
<input
type="tel"
name="phone"
value={shippingData.phone}
onChange={handleShippingChange}
required
className="w-full px-4 py-2 rounded-lg border border-primary-cta/20 bg-background/50 text-foreground placeholder-foreground/50 focus:outline-none focus:border-primary-cta/50 transition-colors"
placeholder="+31 6 12345678"
/>
</div>
</div>
<div>
<label className="block text-sm font-medium text-foreground mb-2">Street Address</label>
<input
type="text"
name="street"
value={shippingData.street}
onChange={handleShippingChange}
required
className="w-full px-4 py-2 rounded-lg border border-primary-cta/20 bg-background/50 text-foreground placeholder-foreground/50 focus:outline-none focus:border-primary-cta/50 transition-colors"
placeholder="123 Main Street"
/>
</div>
<div className="grid grid-cols-2 gap-4">
<div>
<label className="block text-sm font-medium text-foreground mb-2">City</label>
<input
type="text"
name="city"
value={shippingData.city}
onChange={handleShippingChange}
required
className="w-full px-4 py-2 rounded-lg border border-primary-cta/20 bg-background/50 text-foreground placeholder-foreground/50 focus:outline-none focus:border-primary-cta/50 transition-colors"
placeholder="Amsterdam"
/>
</div>
<div>
<label className="block text-sm font-medium text-foreground mb-2">State/Province</label>
<input
type="text"
name="state"
value={shippingData.state}
onChange={handleShippingChange}
required
className="w-full px-4 py-2 rounded-lg border border-primary-cta/20 bg-background/50 text-foreground placeholder-foreground/50 focus:outline-none focus:border-primary-cta/50 transition-colors"
placeholder="North Holland"
/>
</div>
</div>
<div className="grid grid-cols-2 gap-4">
<div>
<label className="block text-sm font-medium text-foreground mb-2">ZIP Code</label>
<input
type="text"
name="zipCode"
value={shippingData.zipCode}
onChange={handleShippingChange}
required
className="w-full px-4 py-2 rounded-lg border border-primary-cta/20 bg-background/50 text-foreground placeholder-foreground/50 focus:outline-none focus:border-primary-cta/50 transition-colors"
placeholder="1012 NX"
/>
</div>
<div>
<label className="block text-sm font-medium text-foreground mb-2">Country</label>
<select
name="country"
value={shippingData.country}
onChange={handleShippingChange}
required
className="w-full px-4 py-2 rounded-lg border border-primary-cta/20 bg-background/50 text-foreground focus:outline-none focus:border-primary-cta/50 transition-colors"
>
<option value="">Select Country</option>
<option value="NL">Netherlands</option>
<option value="DE">Germany</option>
<option value="BE">Belgium</option>
<option value="FR">France</option>
</select>
</div>
</div>
<button
type="submit"
className="w-full mt-8 px-6 py-3 bg-gradient-to-r from-primary-cta to-accent text-white font-semibold rounded-lg hover:opacity-90 transition-opacity"
>
Continue to Order Review
</button>
</form>
</div>
)}
{/* Order Summary */}
{currentStep === 'order' && (
<div className="bg-card rounded-lg p-8 backdrop-blur-md border border-primary-cta/10">
<h2 className="text-2xl font-bold mb-6 text-foreground">Order Summary</h2>
<div className="space-y-4 mb-8">
{orderItems.map(item => (
<div key={item.id} className="flex justify-between items-center pb-4 border-b border-primary-cta/10">
<div>
<p className="font-medium text-foreground">{item.name}</p>
<p className="text-sm text-foreground/60">Quantity: {item.quantity}</p>
</div>
<p className="font-semibold text-foreground">${(item.price * item.quantity).toFixed(2)}</p>
</div>
))}
</div>
<div className="space-y-3 bg-background/50 rounded-lg p-4">
<div className="flex justify-between text-foreground">
<span>Subtotal</span>
<span>${subtotal.toFixed(2)}</span>
</div>
<div className="flex justify-between text-foreground">
<span>Shipping</span>
<span>${shipping.toFixed(2)}</span>
</div>
<div className="flex justify-between text-foreground">
<span>Tax (21%)</span>
<span>${tax.toFixed(2)}</span>
</div>
<div className="flex justify-between text-lg font-bold text-primary-cta pt-3 border-t border-primary-cta/20">
<span>Total</span>
<span>${total.toFixed(2)}</span>
</div>
</div>
<div className="mt-8 flex gap-4">
<button
onClick={() => setCurrentStep('shipping')}
className="flex-1 px-6 py-3 border border-primary-cta/50 text-foreground font-semibold rounded-lg hover:bg-background/50 transition-colors"
>
Back
</button>
<button
onClick={() => setCurrentStep('payment')}
className="flex-1 px-6 py-3 bg-gradient-to-r from-primary-cta to-accent text-white font-semibold rounded-lg hover:opacity-90 transition-opacity"
>
Continue to Payment
</button>
</div>
</div>
)}
{/* Payment Methods */}
{currentStep === 'payment' && (
<div className="bg-card rounded-lg p-8 backdrop-blur-md border border-primary-cta/10">
<h2 className="text-2xl font-bold mb-6 text-foreground">Select Payment Method</h2>
<div className="space-y-4">
{/* iDEAL */}
<label className="flex items-center p-4 border-2 border-primary-cta/20 rounded-lg cursor-pointer hover:border-primary-cta/50 transition-colors" style={{
borderColor: selectedPaymentMethod === 'ideal' ? 'var(--primary-cta)' : 'var(--primary-cta)20'
}}>
<input
type="radio"
name="payment"
value="ideal"
checked={selectedPaymentMethod === 'ideal'}
onChange={(e) => setSelectedPaymentMethod(e.target.value)}
className="w-4 h-4"
/>
<DollarSign className="w-6 h-6 ml-4 text-accent" />
<div className="ml-4">
<p className="font-semibold text-foreground">iDEAL</p>
<p className="text-sm text-foreground/60">Direct bank transfer (Popular in Netherlands)</p>
</div>
</label>
{/* PayPal */}
<label className="flex items-center p-4 border-2 border-primary-cta/20 rounded-lg cursor-pointer hover:border-primary-cta/50 transition-colors" style={{
borderColor: selectedPaymentMethod === 'paypal' ? 'var(--primary-cta)' : 'var(--primary-cta)20'
}}>
<input
type="radio"
name="payment"
value="paypal"
checked={selectedPaymentMethod === 'paypal'}
onChange={(e) => setSelectedPaymentMethod(e.target.value)}
className="w-4 h-4"
/>
<Wallet className="w-6 h-6 ml-4 text-accent" />
<div className="ml-4">
<p className="font-semibold text-foreground">PayPal</p>
<p className="text-sm text-foreground/60">Fast and secure payment with PayPal</p>
</div>
</label>
{/* Mastercard */}
<label className="flex items-center p-4 border-2 border-primary-cta/20 rounded-lg cursor-pointer hover:border-primary-cta/50 transition-colors" style={{
borderColor: selectedPaymentMethod === 'mastercard' ? 'var(--primary-cta)' : 'var(--primary-cta)20'
}}>
<input
type="radio"
name="payment"
value="mastercard"
checked={selectedPaymentMethod === 'mastercard'}
onChange={(e) => setSelectedPaymentMethod(e.target.value)}
className="w-4 h-4"
/>
<CreditCard className="w-6 h-6 ml-4 text-accent" />
<div className="ml-4">
<p className="font-semibold text-foreground">Mastercard</p>
<p className="text-sm text-foreground/60">Credit or debit card payment</p>
</div>
</label>
</div>
<div className="mt-8 flex gap-4">
<button
onClick={() => setCurrentStep('order')}
className="flex-1 px-6 py-3 border border-primary-cta/50 text-foreground font-semibold rounded-lg hover:bg-background/50 transition-colors"
>
Back
</button>
<button
onClick={handlePaymentSubmit}
className="flex-1 px-6 py-3 bg-gradient-to-r from-primary-cta to-accent text-white font-semibold rounded-lg hover:opacity-90 transition-opacity"
>
Complete Payment
</button>
</div>
</div>
)}
)}
{step === 'order' && (
<div>
<h2 className="text-2xl font-bold text-foreground mb-4">Order Review</h2>
<p className="text-foreground/60">Review your order before payment.</p>
</div>
{/* Order Summary Sidebar */}
<div className="lg:col-span-1">
<div className="bg-card rounded-lg p-6 backdrop-blur-md border border-primary-cta/10 sticky top-24">
<h3 className="text-xl font-bold mb-6 text-foreground">Order Total</h3>
<div className="space-y-3 mb-6">
<div className="flex justify-between text-sm text-foreground/80">
<span>Subtotal</span>
<span>${subtotal.toFixed(2)}</span>
</div>
<div className="flex justify-between text-sm text-foreground/80">
<span>Shipping</span>
<span>${shipping.toFixed(2)}</span>
</div>
<div className="flex justify-between text-sm text-foreground/80">
<span>Tax (21%)</span>
<span>${tax.toFixed(2)}</span>
</div>
</div>
<div className="bg-gradient-to-r from-primary-cta/10 to-accent/10 rounded-lg p-4">
<div className="flex justify-between items-center">
<span className="font-semibold text-foreground">Total</span>
<span className="text-2xl font-bold text-primary-cta">${total.toFixed(2)}</span>
</div>
</div>
<div className="mt-6 pt-6 border-t border-primary-cta/10">
<p className="text-xs text-foreground/60"> Secure payment</p>
<p className="text-xs text-foreground/60"> Money-back guarantee</p>
<p className="text-xs text-foreground/60"> Fast delivery</p>
</div>
</div>
)}
{step === 'payment' && (
<div>
<h2 className="text-2xl font-bold text-foreground mb-4">Payment</h2>
<p className="text-foreground/60">Complete your purchase.</p>
</div>
</div>
)}
</div>
</div>
</ReactLenis>
</div>
</ThemeProvider>
);
}