Update src/app/page.tsx

This commit is contained in:
2026-03-21 23:31:28 +00:00
parent 1088f47c1e
commit db72b9c9c7

View File

@@ -9,13 +9,16 @@ import TestimonialCardSix from '@/components/sections/testimonial/TestimonialCar
import FeatureCardNine from '@/components/sections/feature/FeatureCardNine';
import ContactSplitForm from '@/components/sections/contact/ContactSplitForm';
import FooterLogoEmphasis from '@/components/sections/footer/FooterLogoEmphasis';
import { Award, Sparkles, Users, Star } from "lucide-react";
import { Award, Sparkles, Users, Star, ShoppingCart, Trash2, ArrowRight } from "lucide-react";
import { useState } from 'react';
import Link from 'next/link';
export default function LandingPage() {
const [formSubmitted, setFormSubmitted] = useState(false);
const [filterCategory, setFilterCategory] = useState('all');
const [reservation, setReservation] = useState(null);
const [cart, setCart] = useState([]);
const [showCart, setShowCart] = useState(false);
const handleFormSubmit = (data) => {
console.log('Form submitted:', data);
@@ -30,22 +33,97 @@ export default function LandingPage() {
};
const allProducts = [
// Pies Category
{
id: "bacon-egg", name: "Award-Winning Bacon & Egg", price: "Signature Pick", imageSrc: "http://img.b2bpic.net/free-photo/slice-roscon-de-reyes-epiphany-dessert_23-2148721499.jpg?_wi=1", imageAlt: "Bacon and egg pie with crispy golden pastry", category: "savory", onProductClick: () => console.log('Product clicked: Bacon & Egg')
id: "bacon-egg", name: "Award-Winning Bacon & Egg", price: "$8.50", imageSrc: "http://img.b2bpic.net/free-photo/slice-roscon-de-reyes-epiphany-dessert_23-2148721499.jpg?_wi=1", imageAlt: "Bacon and egg pie with crispy golden pastry", category: "pies", onProductClick: () => console.log('Product clicked: Bacon & Egg'),
onQuantityChange: (qty) => handleAddToCart({ id: "bacon-egg", name: "Award-Winning Bacon & Egg", price: "$8.50", quantity: qty })
},
{
id: "beef-cheek", name: "Beef Cheek, Jalapeño & Cheddar", price: "Customer Favorite", imageSrc: "http://img.b2bpic.net/free-photo/bride-groom-salt-broken-piece-wedding-loaf_501050-105.jpg?_wi=1", imageAlt: "Beef cheek jalapeño and cheddar artisan pie", category: "savory", onProductClick: () => console.log('Product clicked: Beef Cheek')
id: "beef-cheek", name: "Beef Cheek, Jalapeño & Cheddar", price: "$9.00", imageSrc: "http://img.b2bpic.net/free-photo/bride-groom-salt-broken-piece-wedding-loaf_501050-105.jpg?_wi=1", imageAlt: "Beef cheek jalapeño and cheddar artisan pie", category: "pies", onProductClick: () => console.log('Product clicked: Beef Cheek'),
onQuantityChange: (qty) => handleAddToCart({ id: "beef-cheek", name: "Beef Cheek, Jalapeño & Cheddar", price: "$9.00", quantity: qty })
},
{
id: "steak-cheese", name: "Steak & Cheese", price: "Best Seller", imageSrc: "http://img.b2bpic.net/free-photo/flat-lay-pumpkin-pie-thanksgiving_23-2148686219.jpg?_wi=1", imageAlt: "Steak and cheese pie with chunky beef and gravy", category: "savory", onProductClick: () => console.log('Product clicked: Steak & Cheese')
id: "steak-cheese", name: "Steak & Cheese", price: "$8.75", imageSrc: "http://img.b2bpic.net/free-photo/flat-lay-pumpkin-pie-thanksgiving_23-2148686219.jpg?_wi=1", imageAlt: "Steak and cheese pie with chunky beef and gravy", category: "pies", onProductClick: () => console.log('Product clicked: Steak & Cheese'),
onQuantityChange: (qty) => handleAddToCart({ id: "steak-cheese", name: "Steak & Cheese", price: "$8.75", quantity: qty })
},
// Sausage Rolls Category
{
id: "pork-sausage", name: "Pork Sausage Roll", price: "$5.50", imageSrc: "http://img.b2bpic.net/free-photo/slice-roscon-de-reyes-epiphany-dessert_23-2148721499.jpg?_wi=1", imageAlt: "Golden pork sausage roll", category: "sausage-rolls", onProductClick: () => console.log('Product clicked: Pork Sausage Roll'),
onQuantityChange: (qty) => handleAddToCart({ id: "pork-sausage", name: "Pork Sausage Roll", price: "$5.50", quantity: qty })
},
{
id: "sweet-selection", name: "Sweet Cabinet Selection", price: "Worth adding on", imageSrc: "http://img.b2bpic.net/free-photo/dessert-catering_1203-2828.jpg?_wi=1", imageAlt: "Assorted artisan donuts, croissants, and tarts", category: "sweet", onProductClick: () => console.log('Product clicked: Sweet Selection')
id: "chorizo-cheese", name: "Chorizo & Cheese Roll", price: "$6.00", imageSrc: "http://img.b2bpic.net/free-photo/bride-groom-salt-broken-piece-wedding-loaf_501050-105.jpg?_wi=1", imageAlt: "Spicy chorizo and cheese sausage roll", category: "sausage-rolls", onProductClick: () => console.log('Product clicked: Chorizo & Cheese Roll'),
onQuantityChange: (qty) => handleAddToCart({ id: "chorizo-cheese", name: "Chorizo & Cheese Roll", price: "$6.00", quantity: qty })
},
// Sweet Treats Category
{
id: "sweet-cabinet", name: "Sweet Cabinet Selection", price: "$4.50-7.00", imageSrc: "http://img.b2bpic.net/free-photo/dessert-catering_1203-2828.jpg?_wi=1", imageAlt: "Assorted artisan donuts, croissants, and tarts", category: "sweet-treats", onProductClick: () => console.log('Product clicked: Sweet Selection'),
onQuantityChange: (qty) => handleAddToCart({ id: "sweet-cabinet", name: "Sweet Cabinet Selection", price: "$4.50-7.00", quantity: qty })
},
{
id: "chocolate-eclair", name: "Chocolate Éclair", price: "$6.50", imageSrc: "http://img.b2bpic.net/free-photo/flat-lay-pumpkin-pie-thanksgiving_23-2148686219.jpg?_wi=1", imageAlt: "Classic chocolate éclair with premium filling", category: "sweet-treats", onProductClick: () => console.log('Product clicked: Chocolate Éclair'),
onQuantityChange: (qty) => handleAddToCart({ id: "chocolate-eclair", name: "Chocolate Éclair", price: "$6.50", quantity: qty })
},
// Bread Category
{
id: "sourdough", name: "Artisan Sourdough", price: "$6.00", imageSrc: "http://img.b2bpic.net/free-photo/bride-groom-salt-broken-piece-wedding-loaf_501050-105.jpg?_wi=1", imageAlt: "Crusty artisan sourdough loaf", category: "bread", onProductClick: () => console.log('Product clicked: Sourdough'),
onQuantityChange: (qty) => handleAddToCart({ id: "sourdough", name: "Artisan Sourdough", price: "$6.00", quantity: qty })
},
{
id: "focaccia", name: "Rosemary Focaccia", price: "$5.50", imageSrc: "http://img.b2bpic.net/free-photo/slice-roscon-de-reyes-epiphany-dessert_23-2148721499.jpg?_wi=1", imageAlt: "Herb-infused focaccia with olive oil", category: "bread", onProductClick: () => console.log('Product clicked: Focaccia'),
onQuantityChange: (qty) => handleAddToCart({ id: "focaccia", name: "Rosemary Focaccia", price: "$5.50", quantity: qty })
},
// Sandwiches Category
{
id: "roasted-veg", name: "Roasted Vegetable & Hummus", price: "$9.50", imageSrc: "http://img.b2bpic.net/free-photo/dessert-catering_1203-2828.jpg?_wi=1", imageAlt: "Fresh roasted vegetable sandwich", category: "sandwiches", onProductClick: () => console.log('Product clicked: Roasted Veg'),
onQuantityChange: (qty) => handleAddToCart({ id: "roasted-veg", name: "Roasted Vegetable & Hummus", price: "$9.50", quantity: qty })
},
{
id: "bacon-tomato", name: "Bacon & Tomato Club", price: "$11.00", imageSrc: "http://img.b2bpic.net/free-photo/flat-lay-pumpkin-pie-thanksgiving_23-2148686219.jpg?_wi=1", imageAlt: "Loaded bacon and tomato club sandwich", category: "sandwiches", onProductClick: () => console.log('Product clicked: Bacon Tomato'),
onQuantityChange: (qty) => handleAddToCart({ id: "bacon-tomato", name: "Bacon & Tomato Club", price: "$11.00", quantity: qty })
},
// Coffee Category
{
id: "flat-white", name: "Flat White", price: "$5.00", imageSrc: "http://img.b2bpic.net/free-photo/medium-shot-woman-working-bakery_23-2150273180.jpg?_wi=1", imageAlt: "Smooth flat white coffee", category: "coffee", onProductClick: () => console.log('Product clicked: Flat White'),
onQuantityChange: (qty) => handleAddToCart({ id: "flat-white", name: "Flat White", price: "$5.00", quantity: qty })
},
{
id: "cappuccino", name: "Cappuccino", price: "$5.00", imageSrc: "http://img.b2bpic.net/free-photo/close-up-pastry-chef-preparing-food_23-2149038998.jpg?_wi=1", imageAlt: "Rich cappuccino with premium crema", category: "coffee", onProductClick: () => console.log('Product clicked: Cappuccino'),
onQuantityChange: (qty) => handleAddToCart({ id: "cappuccino", name: "Cappuccino", price: "$5.00", quantity: qty })
}
];
const filteredProducts = filterCategory === 'all'
? allProducts
const handleAddToCart = (item) => {
setCart(prevCart => {
const existingItem = prevCart.find(cartItem => cartItem.id === item.id);
if (existingItem) {
return prevCart.map(cartItem =>
cartItem.id === item.id
? { ...cartItem, quantity: item.quantity }
: cartItem
);
}
return [...prevCart, item];
});
};
const handleRemoveFromCart = (itemId) => {
setCart(prevCart => prevCart.filter(item => item.id !== itemId));
};
const handleCheckout = () => {
if (cart.length === 0) return;
// Navigate to checkout page
window.location.href = '/checkout';
};
const cartTotal = cart.reduce((total, item) => {
const price = parseFloat(item.price.replace('$', '').split('-')[0]);
return total + (price * (item.quantity || 1));
}, 0);
const filteredProducts = filterCategory === 'all'
? allProducts
: allProducts.filter(p => p.category === filterCategory);
return (
@@ -65,12 +143,62 @@ export default function LandingPage() {
<NavbarStyleApple
brandName="Levain"
navItems={[
{ name: "Signature", id: "signature" },
{ name: "Menu", id: "menu" },
{ name: "Why Levain", id: "why-levain" },
{ name: "Reviews", id: "reviews" },
{ name: "Visit", id: "visit" }
]}
/>
{/* Cart Indicator */}
<div className="fixed top-20 right-4 z-40">
<button
onClick={() => setShowCart(!showCart)}
className="relative bg-primary-cta text-white p-3 rounded-full shadow-lg hover:shadow-xl transition-all"
aria-label="Shopping cart"
>
<ShoppingCart size={24} />
{cart.length > 0 && (
<span className="absolute -top-2 -right-2 bg-red-500 text-white text-xs rounded-full w-6 h-6 flex items-center justify-center">
{cart.length}
</span>
)}
</button>
{showCart && cart.length > 0 && (
<div className="absolute right-0 mt-2 w-72 bg-white dark:bg-gray-900 rounded-lg shadow-2xl p-4 border border-gray-200 dark:border-gray-700">
<h3 className="font-bold text-lg mb-4 text-foreground">Shopping Cart</h3>
<div className="space-y-2 max-h-64 overflow-y-auto">
{cart.map(item => (
<div key={item.id} className="flex justify-between items-center p-2 bg-card rounded border border-gray-100 dark:border-gray-800">
<div className="flex-1">
<p className="font-medium text-sm text-foreground">{item.name}</p>
<p className="text-xs text-gray-600 dark:text-gray-400">Qty: {item.quantity || 1} × {item.price}</p>
</div>
<button
onClick={() => handleRemoveFromCart(item.id)}
className="text-red-500 hover:text-red-700 transition-colors"
aria-label={`Remove ${item.name} from cart`}
>
<Trash2 size={16} />
</button>
</div>
))}
</div>
<div className="mt-4 pt-4 border-t border-gray-200 dark:border-gray-700">
<div className="flex justify-between items-center font-bold text-lg mb-4 text-foreground">
<span>Total:</span>
<span className="text-primary-cta">${cartTotal.toFixed(2)}</span>
</div>
<button
onClick={handleCheckout}
className="w-full bg-primary-cta text-white py-2 rounded-lg font-semibold hover:opacity-90 transition-opacity flex items-center justify-center gap-2"
aria-label="Proceed to checkout"
>
Checkout <ArrowRight size={16} />
</button>
</div>
</div>
)}
</div>
</div>
<div id="hero" data-section="hero">
@@ -78,7 +206,7 @@ export default function LandingPage() {
logoText="Auckland's most talked-about artisan bakery experience."
description="Levain brings elevated bakery craft to everyday cravings — crisp golden pastry, generous fillings, sweet cabinet favourites, fast friendly service, and a reputation people happily drive across town for."
buttons={[
{ text: "Order Fresh Pies Now", href: "#signature" },
{ text: "Order Fresh Pies Now", href: "#menu" },
{ text: "See Hours & Location", href: "#visit" }
]}
imageSrc="http://img.b2bpic.net/free-photo/medium-shot-woman-working-bakery_23-2150273180.jpg?_wi=1"
@@ -88,40 +216,56 @@ export default function LandingPage() {
/>
</div>
<div id="signature" data-section="signature">
<div className="mb-8 flex gap-4 justify-center">
<div id="menu" data-section="menu">
<div className="mb-8 flex gap-4 justify-center flex-wrap">
<button
onClick={() => setFilterCategory('all')}
className={`px-4 py-2 rounded-full transition-all ${
filterCategory === 'all'
? 'bg-primary-cta text-white'
: 'bg-card text-foreground border border-gray-300'
}`}
className={`px-4 py-2 rounded-full transition-all ${filterCategory === 'all' ? 'bg-primary-cta text-white' : 'bg-card text-foreground border border-gray-300 dark:border-gray-700'}`}
aria-label="Show all products"
>
All Items
</button>
<button
onClick={() => setFilterCategory('savory')}
className={`px-4 py-2 rounded-full transition-all ${
filterCategory === 'savory'
? 'bg-primary-cta text-white'
: 'bg-card text-foreground border border-gray-300'
}`}
aria-label="Show savory products"
onClick={() => setFilterCategory('pies')}
className={`px-4 py-2 rounded-full transition-all ${filterCategory === 'pies' ? 'bg-primary-cta text-white' : 'bg-card text-foreground border border-gray-300 dark:border-gray-700'}`}
aria-label="Show pies"
>
Savory
Pies
</button>
<button
onClick={() => setFilterCategory('sweet')}
className={`px-4 py-2 rounded-full transition-all ${
filterCategory === 'sweet'
? 'bg-primary-cta text-white'
: 'bg-card text-foreground border border-gray-300'
}`}
aria-label="Show sweet products"
onClick={() => setFilterCategory('sausage-rolls')}
className={`px-4 py-2 rounded-full transition-all ${filterCategory === 'sausage-rolls' ? 'bg-primary-cta text-white' : 'bg-card text-foreground border border-gray-300 dark:border-gray-700'}`}
aria-label="Show sausage rolls"
>
Sweet
Sausage Rolls
</button>
<button
onClick={() => setFilterCategory('sweet-treats')}
className={`px-4 py-2 rounded-full transition-all ${filterCategory === 'sweet-treats' ? 'bg-primary-cta text-white' : 'bg-card text-foreground border border-gray-300 dark:border-gray-700'}`}
aria-label="Show sweet treats"
>
Sweet Treats
</button>
<button
onClick={() => setFilterCategory('bread')}
className={`px-4 py-2 rounded-full transition-all ${filterCategory === 'bread' ? 'bg-primary-cta text-white' : 'bg-card text-foreground border border-gray-300 dark:border-gray-700'}`}
aria-label="Show bread"
>
Bread
</button>
<button
onClick={() => setFilterCategory('sandwiches')}
className={`px-4 py-2 rounded-full transition-all ${filterCategory === 'sandwiches' ? 'bg-primary-cta text-white' : 'bg-card text-foreground border border-gray-300 dark:border-gray-700'}`}
aria-label="Show sandwiches"
>
Sandwiches
</button>
<button
onClick={() => setFilterCategory('coffee')}
className={`px-4 py-2 rounded-full transition-all ${filterCategory === 'coffee' ? 'bg-primary-cta text-white' : 'bg-card text-foreground border border-gray-300 dark:border-gray-700'}`}
aria-label="Show coffee"
>
Coffee
</button>
</div>
<ProductCardThree
@@ -134,7 +278,7 @@ export default function LandingPage() {
gridVariant="two-columns-alternating-heights"
animationType="slide-up"
buttons={[
{ text: "View Full Menu", href: "#signature" }
{ text: "View Full Menu", href: "#menu" }
]}
products={filteredProducts}
/>
@@ -201,7 +345,7 @@ export default function LandingPage() {
tag="Primary call to action"
tagAnimation="blur-reveal"
buttons={[
{ text: "See Today's Favourites", href: "#signature" },
{ text: "See Today's Favourites", href: "#menu" },
{ text: "Get Directions", href: "#visit" }
]}
buttonAnimation="slide-up"
@@ -265,27 +409,44 @@ export default function LandingPage() {
{
items: [
{ label: "About", href: "#why-levain" },
{ label: "Menu", href: "#signature" },
{ label: "Menu", href: "#menu" },
{ label: "Testimonials", href: "#reviews" }
]
},
{
items: [
{ label: "Visit", href: "#visit" },
{ label: "Instagram", href: "#" },
{ label: "Instagram", href: "https://instagram.com" },
{ label: "Contact", href: "#visit" }
]
},
{
items: [
{ label: "Privacy Policy", href: "#" },
{ label: "Terms of Service", href: "#" },
{ label: "Accessibility", href: "#" }
{ label: "Privacy Policy", href: "/privacy" },
{ label: "Terms of Service", href: "/terms" },
{ label: "Accessibility", href: "/accessibility" }
]
}
]}
ariaLabel="Levain bakery site footer"
/>
{/* Premium Footer CTA */}
<div className="bg-gradient-to-r from-primary-cta to-accent text-white py-12 px-6 text-center mt-8">
<h2 className="text-3xl font-bold mb-4">Join our community of Levain lovers.</h2>
<p className="text-lg mb-6 opacity-95">Fresh, handcrafted pies delivered to your inbox. New flavors, special offers, and stories from our Auckland kitchen.</p>
<div className="flex gap-4 justify-center flex-wrap">
<input
type="email"
placeholder="Your email address"
className="px-6 py-3 rounded-full text-foreground placeholder-gray-500 flex-1 max-w-sm focus:outline-none focus:ring-2 focus:ring-white"
aria-label="Email for newsletter signup"
/>
<button className="px-8 py-3 bg-white text-primary-cta rounded-full font-semibold hover:opacity-90 transition-opacity" aria-label="Subscribe to newsletter">
Subscribe
</button>
</div>
<p className="text-sm mt-6 opacity-75">We respect your inbox. Unsubscribe anytime.</p>
</div>
</div>
</ThemeProvider>
);