Skip to content

crumble cookie #142

Description

@zwgjh7mmgs-cpu

import React, { useState, useEffect, createContext, useContext } from 'react';
import {
ShoppingBag, Menu, X, Star, ChevronRight, ChevronDown,
MapPin, Clock, Phone, Mail, Instagram, Facebook,
Check, ArrowRight, Heart, Sparkles, Plus, Minus, Trash2
} from 'lucide-react';

// --- CONTEXT & STATE MANAGEMENT ---
const CartContext = createContext();

const CartProvider = ({ children }) => {
const [cart, setCart] = useState([]);
const [isCartOpen, setIsCartOpen] = useState(false);

const addToCart = (product, quantity = 1) => {
setCart(prev => {
const existing = prev.find(item => item.id === product.id);
if (existing) {
return prev.map(item =>
item.id === product.id ? { ...item, quantity: item.quantity + quantity } : item
);
}
return [...prev, { ...product, quantity }];
});
setIsCartOpen(true);
};

const removeFromCart = (id) => {
setCart(prev => prev.filter(item => item.id !== id));
};

const updateQuantity = (id, delta) => {
setCart(prev => prev.map(item => {
if (item.id === id) {
const newQty = item.quantity + delta;
return newQty > 0 ? { ...item, quantity: newQty } : item;
}
return item;
}));
};

const totalItems = cart.reduce((sum, item) => sum + item.quantity, 0);
const subtotal = cart.reduce((sum, item) => sum + (item.price * item.quantity), 0);

return (
<CartContext.Provider value={{
cart, addToCart, removeFromCart, updateQuantity,
isCartOpen, setIsCartOpen, totalItems, subtotal
}}>
{children}
</CartContext.Provider>
);
};

const useCart = () => useContext(CartContext);

// --- MOCK DATA ---
const PRODUCTS = [
{
id: 'c1',
name: 'Classic Chocolate Chunk',
tagline: 'Gooey perfection in every bite',
price: 3.99,
category: 'Classic',
rating: 4.9,
reviews: 328,
description: 'Thick, buttery dough loaded with oversized chunks of semi-sweet belgian chocolate, baked until gold on the outside and warm and molten inside.',
allergens: ['Milk', 'Eggs', 'Wheat', 'Soy'],
calories: '480 kcal',
image: 'https://images.unsplash.com/photo-1499636136210-6f4ee915583e?auto=format&fit=crop&q=80&w=600',
popular: true
},
{
id: 'c2',
name: 'Biscoff Butter Crumble',
tagline: 'Warm spiced speculoos bliss',
price: 4.50,
category: 'Stuffed',
rating: 5.0,
reviews: 215,
description: 'Spiced cookie dough filled with a molten cookie butter core, topped with crushed Biscoff cookies and a caramelized drizzle.',
allergens: ['Milk', 'Eggs', 'Wheat', 'Soy'],
calories: '520 kcal',
popular: true
},
{
id: 'c3',
name: 'Birthday Cake Swirl',
tagline: 'Celebration wrapped in sugar',
price: 4.25,
category: 'Classic',
rating: 4.8,
reviews: 184,
description: 'Rich vanilla cake batter dough folded with colorful rainbow sprinkles, stuffed with sweet cream cheese frosting and topped with cake crumbs.',
allergens: ['Milk', 'Eggs', 'Wheat'],
calories: '460 kcal',
popular: false
},
{
id: 'c4',
name: 'Campfire S’mores Overload',
tagline: 'Toasted gooey marshmallow dream',
price: 4.75,
category: 'Stuffed',
rating: 4.9,
reviews: 412,
description: 'Graham cracker enriched dough packed with milk chocolate chunks, stuffed with a giant gooey marshmallow, and flame-torched on top.',
allergens: ['Milk', 'Eggs', 'Wheat', 'Soy'],
calories: '510 kcal',
popular: true
},
{
id: 'c5',
name: 'Red Velvet Cream Cheese',
tagline: 'Decadent, velvet smooth perfection',
price: 4.50,
category: 'Stuffed',
rating: 4.7,
reviews: 156,
description: 'Deep cocoa red velvet dough baked warm with a silky vanilla cream cheese center and sprinkled with dark chocolate chips.',
allergens: ['Milk', 'Eggs', 'Wheat'],
calories: '490 kcal',
popular: false
},
{
id: 'c6',
name: 'Peanut Butter Lava',
tagline: 'Rich, nutty, and irresistibly gooey',
price: 4.25,
category: 'Stuffed',
rating: 4.9,
reviews: 290,
description: 'Salted peanut butter dough overflowing with a molten peanut butter fudge center and finished with crushed roasted peanuts.',
allergens: ['Peanuts', 'Milk', 'Eggs', 'Wheat'],
calories: '540 kcal',
popular: true
},
{
id: 'c7',
name: 'Plant-Based Dark Choc Fudge',
tagline: '100% Vegan, 100% Indulgent',
price: 4.50,
category: 'Vegan',
rating: 4.8,
reviews: 98,
description: 'Rich, fudgy chocolate dough mixed with 70% dark chocolate chunks and sea salt flakes. Absolutely zero animal products, maximum decadence.',
allergens: ['Wheat', 'Soy'],
calories: '430 kcal',
popular: false
},
{
id: 'c8',
name: 'Gluten-Free Cinnamon Roll',
tagline: 'Warm cinnamon swirl goodness',
price: 4.75,
category: 'Gluten-Free',
rating: 4.6,
reviews: 87,
description: 'Crafted with almond and oat flour, swirled with brown sugar and cinnamon, drizzled with sweet cream glaze.',
allergens: ['Milk', 'Eggs', 'Tree Nuts (Almond)'],
calories: '410 kcal',
popular: false
}
];

const TESTIMONIALS = [
{
id: 1,
name: 'Sarah Jenkins',
role: 'Cookie Enthusiast',
quote: 'The Biscoff Butter Crumble literally melted my heart. You haven’t lived until you eat one of these warm!',
rating: 5,
avatar: 'https://images.unsplash.com/photo-1494790108377-be9c29b29330?auto=format&fit=crop&q=80&w=150'
},
{
id: 2,
name: 'Marcus Chen',
role: 'Food Blogger',
quote: 'Crispy outer shell, thick and gooey inside. Crumble Cookie sets the gold standard for artisanal treats.',
rating: 5,
avatar: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?auto=format&fit=crop&q=80&w=150'
},
{
id: 3,
name: 'Emily Watson',
role: 'Event Coordinator',
quote: 'We ordered 200 custom cookies for a corporate event. They arrived warm, fresh, and were gone in 10 minutes!',
rating: 5,
avatar: 'https://images.unsplash.com/photo-1534528741775-53994a69daeb?auto=format&fit=crop&q=80&w=150'
}
];

const LOCATIONS = [
{
city: 'Downtown Flagship',
address: '452 Sweet Briar Lane, Suite 100',
hours: 'Mon-Sun: 8am - 10pm',
phone: '(555) 234-5678'
},
{
city: 'Uptown Bakery & Cafe',
address: '881 Gourmet Boulevard',
hours: 'Mon-Sun: 7am - 11pm',
phone: '(555) 876-5432'
}
];

const FAQS = [
{
q: 'How should I reheat my cookies?',
a: 'For that fresh-out-of-the-oven experience, pop your cookie in a preheated oven at 350°F (175°C) for 3 to 5 minutes, or microwave for 10-12 seconds!'
},
{
q: 'Do you offer gluten-free and vegan options?',
a: 'Yes! We always have at least one dedicated Vegan and one Gluten-Free flavor on our menu. They are baked using strict separation procedures, though processed in a facility that handles gluten.'
},
{
q: 'How long do the cookies stay fresh?',
a: 'Our cookies stay soft and fresh for up to 5 days in an airtight container at room temperature. You can also freeze them for up to 3 months!'
},
{
q: 'How far in advance should I place catering orders?',
a: 'For small event boxes (2-4 dozen), 24-hour notice is appreciated. For large events or custom orders, please contact us at least 5 business days in advance.'
}
];

// --- NAVIGATION COMPONENT ---
const Navbar = ({ activeTab, setActiveTab }) => {
const [isScrolled, setIsScrolled] = useState(false);
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
const { totalItems, setIsCartOpen } = useCart();

useEffect(() => {
const handleScroll = () => {
setIsScrolled(window.scrollY > 20);
};
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);

const navLinks = [
{ name: 'Home', id: 'home' },
{ name: 'Menu', id: 'menu' },
{ name: 'About Us', id: 'about' },
{ name: 'Locations', id: 'locations' },
{ name: 'Catering', id: 'catering' },
{ name: 'FAQ', id: 'faq' },
{ name: 'Contact', id: 'contact' }
];

const handleNavClick = (id) => {
setActiveTab(id);
setMobileMenuOpen(false);
window.scrollTo({ top: 0, behavior: 'smooth' });
};

return (
<nav className={fixed top-0 left-0 right-0 z-40 transition-all duration-300 ${ isScrolled ? 'bg-[#FFF8EC]/95 backdrop-blur-md shadow-md py-3' : 'bg-transparent py-5' }}>

    {/* Brand Logo */}
    <button 
      onClick={() => handleNavClick('home')} 
      className="flex items-center gap-2 group text-left focus:outline-none"
    >
      <div className="w-10 h-10 rounded-full bg-[#E8A857] flex items-center justify-center text-[#3D2817] font-bold text-xl shadow-inner group-hover:scale-105 transition-transform">
        🍪
      </div>
      <div>
        <span className="text-2xl font-black tracking-tight text-[#3D2817] block leading-none font-[#Fredoka]">
          Crumble
        </span>
        <span className="text-xs uppercase tracking-widest text-[#8B5A2B] font-bold">
          Cookie Co.
        </span>
      </div>
    </button>

    {/* Desktop Navigation Links */}
    <div className="hidden md:flex items-center space-x-8">
      {navLinks.map(link => (
        <button
          key={link.id}
          onClick={() => handleNavClick(link.id)}
          className={`text-sm font-bold tracking-wide transition-colors hover:text-[#8B5A2B] ${
            activeTab === link.id ? 'text-[#8B5A2B] border-b-2 border-[#E8A857] pb-1' : 'text-[#3D2817]/80'
          }`}
        >
          {link.name}
        </button>
      ))}
    </div>

    {/* Right CTA / Cart */}
    <div className="hidden md:flex items-center space-x-4">
      <button
        onClick={() => setIsCartOpen(true)}
        className="relative p-2 text-[#3D2817] hover:text-[#8B5A2B] transition-colors focus:outline-none"
        aria-label="Shopping Cart"
      >
        <ShoppingBag className="w-6 h-6" />
        {totalItems > 0 && (
          <span className="absolute -top-1 -right-1 bg-[#8B5A2B] text-white text-xs font-bold rounded-full w-5 h-5 flex items-center justify-center shadow">
            {totalItems}
          </span>
        )}
      </button>

      <button
        onClick={() => handleNavClick('menu')}
        className="bg-[#E8A857] hover:bg-[#d99746] text-[#3D2817] px-5 py-2.5 rounded-full font-bold text-sm transition-all transform hover:-translate-y-0.5 shadow-md"
      >
        Order Fresh Now
      </button>
    </div>

    {/* Mobile Hamburger Button */}
    <div className="flex md:hidden items-center space-x-3">
      <button
        onClick={() => setIsCartOpen(true)}
        className="relative p-2 text-[#3D2817]"
      >
        <ShoppingBag className="w-6 h-6" />
        {totalItems > 0 && (
          <span className="absolute -top-1 -right-1 bg-[#8B5A2B] text-white text-xs font-bold rounded-full w-5 h-5 flex items-center justify-center">
            {totalItems}
          </span>
        )}
      </button>
      <button
        onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
        className="p-2 text-[#3D2817] focus:outline-none"
      >
        {mobileMenuOpen ? <X className="w-7 h-7" /> : <Menu className="w-7 h-7" />}
      </button>
    </div>
  </div>

  {/* Mobile Drawer */}
  {mobileMenuOpen && (
    <div className="md:hidden bg-[#FFF8EC] border-b border-[#8B5A2B]/10 px-4 pt-2 pb-6 space-y-3 shadow-lg animate-fadeIn">
      {navLinks.map(link => (
        <button
          key={link.id}
          onClick={() => handleNavClick(link.id)}
          className={`block w-full text-left px-3 py-2 rounded-lg text-base font-bold ${
            activeTab === link.id ? 'bg-[#E8A857]/20 text-[#8B5A2B]' : 'text-[#3D2817]'
          }`}
        >
          {link.name}
        </button>
      ))}
      <button
        onClick={() => handleNavClick('menu')}
        className="w-full mt-4 bg-[#E8A857] text-[#3D2817] py-3 rounded-full font-bold text-center shadow"
      >
        Order Fresh Now
      </button>
    </div>
  )}
</nav>

);
};

// --- CART DRAWER COMPONENT ---
const CartDrawer = () => {
const { cart, isCartOpen, setIsCartOpen, removeFromCart, updateQuantity, subtotal } = useCart();

if (!isCartOpen) return null;

return (


<div
className="absolute inset-0 bg-black/40 backdrop-blur-sm transition-opacity"
onClick={() => setIsCartOpen(false)}
/>

  <div className="fixed inset-y-0 right-0 max-w-full flex pl-10">
    <div className="w-screen max-w-md bg-[#FFF8EC] shadow-2xl flex flex-col">
      
      {/* Header */}
      <div className="p-6 bg-[#3D2817] text-[#FFF8EC] flex items-center justify-between">
        <div className="flex items-center gap-2">
          <ShoppingBag className="w-5 h-5 text-[#E8A857]" />
          <h2 className="text-xl font-bold tracking-wide">Your Fresh Box</h2>
        </div>
        <button 
          onClick={() => setIsCartOpen(false)}
          className="p-1 hover:bg-white/10 rounded-full transition-colors"
        >
          <X className="w-6 h-6" />
        </button>
      </div>

      {/* Cart Items List */}
      <div className="flex-1 overflow-y-auto p-6 space-y-4">
        {cart.length === 0 ? (
          <div className="text-center py-16">
            <div className="text-6xl mb-4">🍪</div>
            <h3 className="text-lg font-bold text-[#3D2817]">Your box is currently empty</h3>
            <p className="text-sm text-[#8B5A2B] mt-1">Fill it up with warm, gooey goodness!</p>
          </div>
        ) : (
          cart.map(item => (
            <div key={item.id} className="flex gap-4 p-3 bg-white rounded-2xl shadow-sm border border-[#8B5A2B]/10 items-center">
              <img 
                src={item.image} 
                alt={item.name} 
                className="w-20 h-20 object-cover rounded-xl flex-shrink-0"
              />
              <div className="flex-1 min-w-0">
                <h4 className="font-bold text-[#3D2817] text-sm truncate">{item.name}</h4>
                <p className="text-xs text-[#8B5A2B] font-semibold">${item.price.toFixed(2)} each</p>
                
                <div className="flex items-center gap-3 mt-2">
                  <div className="flex items-center border border-gray-200 rounded-lg bg-[#FFF8EC]">
                    <button 
                      onClick={() => updateQuantity(item.id, -1)}
                      className="p-1 text-[#3D2817] hover:text-[#8B5A2B]"
                    >
                      <Minus className="w-3.5 h-3.5" />
                    </button>
                    <span className="px-2 text-xs font-bold text-[#3D2817]">{item.quantity}</span>
                    <button 
                      onClick={() => updateQuantity(item.id, 1)}
                      className="p-1 text-[#3D2817] hover:text-[#8B5A2B]"
                    >
                      <Plus className="w-3.5 h-3.5" />
                    </button>
                  </div>
                  <button 
                    onClick={() => removeFromCart(item.id)}
                    className="text-red-400 hover:text-red-600 p-1"
                  >
                    <Trash2 className="w-4 h-4" />
                  </button>
                </div>
              </div>
              <div className="text-right font-bold text-[#3D2817] text-sm">
                ${(item.price * item.quantity).toFixed(2)}
              </div>
            </div>
          ))
        )}
      </div>

      {/* Footer Checkout Info */}
      {cart.length > 0 && (
        <div className="p-6 bg-white border-t border-[#8B5A2B]/10 space-y-4">
          <div className="space-y-1.5 text-sm">
            <div className="flex justify-between text-gray-600">
              <span>Subtotal</span>
              <span className="font-semibold text-[#3D2817]">${subtotal.toFixed(2)}</span>
            </div>
            <div className="flex justify-between text-gray-600">
              <span>Estimated Taxes & Shipping</span>
              <span className="font-semibold text-[#3D2817]">$4.99</span>
            </div>
            <div className="flex justify-between text-base font-black text-[#3D2817] pt-2 border-t">
              <span>Total</span>
              <span className="text-[#8B5A2B]">${(subtotal + 4.99).toFixed(2)}</span>
            </div>
          </div>

          <button 
            onClick={() => alert("Mock Checkout Complete! Your cookies will be baked fresh!")}
            className="w-full bg-[#E8A857] hover:bg-[#d99746] text-[#3D2817] font-extrabold py-3.5 rounded-full shadow-lg transition-transform transform active:scale-95 flex items-center justify-center gap-2"
          >
            Checkout Now
            <ArrowRight className="w-4 h-4" />
          </button>
        </div>
      )}

    </div>
  </div>
</div>

);
};

// --- PRODUCT CARD COMPONENT ---
const ProductCard = ({ product, onSelectProduct }) => {
const { addToCart } = useCart();

return (



<div
className="relative overflow-hidden rounded-2xl cursor-pointer aspect-square mb-4 bg-[#FFF8EC]"
onClick={() => onSelectProduct(product)}
>
{product.name}
{product.popular && (

Best Seller

)}

{product.category}

    <div className="flex items-center gap-1 mb-1 text-amber-500 text-xs font-bold">
      <Star className="w-3.5 h-3.5 fill-current" />
      <span>{product.rating}</span>
      <span className="text-gray-400 font-normal">({product.reviews})</span>
    </div>

    <h3 
      onClick={() => onSelectProduct(product)}
      className="font-black text-lg text-[#3D2817] cursor-pointer hover:text-[#8B5A2B] transition-colors leading-snug"
    >
      {product.name}
    </h3>
    <p className="text-xs text-[#8B5A2B] font-medium mt-1 line-clamp-2">
      {product.tagline}
    </p>
  </div>

  <div className="flex items-center justify-between mt-5 pt-3 border-t border-gray-100">
    <span className="text-lg font-black text-[#3D2817]">${product.price.toFixed(2)}</span>
    <button
      onClick={() => addToCart(product)}
      className="bg-[#FFF8EC] hover:bg-[#E8A857] text-[#3D2817] border border-[#E8A857] hover:border-transparent font-bold text-xs px-4 py-2 rounded-full transition-all flex items-center gap-1.5 shadow-sm"
    >
      <Plus className="w-3.5 h-3.5" />
      Add
    </button>
  </div>
</div>

);
};

// --- PAGES ---

// 1. HOME PAGE
const HomePage = ({ setActiveTab, onSelectProduct }) => {
const { addToCart } = useCart();

return (

  {/* HERO SECTION */}
  <section className="relative pt-32 pb-20 md:pt-40 md:pb-28 overflow-hidden bg-gradient-to-b from-[#FFF8EC] to-white">
    <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
      <div className="grid md:grid-cols-2 gap-12 items-center">
        
        <div className="space-y-6 text-center md:text-left">
          <span className="inline-flex items-center gap-2 bg-[#E8A857]/20 border border-[#E8A857]/40 text-[#8B5A2B] px-4 py-1.5 rounded-full text-xs font-bold uppercase tracking-widest">
            <Sparkles className="w-3.5 h-3.5" /> Baked Fresh Daily
          </span>
          <h1 className="text-4xl sm:text-6xl font-black text-[#3D2817] leading-none tracking-tight">
            Baked Thick. <br />
            Baked Fresh. <br />
            <span className="text-[#8B5A2B]">Baked to Crumble.</span>
          </h1>
          <p className="text-base sm:text-lg text-gray-600 max-w-lg mx-auto md:mx-0 font-medium">
            Gourmet oversized cookies baked warm all day long. Soft, melt-in-your-mouth centers with golden crispy edges.
          </p>
          
          <div className="flex flex-col sm:flex-row items-center justify-center md:justify-start gap-4 pt-2">
            <button 
              onClick={() => setActiveTab('menu')}
              className="w-full sm:w-auto bg-[#E8A857] hover:bg-[#d99746] text-[#3D2817] font-extrabold px-8 py-4 rounded-full shadow-lg hover:shadow-xl transition-all transform hover:-translate-y-1 text-center"
            >
              Order Warm Cookies
            </button>
            <button 
              onClick={() => setActiveTab('about')}
              className="w-full sm:w-auto border-2 border-[#8B5A2B] text-[#8B5A2B] hover:bg-[#8B5A2B] hover:text-white font-bold px-8 py-4 rounded-full transition-all text-center"
            >
              Our Story
            </button>
          </div>

          {/* Trust Badges */}
          <div className="pt-6 flex items-center justify-center md:justify-start gap-6 text-xs font-bold text-gray-500">
            <div className="flex items-center gap-1.5">
              <Check className="w-4 h-4 text-[#8B5A2B]" /> 100% Real Butter
            </div>
            <div className="flex items-center gap-1.5">
              <Check className="w-4 h-4 text-[#8B5A2B]" /> Zero Preservatives
            </div>
          </div>
        </div>

        {/* Hero Image / Visual */}
        <div className="relative">
          <div className="absolute -inset-4 bg-[#E8A857]/30 rounded-full blur-3xl -z-10" />
          <div className="relative rounded-3xl overflow-hidden shadow-2xl border-4 border-white transform rotate-2 hover:rotate-0 transition-transform duration-500">
            <img 
              src="https://images.unsplash.com/photo-1499636136210-6f4ee915583e?auto=format&fit=crop&q=80&w=800" 
              alt="Gooey warm chocolate chunk cookie pull" 
              className="w-full h-[400px] sm:h-[480px] object-cover"
            />
            <div className="absolute bottom-4 left-4 right-4 bg-white/90 backdrop-blur-md p-4 rounded-2xl shadow-lg flex items-center justify-between">
              <div>
                <p className="font-black text-[#3D2817] text-sm">Classic Chocolate Chunk</p>
                <p className="text-xs text-[#8B5A2B]">Molten Belgian dark chocolate</p>
              </div>
              <button 
                onClick={() => addToCart(PRODUCTS[0])}
                className="bg-[#8B5A2B] text-white px-3.5 py-2 rounded-xl text-xs font-bold hover:bg-[#3D2817] transition-colors"
              >
                Quick Add
              </button>
            </div>
          </div>
        </div>

      </div>
    </div>
  </section>

  {/* FEATURED FLAVORS CAROUSEL / GRID */}
  <section className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
    <div className="flex flex-col md:flex-row md:items-end justify-between mb-8">
      <div>
        <span className="text-xs font-bold text-[#8B5A2B] tracking-widest uppercase">Fresh From The Oven</span>
        <h2 className="text-3xl font-black text-[#3D2817] mt-1">This Week’s Lineup</h2>
      </div>
      <button 
        onClick={() => setActiveTab('menu')}
        className="mt-4 md:mt-0 text-[#8B5A2B] font-bold text-sm flex items-center gap-1 hover:gap-2 transition-all"
      >
        Explore All Flavors <ChevronRight className="w-4 h-4" />
      </button>
    </div>

    <div className="grid sm:grid-cols-2 lg:grid-cols-4 gap-6">
      {PRODUCTS.slice(0, 4).map(product => (
        <ProductCard key={product.id} product={product} onSelectProduct={onSelectProduct} />
      ))}
    </div>
  </section>

  {/* HOW IT WORKS */}
  <section className="bg-[#FFF8EC] py-16 border-y border-[#8B5A2B]/10">
    <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
      <span className="text-xs font-bold text-[#8B5A2B] tracking-widest uppercase">Simple & Sweet</span>
      <h2 className="text-3xl font-black text-[#3D2817] mt-1 mb-12">How To Get Your Crumble Fix</h2>

      <div className="grid md:grid-cols-3 gap-8">
        <div className="bg-white p-8 rounded-3xl shadow-sm space-y-3 relative">
          <div className="w-14 h-14 bg-[#E8A857]/20 text-[#8B5A2B] rounded-2xl font-black text-xl flex items-center justify-center mx-auto">
            1
          </div>
          <h3 className="font-bold text-lg text-[#3D2817]">Pick Your Flavors</h3>
          <p className="text-xs text-gray-600">Browse our weekly rotating lineup of warm classic and stuffed oversized cookies.</p>
        </div>

        <div className="bg-white p-8 rounded-3xl shadow-sm space-y-3 relative">
          <div className="w-14 h-14 bg-[#E8A857]/20 text-[#8B5A2B] rounded-2xl font-black text-xl flex items-center justify-center mx-auto">
            2
          </div>
          <h3 className="font-bold text-lg text-[#3D2817]">Baked To Order</h3>
          <p className="text-xs text-gray-600">Our bakers prepare your warm treats in small batches using premium natural ingredients.</p>
        </div>

        <div className="bg-white p-8 rounded-3xl shadow-sm space-y-3 relative">
          <div className="w-14 h-14 bg-[#E8A857]/20 text-[#8B5A2B] rounded-2xl font-black text-xl flex items-center justify-center mx-auto">
            3
          </div>
          <h3 className="font-bold text-lg text-[#3D2817]">Warm Delivery or Pickup</h3>
          <p className="text-xs text-gray-600">Get your pink-accent box delivered straight to your door or pick up warm in store.</p>
        </div>
      </div>
    </div>
  </section>

  {/* TESTIMONIALS */}
  <section className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
    <div className="text-center max-w-2xl mx-auto mb-12">
      <span className="text-xs font-bold text-[#8B5A2B] tracking-widest uppercase">Real Cookie Lovers</span>
      <h2 className="text-3xl font-black text-[#3D2817] mt-1">What Our Fans Say</h2>
    </div>

    <div className="grid md:grid-cols-3 gap-6">
      {TESTIMONIALS.map(t => (
        <div key={t.id} className="bg-white p-6 rounded-3xl border border-[#8B5A2B]/10 shadow-sm flex flex-col justify-between">
          <div>
            <div className="flex gap-1 text-amber-400 mb-3">
              {[...Array(t.rating)].map((_, i) => (
                <Star key={i} className="w-4 h-4 fill-current" />
              ))}
            </div>
            <p className="text-sm text-gray-700 italic">"{t.quote}"</p>
          </div>

          <div className="flex items-center gap-3 mt-6 pt-4 border-t border-gray-100">
            <img src={t.avatar} alt={t.name} className="w-10 h-10 rounded-full object-cover" />
            <div>
              <h4 className="text-xs font-bold text-[#3D2817]">{t.name}</h4>
              <p className="text-[10px] text-gray-500">{t.role}</p>
            </div>
          </div>
        </div>
      ))}
    </div>
  </section>

  {/* CATERING BANNER */}
  <section className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
    <div className="bg-[#3D2817] rounded-3xl p-8 md:p-12 text-white flex flex-col md:flex-row items-center justify-between gap-8 relative overflow-hidden shadow-xl">
      <div className="space-y-4 max-w-xl z-10 text-center md:text-left">
        <span className="bg-[#E8A857] text-[#3D2817] text-xs font-black uppercase px-3 py-1 rounded-full">
          Events & Weddings
        </span>
        <h2 className="text-3xl font-black text-[#FFF8EC]">Planning a Special Event?</h2>
        <p className="text-sm text-gray-300">
          Bring the ultimate cookie bar to your wedding, corporate party, or birthday. Custom boxes, mini cookies, and catering trays available!
        </p>
        <button 
          onClick={() => setActiveTab('catering')}
          className="inline-block bg-[#E8A857] hover:bg-[#d99746] text-[#3D2817] font-bold px-6 py-3 rounded-full text-sm transition-transform transform hover:scale-105"
        >
          Request Catering Quote
        </button>
      </div>
      
      <div className="w-full md:w-1/3 h-48 md:h-64 rounded-2xl overflow-hidden shadow-md z-10">
        <img 
          src="https://images.unsplash.com/photo-1558961363-fa8fdf82db35?auto=format&fit=crop&q=80&w=600" 
          alt="Cookie catering box" 
          className="w-full h-full object-cover"
        />
      </div>
    </div>
  </section>

</div>

);
};

// 2. MENU / SHOP PAGE
const MenuPage = ({ onSelectProduct }) => {
const [activeFilter, setActiveFilter] = useState('All');
const categories = ['All', 'Classic', 'Stuffed', 'Vegan', 'Gluten-Free'];

const filteredProducts = activeFilter === 'All'
? PRODUCTS
: PRODUCTS.filter(p => p.category === activeFilter);

return (



Our Cookie Menu



Baked in small batches with premium French butter and real Belgian chocolate.


  {/* Filter Tabs */}
  <div className="flex flex-wrap justify-center gap-2 mb-10">
    {categories.map(cat => (
      <button
        key={cat}
        onClick={() => setActiveFilter(cat)}
        className={`px-5 py-2.5 rounded-full text-xs font-bold transition-all ${
          activeFilter === cat 
            ? 'bg-[#8B5A2B] text-white shadow-md' 
            : 'bg-white text-[#3D2817] border border-[#8B5A2B]/10 hover:bg-[#FFF8EC]'
        }`}
      >
        {cat}
      </button>
    ))}
  </div>

  {/* Product Grid */}
  <div className="grid sm:grid-cols-2 lg:grid-cols-4 gap-6">
    {filteredProducts.map(product => (
      <ProductCard key={product.id} product={product} onSelectProduct={onSelectProduct} />
    ))}
  </div>
</div>

);
};

// 3. PRODUCT DETAIL PAGE / MODAL VIEW
const ProductDetailPage = ({ product, onBack, setActiveTab }) => {
const { addToCart } = useCart();
const [quantity, setQuantity] = useState(1);

if (!product) return null;

return (



← Back to Menu

  <div className="bg-white rounded-3xl p-6 md:p-10 border border-[#8B5A2B]/10 shadow-xl grid md:grid-cols-2 gap-10">
    <div className="rounded-2xl overflow-hidden bg-[#FFF8EC]">
      <img 
        src={product.image} 
        alt={product.name} 
        className="w-full h-96 object-cover"
      />
    </div>

    <div className="flex flex-col justify-between space-y-6">
      <div>
        <span className="text-xs font-bold uppercase tracking-widest text-[#8B5A2B] bg-[#FFF8EC] px-3 py-1 rounded-full">
          {product.category}
        </span>
        <h1 className="text-3xl font-black text-[#3D2817] mt-3">{product.name}</h1>
        <p className="text-2xl font-bold text-[#8B5A2B] mt-2">${product.price.toFixed(2)}</p>
        <p className="text-sm text-gray-600 mt-4 leading-relaxed">{product.description}</p>

        <div className="mt-6 space-y-2 border-t pt-4 border-gray-100">
          <div className="flex justify-between text-xs">
            <span className="font-bold text-[#3D2817]">Allergens:</span>
            <span className="text-gray-500">{product.allergens.join(', ')}</span>
          </div>
          <div className="flex justify-between text-xs">
            <span className="font-bold text-[#3D2817]">Calories:</span>
            <span className="text-gray-500">{product.calories}</span>
          </div>
        </div>
      </div>

      <div className="space-y-4 pt-4 border-t border-gray-100">
        <div className="flex items-center gap-4">
          <div className="flex items-center border border-gray-300 rounded-full px-3 py-1.5 bg-[#FFF8EC]">
            <button onClick={() => setQuantity(Math.max(1, quantity - 1))} className="p-1 text-[#3D2817]">
              <Minus className="w-4 h-4" />
            </button>
            <span className="px-4 font-bold text-sm text-[#3D2817]">{quantity}</span>
            <button onClick={() => setQuantity(quantity + 1)} className="p-1 text-[#3D2817]">
              <Plus className="w-4 h-4" />
            </button>
          </div>

          <button
            onClick={() => {
              addToCart(product, quantity);
            }}
            className="flex-1 bg-[#E8A857] hover:bg-[#d99746] text-[#3D2817] font-extrabold py-3.5 rounded-full shadow-lg transition-transform active:scale-95 text-sm"
          >
            Add To Box — ${(product.price * quantity).toFixed(2)}
          </button>
        </div>
      </div>

    </div>
  </div>
</div>

);
};

// 4. ABOUT US PAGE
const AboutPage = () => (

Our Story

Born From Pure Obsession

<div className="grid md:grid-cols-2 gap-10 items-center">
  <img 
    src="https://images.unsplash.com/photo-1556911220-e15b29be8c8f?auto=format&fit=crop&q=80&w=600" 
    alt="Baker preparing cookie dough" 
    className="rounded-3xl shadow-lg object-cover h-96 w-full"
  />
  <div className="space-y-4 text-gray-700 text-sm leading-relaxed">
    <h2 className="text-2xl font-black text-[#3D2817]">Thick, Gooey, Unapologetic.</h2>
    <p>
      Crumble Cookie started in a small home kitchen with one simple mission: build the ultimate cookie. No thin, dry, store-bought wafers — we wanted heavy, thick, gooey-centered cookies loaded with highest quality ingredients.
    </p>
    <p>
      Every dough batch is chilled for 24 hours to intensify flavors, then baked warm in our specialized convection ovens throughout the day.
    </p>
  </div>
</div>
);

// 5. LOCATIONS PAGE
const LocationsPage = () => (

Find A Bakery Near You

Stop by for a warm cookie straight out of the oven.

<div className="grid md:grid-cols-2 gap-6">
  {LOCATIONS.map((loc, idx) => (
    <div key={idx} className="bg-white p-6 rounded-3xl border border-[#8B5A2B]/10 shadow-sm space-y-4">
      <h3 className="text-xl font-black text-[#3D2817]">{loc.city}</h3>
      <div className="space-y-2 text-xs text-gray-600">
        <p className="flex items-center gap-2"><MapPin className="w-4 h-4 text-[#8B5A2B]" /> {loc.address}</p>
        <p className="flex items-center gap-2"><Clock className="w-4 h-4 text-[#8B5A2B]" /> {loc.hours}</p>
        <p className="flex items-center gap-2"><Phone className="w-4 h-4 text-[#8B5A2B]" /> {loc.phone}</p>
      </div>
      <button className="w-full mt-2 bg-[#FFF8EC] text-[#8B5A2B] hover:bg-[#8B5A2B] hover:text-white font-bold text-xs py-2.5 rounded-full transition-colors border border-[#8B5A2B]/20">
        Get Directions
      </button>
    </div>
  ))}
</div>
);

// 6. CATERING PAGE
const CateringPage = () => {
const [submitted, setSubmitted] = useState(false);

return (



Cookie Catering & Events


Make your special day unforgettable with warm, custom cookies.


  {submitted ? (
    <div className="bg-white p-8 rounded-3xl shadow-md text-center space-y-3">
      <div className="text-5xl">🎉</div>
      <h2 className="text-2xl font-bold text-[#3D2817]">Inquiry Received!</h2>
      <p className="text-xs text-gray-600">Our catering coordinator will reach out to you within 24 hours.</p>
    </div>
  ) : (
    <form onSubmit={(e) => { e.preventDefault(); setSubmitted(true); }} className="bg-white p-8 rounded-3xl border border-[#8B5A2B]/10 shadow-lg space-y-4">
      <div className="grid md:grid-cols-2 gap-4">
        <div>
          <label className="block text-xs font-bold text-[#3D2817] mb-1">Your Name</label>
          <input required type="text" className="w-full bg-[#FFF8EC] border border-gray-200 rounded-xl p-3 text-xs focus:outline-none focus:border-[#8B5A2B]" placeholder="Jane Doe" />
        </div>
        <div>
          <label className="block text-xs font-bold text-[#3D2817] mb-1">Email Address</label>
          <input required type="email" className="w-full bg-[#FFF8EC] border border-gray-200 rounded-xl p-3 text-xs focus:outline-none focus:border-[#8B5A2B]" placeholder="jane@example.com" />
        </div>
      </div>

      <div className="grid md:grid-cols-2 gap-4">
        <div>
          <label className="block text-xs font-bold text-[#3D2817] mb-1">Event Date</label>
          <input required type="date" className="w-full bg-[#FFF8EC] border border-gray-200 rounded-xl p-3 text-xs focus:outline-none focus:border-[#8B5A2B]" />
        </div>
        <div>
          <label className="block text-xs font-bold text-[#3D2817] mb-1">Estimated Quantity (Cookies)</label>
          <input required type="number" min="24" className="w-full bg-[#FFF8EC] border border-gray-200 rounded-xl p-3 text-xs focus:outline-none focus:border-[#8B5A2B]" placeholder="e.g. 50" />
        </div>
      </div>

      <div>
        <label className="block text-xs font-bold text-[#3D2817] mb-1">Event Details & Requests</label>
        <textarea rows="4" className="w-full bg-[#FFF8EC] border border-gray-200 rounded-xl p-3 text-xs focus:outline-none focus:border-[#8B5A2B]" placeholder="Tell us about your event, preferred flavors, custom box preferences..."></textarea>
      </div>

      <button type="submit" className="w-full bg-[#E8A857] hover:bg-[#d99746] text-[#3D2817] font-extrabold py-3.5 rounded-full text-sm shadow">
        Submit Catering Request
      </button>
    </form>
  )}
</div>

);
};

// 7. FAQ PAGE
const FAQPage = () => {
const [openIdx, setOpenIdx] = useState(null);

return (



Frequently Asked Questions


Everything you need to know about our warm treats.


  <div className="space-y-3">
    {FAQS.map((faq, idx) => (
      <div key={idx} className="bg-white rounded-2xl border border-[#8B5A2B]/10 overflow-hidden">
        <button 
          onClick={() => setOpenIdx(openIdx === idx ? null : idx)}
          className="w-full p-5 text-left font-bold text-sm text-[#3D2817] flex justify-between items-center hover:bg-[#FFF8EC]/50"
        >
          <span>{faq.q}</span>
          <ChevronDown className={`w-4 h-4 transition-transform ${openIdx === idx ? 'rotate-180' : ''}`} />
        </button>
        {openIdx === idx && (
          <div className="p-5 pt-0 text-xs text-gray-600 border-t border-gray-100 bg-white">
            {faq.a}
          </div>
        )}
      </div>
    ))}
  </div>
</div>

);
};

// 8. CONTACT PAGE
const ContactPage = () => {
const [sent, setSent] = useState(false);

return (



Say Hello


Have a question or feedback? We’d love to hear from you!


  {sent ? (
    <div className="bg-white p-8 rounded-3xl shadow-md text-center space-y-2">
      <div className="text-4xl">📬</div>
      <h2 className="text-xl font-bold text-[#3D2817]">Message Sent!</h2>
      <p className="text-xs text-gray-600">We'll respond to your email as soon as possible.</p>
    </div>
  ) : (
    <form onSubmit={(e) => { e.preventDefault(); setSent(true); }} className="bg-white p-8 rounded-3xl border border-[#8B5A2B]/10 shadow-lg space-y-4">
      <div>
        <label className="block text-xs font-bold text-[#3D2817] mb-1">Name</label>
        <input required type="text" className="w-full bg-[#FFF8EC] border border-gray-200 rounded-xl p-3 text-xs focus:outline-none" />
      </div>
      <div>
        <label className="block text-xs font-bold text-[#3D2817] mb-1">Email</label>
        <input required type="email" className="w-full bg-[#FFF8EC] border border-gray-200 rounded-xl p-3 text-xs focus:outline-none" />
      </div>
      <div>
        <label className="block text-xs font-bold text-[#3D2817] mb-1">Message</label>
        <textarea required rows="4" className="w-full bg-[#FFF8EC] border border-gray-200 rounded-xl p-3 text-xs focus:outline-none"></textarea>
      </div>
      <button type="submit" className="w-full bg-[#E8A857] hover:bg-[#d99746] text-[#3D2817] font-extrabold py-3.5 rounded-full text-sm shadow">
        Send Message
      </button>
    </form>
  )}
</div>

);
};

// --- FOOTER COMPONENT ---
const Footer = ({ setActiveTab }) => (

  <div className="space-y-4">
    <div className="flex items-center gap-2">
      <div className="w-8 h-8 rounded-full bg-[#E8A857] flex items-center justify-center text-[#3D2817] font-bold text-lg">
        🍪
      </div>
      <span className="text-xl font-black text-[#FFF8EC]">Crumble Cookie</span>
    </div>
    <p className="text-xs text-gray-400 leading-relaxed">
      Artisanal gourmet cookies, baked fresh in small batches daily. Satisfying your sweet cravings one warm cookie at a time.
    </p>
  </div>

  <div>
    <h4 className="text-xs font-bold tracking-widest text-[#E8A857] uppercase mb-4">Quick Links</h4>
    <ul className="space-y-2 text-xs font-medium text-gray-300">
      {['home', 'menu', 'about', 'locations', 'catering', 'faq', 'contact'].map(tab => (
        <li key={tab}>
          <button 
            onClick={() => { setActiveTab(tab); window.scrollTo({ top: 0, behavior: 'smooth' }); }}
            className="hover:text-[#E8A857] capitalize transition-colors"
          >
            {tab}
          </button>
        </li>
      ))}
    </ul>
  </div>

  <div>
    <h4 className="text-xs font-bold tracking-widest text-[#E8A857] uppercase mb-4">Store Hours</h4>
    <div className="text-xs text-gray-300 space-y-1">
      <p>Monday - Thursday: 8am - 10pm</p>
      <p>Friday - Saturday: 8am - 11pm</p>
      <p>Sunday: 9am - 9pm</p>
    </div>
  </div>

  <div>
    <h4 className="text-xs font-bold tracking-widest text-[#E8A857] uppercase mb-4">Get 10% Off</h4>
    <p className="text-xs text-gray-400 mb-3">Join our Cookie Club for exclusive discounts and weekly flavor updates.</p>
    <form onSubmit={(e) => { e.preventDefault(); alert("Subscribed!"); }} className="flex gap-2">
      <input 
        type="email" 
        placeholder="Your email" 
        className="bg-[#FFF8EC]/10 border border-[#FFF8EC]/20 rounded-full px-4 py-2 text-xs text-white placeholder-gray-400 focus:outline-none flex-1"
      />
      <button className="bg-[#E8A857] text-[#3D2817] font-bold px-4 py-2 rounded-full text-xs hover:bg-[#d99746]">
        Join
      </button>
    </form>
  </div>

</div>

<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 mt-12 pt-6 border-t border-white/10 text-center text-[10px] text-gray-400">
  © {new Date().getFullYear()} Crumble Cookie Co. All rights reserved. Crafted with care.
</div>
);

// --- MAIN APPLICATION COMPONENT ---
export default function App() {
const [activeTab, setActiveTab] = useState('home');
const [selectedProduct, setSelectedProduct] = useState(null);

const handleSelectProduct = (product) => {
setSelectedProduct(product);
setActiveTab('product-detail');
window.scrollTo({ top: 0, behavior: 'smooth' });
};

return (


    <CartDrawer />

    <main>
      {activeTab === 'home' && <HomePage setActiveTab={setActiveTab} onSelectProduct={handleSelectProduct} />}
      {activeTab === 'menu' && <MenuPage onSelectProduct={handleSelectProduct} />}
      {activeTab === 'product-detail' && <ProductDetailPage product={selectedProduct} onBack={() => setActiveTab('menu')} setActiveTab={setActiveTab} />}
      {activeTab === 'about' && <AboutPage />}
      {activeTab === 'locations' && <LocationsPage />}
      {activeTab === 'catering' && <CateringPage />}
      {activeTab === 'faq' && <FAQPage />}
      {activeTab === 'contact' && <ContactPage />}
    </main>

    <Footer setActiveTab={setActiveTab} />
  </div>
</CartProvider>

);
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions