Update src/app/checkout/page.tsx
This commit is contained in:
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user