Merge version_3 into main #5
203
src/app/checkout/page.tsx
Normal file
203
src/app/checkout/page.tsx
Normal file
@@ -0,0 +1,203 @@
|
||||
"use client";
|
||||
|
||||
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
||||
import NavbarStyleApple from '@/components/navbar/NavbarStyleApple/NavbarStyleApple';
|
||||
import FooterLogoReveal from '@/components/sections/footer/FooterLogoReveal';
|
||||
import TextBox from '@/components/Textbox';
|
||||
import { ShoppingCart, Trash2, ArrowRight } from 'lucide-react';
|
||||
import { useState, useEffect } from 'react';
|
||||
import Link from 'next/link';
|
||||
|
||||
export default function CheckoutPage() {
|
||||
const [cartItems, setCartItems] = useState([]);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
const storedCart = localStorage.getItem('cart');
|
||||
if (storedCart) {
|
||||
try {
|
||||
setCartItems(JSON.parse(storedCart));
|
||||
} catch (error) {
|
||||
console.error('Error parsing cart:', error);
|
||||
}
|
||||
}
|
||||
setIsLoading(false);
|
||||
}, []);
|
||||
|
||||
const handleRemoveItem = (id) => {
|
||||
const updatedCart = cartItems.filter(item => item.id !== id);
|
||||
setCartItems(updatedCart);
|
||||
localStorage.setItem('cart', JSON.stringify(updatedCart));
|
||||
};
|
||||
|
||||
const handleUpdateQuantity = (id, quantity) => {
|
||||
if (quantity <= 0) {
|
||||
handleRemoveItem(id);
|
||||
} else {
|
||||
const updatedCart = cartItems.map(item =>
|
||||
item.id === id ? { ...item, quantity } : item
|
||||
);
|
||||
setCartItems(updatedCart);
|
||||
localStorage.setItem('cart', JSON.stringify(updatedCart));
|
||||
}
|
||||
};
|
||||
|
||||
const subtotal = cartItems.reduce((sum, item) => sum + (parseFloat(item.price.replace('$', '')) * item.quantity), 0);
|
||||
const tax = subtotal * 0.08;
|
||||
const delivery = subtotal > 30 ? 0 : 4.99;
|
||||
const total = subtotal + tax + delivery;
|
||||
|
||||
return (
|
||||
<ThemeProvider
|
||||
defaultButtonVariant="expand-hover"
|
||||
defaultTextAnimation="entrance-slide"
|
||||
borderRadius="soft"
|
||||
contentWidth="compact"
|
||||
sizing="largeSmall"
|
||||
background="aurora"
|
||||
cardStyle="subtle-shadow"
|
||||
primaryButtonStyle="shadow"
|
||||
secondaryButtonStyle="radial-glow"
|
||||
headingFontWeight="normal"
|
||||
>
|
||||
<div id="nav" data-section="nav">
|
||||
<NavbarStyleApple
|
||||
brandName="Kings Garden"
|
||||
navItems={[
|
||||
{ name: "Menu", id: "/products" },
|
||||
{ name: "About", id: "about" },
|
||||
{ name: "How It Works", id: "how-it-works" },
|
||||
{ name: "Reviews", id: "reviews" },
|
||||
{ name: "Contact", id: "contact" }
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="checkout" data-section="checkout" className="w-full py-20 px-4 md:px-8">
|
||||
<div className="w-full max-w-4xl mx-auto">
|
||||
<TextBox
|
||||
title="Order Summary"
|
||||
description="Review your items before completing your order"
|
||||
textboxLayout="default"
|
||||
center={true}
|
||||
className="mb-12"
|
||||
/>
|
||||
|
||||
{isLoading ? (
|
||||
<div className="flex justify-center items-center h-40">
|
||||
<p className="text-lg">Loading cart...</p>
|
||||
</div>
|
||||
) : cartItems.length === 0 ? (
|
||||
<div className="text-center py-12 border border-dashed border-accent/30 rounded-lg">
|
||||
<ShoppingCart className="w-12 h-12 mx-auto mb-4 opacity-50" />
|
||||
<p className="text-lg mb-6">Your cart is empty</p>
|
||||
<Link
|
||||
href="/products"
|
||||
className="inline-flex items-center gap-2 px-6 py-2 rounded-lg bg-primary-cta text-white hover:opacity-90 transition"
|
||||
>
|
||||
Continue Shopping
|
||||
<ArrowRight className="w-4 h-4" />
|
||||
</Link>
|
||||
</div>
|
||||
) : (
|
||||
<div className="grid md:grid-cols-3 gap-8">
|
||||
{/* Cart Items */}
|
||||
<div className="md:col-span-2">
|
||||
<div className="space-y-4">
|
||||
{cartItems.map((item) => (
|
||||
<div key={item.id} className="flex items-center justify-between p-4 border border-accent/20 rounded-lg hover:border-accent/40 transition">
|
||||
<div className="flex items-start gap-4 flex-1">
|
||||
{item.imageSrc && (
|
||||
<img
|
||||
src={item.imageSrc}
|
||||
alt={item.name}
|
||||
className="w-24 h-24 object-cover rounded-lg"
|
||||
/>
|
||||
)}
|
||||
<div className="flex-1">
|
||||
<h3 className="font-semibold text-lg mb-1">{item.name}</h3>
|
||||
<p className="text-sm opacity-75 mb-3">{item.variant}</p>
|
||||
<p className="text-sm font-medium">{item.price}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-3 ml-4">
|
||||
<div className="flex items-center border border-accent/30 rounded">
|
||||
<button
|
||||
onClick={() => handleUpdateQuantity(item.id, item.quantity - 1)}
|
||||
className="px-3 py-1 hover:bg-accent/10 transition"
|
||||
>
|
||||
−
|
||||
</button>
|
||||
<span className="px-3 py-1 min-w-12 text-center">{item.quantity}</span>
|
||||
<button
|
||||
onClick={() => handleUpdateQuantity(item.id, item.quantity + 1)}
|
||||
className="px-3 py-1 hover:bg-accent/10 transition"
|
||||
>
|
||||
+
|
||||
</button>
|
||||
</div>
|
||||
<button
|
||||
onClick={() => handleRemoveItem(item.id)}
|
||||
className="p-2 hover:bg-red-500/10 transition rounded"
|
||||
aria-label="Remove item"
|
||||
>
|
||||
<Trash2 className="w-5 h-5 text-red-500" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<Link
|
||||
href="/products"
|
||||
className="inline-flex items-center gap-2 mt-6 text-primary-cta hover:opacity-75 transition"
|
||||
>
|
||||
← Continue Shopping
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{/* Order Summary */}
|
||||
<div className="md:col-span-1">
|
||||
<div className="p-6 border border-accent/20 rounded-lg sticky top-24">
|
||||
<h3 className="text-lg font-semibold mb-4">Order Total</h3>
|
||||
<div className="space-y-3 mb-4 pb-4 border-b border-accent/20">
|
||||
<div className="flex justify-between">
|
||||
<span className="opacity-75">Subtotal</span>
|
||||
<span>${subtotal.toFixed(2)}</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="opacity-75">Tax (8%)</span>
|
||||
<span>${tax.toFixed(2)}</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="opacity-75">Delivery</span>
|
||||
<span>{delivery === 0 ? 'FREE' : `$${delivery.toFixed(2)}`}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex justify-between mb-6 text-lg font-semibold">
|
||||
<span>Total</span>
|
||||
<span>${total.toFixed(2)}</span>
|
||||
</div>
|
||||
{delivery === 0 && (
|
||||
<p className="text-xs text-green-600 mb-4 text-center">Free delivery on orders over $30!</p>
|
||||
)}
|
||||
<button className="w-full py-3 bg-primary-cta text-white rounded-lg font-semibold hover:opacity-90 transition">
|
||||
Proceed to Payment
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="footer" data-section="footer">
|
||||
<FooterLogoReveal
|
||||
logoText="Kings Garden"
|
||||
leftLink={{ text: "Privacy Policy", href: "#" }}
|
||||
rightLink={{ text: "Terms of Service", href: "#" }}
|
||||
ariaLabel="Site footer"
|
||||
/>
|
||||
</div>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
@@ -30,7 +30,7 @@ export default function LandingPage() {
|
||||
<NavbarStyleApple
|
||||
brandName="Kings Garden"
|
||||
navItems={[
|
||||
{ name: "Menu", id: "menu" },
|
||||
{ name: "Menu", id: "/products" },
|
||||
{ name: "About", id: "about" },
|
||||
{ name: "How It Works", id: "how-it-works" },
|
||||
{ name: "Reviews", id: "reviews" },
|
||||
@@ -47,8 +47,8 @@ export default function LandingPage() {
|
||||
tagIcon={Zap}
|
||||
tagAnimation="slide-up"
|
||||
buttons={[
|
||||
{ text: "Order Now", href: "#menu" },
|
||||
{ text: "View Menu", href: "#menu" }
|
||||
{ text: "Order Now", href: "/products" },
|
||||
{ text: "View Menu", href: "/products" }
|
||||
]}
|
||||
buttonAnimation="slide-up"
|
||||
imageSrc="http://img.b2bpic.net/free-photo/top-close-up-view-vegetables-plate-roasted-vegetables-red-tablecloth_140725-72155.jpg"
|
||||
@@ -81,13 +81,13 @@ export default function LandingPage() {
|
||||
textboxLayout="default"
|
||||
features={[
|
||||
{
|
||||
title: "Kung Pao Chicken", description: "Tender chicken stir-fried with cashews, peppers, and our secret spicy sauce. A timeless favorite.", imageSrc: "http://img.b2bpic.net/free-photo/clams-fried-curry-powder-black-plate_1150-23777.jpg", imageAlt: "Kung Pao chicken dish", button: { text: "Add to Cart", href: "#menu" }
|
||||
title: "Kung Pao Chicken", description: "Tender chicken stir-fried with cashews, peppers, and our secret spicy sauce. A timeless favorite.", imageSrc: "http://img.b2bpic.net/free-photo/clams-fried-curry-powder-black-plate_1150-23777.jpg", imageAlt: "Kung Pao chicken dish", button: { text: "Add to Cart", href: "/products" }
|
||||
},
|
||||
{
|
||||
title: "Egg Fried Rice", description: "Fluffy jasmine rice with eggs, peas, carrots, and green onions. Perfect side or light meal.", imageSrc: "http://img.b2bpic.net/free-psd/savory-bowl-fried-rice-features-sunnysideup-egg-is-garnished-with-fresh-chilies-green-onions_84443-63357.jpg", imageAlt: "Egg fried rice", button: { text: "Add to Cart", href: "#menu" }
|
||||
title: "Egg Fried Rice", description: "Fluffy jasmine rice with eggs, peas, carrots, and green onions. Perfect side or light meal.", imageSrc: "http://img.b2bpic.net/free-psd/savory-bowl-fried-rice-features-sunnysideup-egg-is-garnished-with-fresh-chilies-green-onions_84443-63357.jpg", imageAlt: "Egg fried rice", button: { text: "Add to Cart", href: "/products" }
|
||||
},
|
||||
{
|
||||
title: "Steamed Dumplings", description: "Hand-wrapped pork and vegetable dumplings, steamed to perfection. Six pieces per order.", imageSrc: "http://img.b2bpic.net/free-photo/close-up-person-s-hand-holding-taiwan-s-traditional-food-gua-bao-steamer_23-2148123757.jpg", imageAlt: "Steamed dumplings", button: { text: "Add to Cart", href: "#menu" }
|
||||
title: "Steamed Dumplings", description: "Hand-wrapped pork and vegetable dumplings, steamed to perfection. Six pieces per order.", imageSrc: "http://img.b2bpic.net/free-photo/close-up-person-s-hand-holding-taiwan-s-traditional-food-gua-bao-steamer_23-2148123757.jpg", imageAlt: "Steamed dumplings", button: { text: "Add to Cart", href: "/products" }
|
||||
}
|
||||
]}
|
||||
gridVariant="three-columns-all-equal-width"
|
||||
|
||||
74
src/app/products/page.tsx
Normal file
74
src/app/products/page.tsx
Normal file
@@ -0,0 +1,74 @@
|
||||
"use client";
|
||||
|
||||
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
||||
import NavbarStyleApple from '@/components/navbar/NavbarStyleApple/NavbarStyleApple';
|
||||
import ProductCardFour from '@/components/sections/product/ProductCardFour';
|
||||
import FooterLogoReveal from '@/components/sections/footer/FooterLogoReveal';
|
||||
import { Package } from 'lucide-react';
|
||||
|
||||
export default function ProductsPage() {
|
||||
return (
|
||||
<ThemeProvider
|
||||
defaultButtonVariant="expand-hover"
|
||||
defaultTextAnimation="entrance-slide"
|
||||
borderRadius="soft"
|
||||
contentWidth="compact"
|
||||
sizing="largeSmall"
|
||||
background="aurora"
|
||||
cardStyle="subtle-shadow"
|
||||
primaryButtonStyle="shadow"
|
||||
secondaryButtonStyle="radial-glow"
|
||||
headingFontWeight="normal"
|
||||
>
|
||||
<div id="nav" data-section="nav">
|
||||
<NavbarStyleApple
|
||||
brandName="Kings Garden"
|
||||
navItems={[
|
||||
{ name: "Menu", id: "/products" },
|
||||
{ name: "About", id: "about" },
|
||||
{ name: "How It Works", id: "how-it-works" },
|
||||
{ name: "Reviews", id: "reviews" },
|
||||
{ name: "Contact", id: "contact" }
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="menu" data-section="menu">
|
||||
<ProductCardFour
|
||||
title="Our Complete Menu"
|
||||
description="Browse our full selection of authentic Chinese dishes, carefully prepared with the finest ingredients."
|
||||
tag="Menu"
|
||||
tagIcon={Package}
|
||||
textboxLayout="default"
|
||||
products={[
|
||||
{
|
||||
id: "1", name: "Kung Pao Chicken", price: "$12.99", variant: "Tender Chicken with Cashews", imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3ArAeZdkmaiH7QZEdHRplvV2gS5/uploaded-1773341150763-pi70hoij.jpg", imageAlt: "Kung Pao Chicken"
|
||||
},
|
||||
{
|
||||
id: "2", name: "Egg Fried Rice", price: "$8.99", variant: "Jasmine Rice with Eggs & Vegetables", imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3ArAeZdkmaiH7QZEdHRplvV2gS5/uploaded-1773341150763-d54tflwh.jpg", imageAlt: "Egg Fried Rice"
|
||||
},
|
||||
{
|
||||
id: "3", name: "Steamed Dumplings", price: "$9.99", variant: "Pork & Vegetable - 6 pieces", imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3ArAeZdkmaiH7QZEdHRplvV2gS5/uploaded-1773341150763-zpox5ebq.jpg", imageAlt: "Steamed Dumplings"
|
||||
},
|
||||
{
|
||||
id: "4", name: "Kung Pao Chicken", price: "$12.99", variant: "Tender Chicken with Cashews", imageSrc: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3ArAeZdkmaiH7QZEdHRplvV2gS5/uploaded-1773341150763-pi70hoij.jpg", imageAlt: "Kung Pao Chicken"
|
||||
}
|
||||
]}
|
||||
gridVariant="uniform-all-items-equal"
|
||||
animationType="slide-up"
|
||||
useInvertedBackground={false}
|
||||
ariaLabel="Product menu section"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="footer" data-section="footer">
|
||||
<FooterLogoReveal
|
||||
logoText="Kings Garden"
|
||||
leftLink={{ text: "Privacy Policy", href: "#" }}
|
||||
rightLink={{ text: "Terms of Service", href: "#" }}
|
||||
ariaLabel="Site footer"
|
||||
/>
|
||||
</div>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user