Compare commits
13 Commits
version_1_
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 4bcd4c48ea | |||
|
|
e769151865 | ||
|
|
0f5b3d9173 | ||
| 0bf1edb8d5 | |||
| 7e4471a4c7 | |||
| 0564b54b92 | |||
|
|
7f9f8ae097 | ||
| b2bcfdc5bd | |||
|
|
a92a48dc84 | ||
| ca71cf51d1 | |||
|
|
5e91a51d8a | ||
| 0fe87384a2 | |||
| 40cb092069 |
@@ -73,15 +73,24 @@ export default function Layout() {
|
||||
title: "Hours",
|
||||
items: [
|
||||
{
|
||||
label: "Mon-Fri: 7am-9pm",
|
||||
label: "Daily: 6:00 AM - 12:00 AM",
|
||||
href: "#",
|
||||
},
|
||||
{
|
||||
label: "Sat-Sun: 8am-10pm",
|
||||
label: "يومياً: من 6 صباحاً حتى 12 منتصف الليل",
|
||||
href: "#",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Location",
|
||||
items: [
|
||||
{
|
||||
label: "Sana'a, Yemen",
|
||||
href: "#",
|
||||
}
|
||||
]
|
||||
},
|
||||
]}
|
||||
copyright="© 2024 Lithos Specialty Coffee. All rights reserved."
|
||||
links={[
|
||||
|
||||
@@ -1,179 +1,38 @@
|
||||
import AboutText from '@/components/sections/about/AboutText';
|
||||
import ContactCta from '@/components/sections/contact/ContactCta';
|
||||
import FaqSimple from '@/components/sections/faq/FaqSimple';
|
||||
import FeaturesBento from '@/components/sections/features/FeaturesBento';
|
||||
import FeaturesRevealCardsBento from '@/components/sections/features/FeaturesRevealCardsBento';
|
||||
import HeroCenteredLogos from '@/components/sections/hero/HeroCenteredLogos';
|
||||
import MetricsFeatureCards from '@/components/sections/metrics/MetricsFeatureCards';
|
||||
import TestimonialMarqueeCards from '@/components/sections/testimonial/TestimonialMarqueeCards';
|
||||
import SectionErrorBoundary from "@/components/ui/SectionErrorBoundary";
|
||||
// AUTO-GENERATED shell by per-section-migrate.
|
||||
// Section bodies live in ./<PageBase>/sections/<X>.tsx. Edit the section
|
||||
// files directly. Non-block content (wrappers, non-inlinable sections) is
|
||||
// preserved inline; extracted section blocks become <XSection/> refs.
|
||||
|
||||
export default function HomePage() {
|
||||
import React from 'react';
|
||||
import HeroSection from './HomePage/sections/Hero';
|
||||
import StorySection from './HomePage/sections/Story';
|
||||
import MenuSection from './HomePage/sections/Menu';
|
||||
import GallerySection from './HomePage/sections/Gallery';
|
||||
import TestimonialsSection from './HomePage/sections/Testimonials';
|
||||
import MetricsSection from './HomePage/sections/Metrics';
|
||||
import FaqSection from './HomePage/sections/Faq';
|
||||
|
||||
|
||||
import ContactSection from './HomePage/sections/Contact';
|
||||
import BookingSection from './HomePage/sections/Booking';export default function HomePage(): React.JSX.Element {
|
||||
return (
|
||||
<>
|
||||
<div id="hero" data-section="hero">
|
||||
<SectionErrorBoundary name="hero">
|
||||
<HeroCenteredLogos
|
||||
avatarsSrc={[
|
||||
"http://img.b2bpic.net/free-photo/happy-portrait-girl-holding-takeaway-coffee-cup_23-2147906477.jpg", "http://img.b2bpic.net/free-photo/high-angle-man-restaurant_23-2148395381.jpg", "http://img.b2bpic.net/free-photo/dreamy-beautiful-woman-student-sitting-cafe-with-books-magazines-smiling-holding-phone-thinking_176420-12422.jpg", "http://img.b2bpic.net/free-photo/medium-shot-smiley-woman-with-coffee-cup_23-2149412558.jpg", "http://img.b2bpic.net/free-photo/pretty-young-woman-enjoying-coffee-cup_23-2148756344.jpg"]}
|
||||
avatarText="Loved by 10,000+ coffee enthusiasts"
|
||||
title="The Art of Lithos Coffee"
|
||||
description="Experience the pinnacle of specialty coffee, where every drop tells a story of origin, passion, and meticulous craft."
|
||||
primaryButton={{
|
||||
text: "Discover Menu", href: "#menu"}}
|
||||
secondaryButton={{
|
||||
text: "Our Story", href: "#story"}}
|
||||
names={[
|
||||
"Sarah J.", "Michael R.", "Elena K.", "David W.", "Olivia M."]}
|
||||
imageSrc="http://img.b2bpic.net/free-photo/close-up-barista-hands-preparing-coffee-customer-coffee-shop_93675-135317.jpg"
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
<>
|
||||
<HeroSection />
|
||||
|
||||
<div id="story" data-section="story">
|
||||
<SectionErrorBoundary name="story">
|
||||
<AboutText
|
||||
title="Rooted in Passion, Crafted in Lithos"
|
||||
primaryButton={{
|
||||
text: "Our Brewing Philosophy", href: "#"}}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
<StorySection />
|
||||
|
||||
<div id="menu" data-section="menu">
|
||||
<SectionErrorBoundary name="menu">
|
||||
<FeaturesRevealCardsBento
|
||||
tag="The Menu"
|
||||
title="Curated Experiences"
|
||||
description="From single-origin pours to delicate pastries, every item is selected for quality."
|
||||
items={[
|
||||
{
|
||||
title: "Signature Espresso", description: "Robust and refined, our signature blend.", href: "#", imageSrc: "http://img.b2bpic.net/free-photo/close-up-hand-holding-coffee-with-milk-cream_23-2148865608.jpg"},
|
||||
{
|
||||
title: "Cold Brew", description: "Steeped for 24 hours, velvet smooth.", href: "#", imageSrc: "http://img.b2bpic.net/free-photo/glasses-with-tasty-coffee-assortment_23-2149514291.jpg"},
|
||||
{
|
||||
title: "Gourmet Pastries", description: "Freshly baked every single morning.", href: "#", imageSrc: "http://img.b2bpic.net/free-photo/blue-plate-two-sweet-doughnuts-with-colorful-sprinkles_114579-87208.jpg"},
|
||||
{
|
||||
title: "Flat White", description: "Perfectly steamed, silky texture.", href: "#", imageSrc: "http://img.b2bpic.net/free-photo/small-business-items-serving-coffee_23-2149458023.jpg"},
|
||||
{
|
||||
title: "Iced Latte", description: "Refreshing and bold caffeine lift.", href: "#", imageSrc: "http://img.b2bpic.net/free-photo/refreshing-iced-coffee-glass-with-condensation-ice_84443-83820.jpg"},
|
||||
{
|
||||
title: "Artisan Danishes", description: "Layers of buttery, flaky perfection.", href: "#", imageSrc: "http://img.b2bpic.net/free-photo/strawberry-pie-table_140725-6826.jpg"},
|
||||
{
|
||||
title: "Pour Over", description: "Clean flavors, vibrant origin notes.", href: "#", imageSrc: "http://img.b2bpic.net/free-photo/man-pouring-syrup-coffee-mixed-with-milk_140725-7036.jpg"},
|
||||
]}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
<MenuSection />
|
||||
|
||||
<div id="gallery" data-section="gallery">
|
||||
<SectionErrorBoundary name="gallery">
|
||||
<FeaturesBento
|
||||
tag="Our Space"
|
||||
title="A Sanctuary of Coffee"
|
||||
description="Explore the aesthetic detail that defines Lithos."
|
||||
features={[
|
||||
{
|
||||
title: "Designed for You", description: "Modern minimalist interiors designed for comfort and focus.", bentoComponent: "media-stack", mediaItems: [
|
||||
{
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/hookah-still-life-assortment_23-2149213303.jpg"},
|
||||
{
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/luxury-bar-illuminated-by-modern-lighting-equipment-generated-by-ai_188544-24181.jpg"},
|
||||
{
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/coffee-cup-cheesecake-wooden-table-front-cushion-against-white-wall_23-2148067198.jpg"},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Crafted Details", description: "Every corner is meticulously considered.", bentoComponent: "media-stack", mediaItems: [
|
||||
{
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/pretty-blonde-woman-sitting-cafe_273609-6751.jpg"},
|
||||
{
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/top-view-black-coffee-mug-near-wooden-cutting-board-cheese-copy-space_132075-11328.jpg"},
|
||||
{
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/happy-beautiful-asian-girl-barista-apron-works-with-coffee-machine-counter-standing_1258-203398.jpg"},
|
||||
],
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
<GallerySection />
|
||||
|
||||
<div id="testimonials" data-section="testimonials">
|
||||
<SectionErrorBoundary name="testimonials">
|
||||
<TestimonialMarqueeCards
|
||||
tag="Reviews"
|
||||
title="What Our Community Says"
|
||||
testimonials={[
|
||||
{
|
||||
name: "Sarah J.", role: "Coffee Enthusiast", quote: "The best flat white I have ever had.", imageSrc: "http://img.b2bpic.net/free-photo/portrait-beautiful-girl-dressed-white-pajamas_158538-18356.jpg"},
|
||||
{
|
||||
name: "Michael R.", role: "Regular Patron", quote: "Lithos feels like home away from home.", imageSrc: "http://img.b2bpic.net/free-photo/bearded-male-drinks-coffee-cafe_613910-8838.jpg"},
|
||||
{
|
||||
name: "Elena K.", role: "Design Critic", quote: "Unmatched aesthetic and impeccable coffee.", imageSrc: "http://img.b2bpic.net/free-photo/young-adult-enjoying-beverage_23-2149304428.jpg"},
|
||||
{
|
||||
name: "David W.", role: "Professional", quote: "The perfect spot for my morning meetings.", imageSrc: "http://img.b2bpic.net/free-photo/young-man-texting-cafe-happy-businessman-smiling-texting-smartphone-table_1391-595.jpg"},
|
||||
{
|
||||
name: "Olivia M.", role: "Foodie", quote: "Their danishes are genuinely life-changing.", imageSrc: "http://img.b2bpic.net/free-photo/attractive-casual-african-american-girl-stylish-trench-coat-happily-looking-away-with-coffee-go-cafe-street_574295-2881.jpg"},
|
||||
]}
|
||||
description="Join our community of coffee lovers."
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
<TestimonialsSection />
|
||||
|
||||
<div id="metrics" data-section="metrics">
|
||||
<SectionErrorBoundary name="metrics">
|
||||
<MetricsFeatureCards
|
||||
tag="Our Impact"
|
||||
title="Lithos By The Numbers"
|
||||
description="Dedication to quality measured in cups."
|
||||
metrics={[
|
||||
{
|
||||
value: "15k+", title: "Cups Served", features: [
|
||||
"Sustainably sourced", "Small batch roasts"],
|
||||
},
|
||||
{
|
||||
value: "50+", title: "Coffee Origins", features: [
|
||||
"Direct trade", "Premium quality"],
|
||||
},
|
||||
{
|
||||
value: "12", title: "Pastry Flavors", features: [
|
||||
"Daily fresh", "Handmade"],
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
<MetricsSection />
|
||||
|
||||
<div id="faq" data-section="faq">
|
||||
<SectionErrorBoundary name="faq">
|
||||
<FaqSimple
|
||||
tag="Support"
|
||||
title="Common Inquiries"
|
||||
description="Answers to your burning coffee questions."
|
||||
items={[
|
||||
{
|
||||
question: "Do you offer plant-based milks?", answer: "Yes, we offer oat, almond, and soy alternatives."},
|
||||
{
|
||||
question: "Can I work from your cafe?", answer: "Absolutely, our space is designed for comfort and focused work."},
|
||||
{
|
||||
question: "Do you host brewing workshops?", answer: "Yes, subscribe to our newsletter for event announcements."},
|
||||
]}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
<FaqSection />
|
||||
|
||||
<div id="contact" data-section="contact">
|
||||
<SectionErrorBoundary name="contact">
|
||||
<ContactCta
|
||||
tag="Visit Us"
|
||||
text="Join us at Lithos and experience the difference today."
|
||||
primaryButton={{
|
||||
text: "Get Directions", href: "#footer"}}
|
||||
secondaryButton={{
|
||||
text: "Call Now", href: "tel:5550123"}}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
<ContactSection />
|
||||
<BookingSection />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
205
src/pages/HomePage/sections/Booking.tsx
Normal file
205
src/pages/HomePage/sections/Booking.tsx
Normal file
@@ -0,0 +1,205 @@
|
||||
import React, { useState } from 'react';
|
||||
import { MapPin, Phone, MessageCircle } from 'lucide-react';
|
||||
|
||||
export default function BookingSection() {
|
||||
const [orderName, setOrderName] = useState('');
|
||||
const [orderDrink, setOrderDrink] = useState('');
|
||||
|
||||
const handleOrderSubmit = (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
alert(`Order placed for ${orderName}: ${orderDrink}`);
|
||||
};
|
||||
|
||||
const handleBookingSubmit = (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
alert('Table booked successfully!');
|
||||
};
|
||||
|
||||
return (
|
||||
<div id="booking" data-webild-section="booking">
|
||||
<section className="relative w-full py-24 bg-background">
|
||||
<div className="w-content-width mx-auto">
|
||||
<div className="text-center mb-16">
|
||||
<h2 className="text-4xl md:text-5xl font-bold text-foreground mb-4">Visit & Order</h2>
|
||||
<p className="text-lg text-accent max-w-2xl mx-auto">
|
||||
Find us in Sana'a, order your favorite drinks ahead of time, or book a quiet table for your next meeting.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
|
||||
{/* Contact Info & Map */}
|
||||
<div className="card p-8 flex flex-col gap-6 rounded-lg">
|
||||
<div>
|
||||
<h3 className="text-2xl font-bold text-foreground mb-6">Contact Us</h3>
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-start gap-3">
|
||||
<MapPin className="w-5 h-5 text-accent mt-1" />
|
||||
<div>
|
||||
<p className="font-medium text-foreground">Location</p>
|
||||
<p className="text-accent">Sana'a, Yemen</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-start gap-3">
|
||||
<Phone className="w-5 h-5 text-accent mt-1" />
|
||||
<div>
|
||||
<p className="font-medium text-foreground">Phone</p>
|
||||
<a href="tel:+967730725728" className="text-accent hover:text-foreground transition-colors">
|
||||
+967 730725728
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-3 mt-2">
|
||||
<a
|
||||
href="tel:+967730725728"
|
||||
className="secondary-button w-full py-3 rounded-md text-center font-medium flex items-center justify-center"
|
||||
>
|
||||
Call Now
|
||||
</a>
|
||||
<a
|
||||
href="https://wa.me/967730725728"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center justify-center gap-2 w-full py-3 rounded-md font-medium transition-colors bg-[#25D366] hover:bg-[#128C7E] text-white"
|
||||
>
|
||||
<MessageCircle className="w-5 h-5" />
|
||||
WhatsApp Ordering
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="mt-auto pt-6 rounded-lg overflow-hidden h-48 relative">
|
||||
<iframe
|
||||
src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d123115.34027786435!2d44.12766324024888!3d15.35010619717163!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x1603db129e928231%3A0x101037599292820!2sSana'a%2C%20Yemen!5e0!3m2!1sen!2sus!4v1700000000000!5m2!1sen!2sus"
|
||||
width="100%"
|
||||
height="100%"
|
||||
style={{ border: 0 }}
|
||||
allowFullScreen={false}
|
||||
loading="lazy"
|
||||
referrerPolicy="no-referrer-when-downgrade"
|
||||
className="absolute inset-0"
|
||||
></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Order Ahead Form */}
|
||||
<div className="card p-8 rounded-lg">
|
||||
<h3 className="text-2xl font-bold text-foreground mb-2">Order Ahead</h3>
|
||||
<p className="text-accent mb-6">Skip the line and pick up your favorites.</p>
|
||||
|
||||
<form onSubmit={handleOrderSubmit} className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<label htmlFor="name" className="text-sm font-medium text-foreground">Your Name</label>
|
||||
<input
|
||||
id="name"
|
||||
placeholder="Enter your name"
|
||||
value={orderName}
|
||||
onChange={(e) => setOrderName(e.target.value)}
|
||||
required
|
||||
className="w-full h-10 px-3 py-2 rounded-md border border-foreground/20 bg-background text-foreground focus:outline-none focus:border-foreground/50"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<label htmlFor="drink" className="text-sm font-medium text-foreground">Select Drink</label>
|
||||
<select
|
||||
id="drink"
|
||||
className="w-full h-10 px-3 py-2 rounded-md border border-foreground/20 bg-background text-foreground focus:outline-none focus:border-foreground/50"
|
||||
value={orderDrink}
|
||||
onChange={(e) => setOrderDrink(e.target.value)}
|
||||
required
|
||||
>
|
||||
<option value="" disabled>Choose a drink...</option>
|
||||
<option value="flat-white">Flat White</option>
|
||||
<option value="v60">V60 Pour Over</option>
|
||||
<option value="cortado">Cortado</option>
|
||||
<option value="matcha">Matcha Latte</option>
|
||||
<option value="cold-brew">Cold Brew</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<label htmlFor="notes" className="text-sm font-medium text-foreground">Special Instructions</label>
|
||||
<textarea
|
||||
id="notes"
|
||||
placeholder="Oat milk, extra hot, etc."
|
||||
rows={3}
|
||||
className="w-full px-3 py-2 rounded-md border border-foreground/20 bg-background text-foreground focus:outline-none focus:border-foreground/50"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="pt-2">
|
||||
<button type="submit" className="primary-button w-full py-3 rounded-md font-medium">
|
||||
Submit Order
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{/* Table Booking Widget */}
|
||||
<div className="card p-8 rounded-lg">
|
||||
<h3 className="text-2xl font-bold text-foreground mb-2">Book a Table</h3>
|
||||
<p className="text-accent mb-6">Reserve a quiet spot for studying or meetings.</p>
|
||||
|
||||
<form onSubmit={handleBookingSubmit} className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<label htmlFor="booking-name" className="text-sm font-medium text-foreground">Name</label>
|
||||
<input
|
||||
id="booking-name"
|
||||
placeholder="Enter your name"
|
||||
required
|
||||
className="w-full h-10 px-3 py-2 rounded-md border border-foreground/20 bg-background text-foreground focus:outline-none focus:border-foreground/50"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div className="space-y-2">
|
||||
<label htmlFor="date" className="text-sm font-medium text-foreground">Date</label>
|
||||
<input
|
||||
id="date"
|
||||
type="date"
|
||||
required
|
||||
className="w-full h-10 px-3 py-2 rounded-md border border-foreground/20 bg-background text-foreground focus:outline-none focus:border-foreground/50"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<label htmlFor="time" className="text-sm font-medium text-foreground">Time</label>
|
||||
<input
|
||||
id="time"
|
||||
type="time"
|
||||
required
|
||||
className="w-full h-10 px-3 py-2 rounded-md border border-foreground/20 bg-background text-foreground focus:outline-none focus:border-foreground/50"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<label htmlFor="guests" className="text-sm font-medium text-foreground">Number of Guests</label>
|
||||
<select
|
||||
id="guests"
|
||||
className="w-full h-10 px-3 py-2 rounded-md border border-foreground/20 bg-background text-foreground focus:outline-none focus:border-foreground/50"
|
||||
required
|
||||
defaultValue="1"
|
||||
>
|
||||
<option value="1">1 Person</option>
|
||||
<option value="2">2 People</option>
|
||||
<option value="3">3 People</option>
|
||||
<option value="4">4 People</option>
|
||||
<option value="5+">5+ People</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div className="pt-2">
|
||||
<button type="submit" className="primary-button w-full py-3 rounded-md font-medium">
|
||||
Confirm Booking
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
187
src/pages/HomePage/sections/Contact.tsx
Normal file
187
src/pages/HomePage/sections/Contact.tsx
Normal file
@@ -0,0 +1,187 @@
|
||||
import React, { useState } from 'react';
|
||||
import { MapPin, Phone, MessageCircle } from 'lucide-react';
|
||||
import Button from '@/components/ui/Button';
|
||||
import Input from '@/components/ui/Input';
|
||||
import Label from '@/components/ui/Label';
|
||||
import Textarea from '@/components/ui/Textarea';
|
||||
import Card from '@/components/ui/Card';
|
||||
|
||||
export default function ContactSection() {
|
||||
const [orderName, setOrderName] = useState('');
|
||||
const [orderDrink, setOrderDrink] = useState('');
|
||||
|
||||
const handleOrderSubmit = (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
alert(`Order placed for ${orderName}: ${orderDrink}`);
|
||||
};
|
||||
|
||||
const handleBookingSubmit = (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
alert('Table booked successfully!');
|
||||
};
|
||||
|
||||
return (
|
||||
<section id="contact" data-webild-section="contact" className="relative w-full py-24 bg-background">
|
||||
<div className="w-content-width mx-auto">
|
||||
<div className="text-center mb-16">
|
||||
<h2 className="text-4xl md:text-5xl font-bold text-foreground mb-4">Visit & Order</h2>
|
||||
<p className="text-lg text-accent max-w-2xl mx-auto">
|
||||
Find us in Sana'a, order your favorite drinks ahead of time, or book a quiet table for your next meeting.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
|
||||
{/* Contact Info & Map */}
|
||||
<Card className="p-8 flex flex-col gap-6">
|
||||
<div>
|
||||
<h3 className="text-2xl font-bold text-foreground mb-6">Contact Us</h3>
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-start gap-3">
|
||||
<MapPin className="w-5 h-5 text-accent mt-1" />
|
||||
<div>
|
||||
<p className="font-medium text-foreground">Location</p>
|
||||
<p className="text-accent">Sana'a, Yemen</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-start gap-3">
|
||||
<Phone className="w-5 h-5 text-accent mt-1" />
|
||||
<div>
|
||||
<p className="font-medium text-foreground">Phone</p>
|
||||
<a href="tel:+967730725728" className="text-accent hover:text-foreground transition-colors">
|
||||
+967 730725728
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-3 mt-2">
|
||||
<Button
|
||||
text="Call Now"
|
||||
href="tel:+967730725728"
|
||||
variant="secondary"
|
||||
className="w-full justify-center"
|
||||
/>
|
||||
<a
|
||||
href="https://wa.me/967730725728"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center justify-center gap-2 w-full h-12 px-6 rounded-md font-medium transition-colors bg-[#25D366] hover:bg-[#128C7E] text-white"
|
||||
>
|
||||
<MessageCircle className="w-5 h-5" />
|
||||
WhatsApp Ordering
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="mt-auto pt-6 rounded-lg overflow-hidden h-48 relative">
|
||||
<iframe
|
||||
src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d123115.34027786435!2d44.12766324024888!3d15.35010619717163!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x1603db129e928231%3A0x101037599292820!2sSana'a%2C%20Yemen!5e0!3m2!1sen!2sus!4v1700000000000!5m2!1sen!2sus"
|
||||
width="100%"
|
||||
height="100%"
|
||||
style={{ border: 0 }}
|
||||
allowFullScreen={false}
|
||||
loading="lazy"
|
||||
referrerPolicy="no-referrer-when-downgrade"
|
||||
className="absolute inset-0"
|
||||
></iframe>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
{/* Order Ahead Form */}
|
||||
<Card className="p-8">
|
||||
<h3 className="text-2xl font-bold text-foreground mb-2">Order Ahead</h3>
|
||||
<p className="text-accent mb-6">Skip the line and pick up your favorites.</p>
|
||||
|
||||
<form onSubmit={handleOrderSubmit} className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="name">Your Name</Label>
|
||||
<Input
|
||||
id="name"
|
||||
placeholder="Enter your name"
|
||||
value={orderName}
|
||||
onChange={(e) => setOrderName(e.target.value)}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="drink">Select Drink</Label>
|
||||
<select
|
||||
id="drink"
|
||||
className="w-full h-10 px-3 py-2 rounded-md border border-input bg-background text-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 text-foreground"
|
||||
value={orderDrink}
|
||||
onChange={(e) => setOrderDrink(e.target.value)}
|
||||
required
|
||||
>
|
||||
<option value="" disabled>Choose a drink...</option>
|
||||
<option value="flat-white">Flat White</option>
|
||||
<option value="v60">V60 Pour Over</option>
|
||||
<option value="cortado">Cortado</option>
|
||||
<option value="matcha">Matcha Latte</option>
|
||||
<option value="cold-brew">Cold Brew</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="notes">Special Instructions</Label>
|
||||
<Textarea id="notes" placeholder="Oat milk, extra hot, etc." rows={3} />
|
||||
</div>
|
||||
|
||||
<div className="pt-2">
|
||||
<Button text="Submit Order" variant="primary" className="w-full justify-center" />
|
||||
</div>
|
||||
</form>
|
||||
</Card>
|
||||
|
||||
{/* Table Booking Widget */}
|
||||
<Card className="p-8">
|
||||
<h3 className="text-2xl font-bold text-foreground mb-2">Book a Table</h3>
|
||||
<p className="text-accent mb-6">Reserve a quiet spot for studying or meetings.</p>
|
||||
|
||||
<form onSubmit={handleBookingSubmit} className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="booking-name">Name</Label>
|
||||
<Input id="booking-name" placeholder="Enter your name" required />
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="date">Date</Label>
|
||||
<div className="relative">
|
||||
<Input id="date" type="date" required className="w-full" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="time">Time</Label>
|
||||
<div className="relative">
|
||||
<Input id="time" type="time" required className="w-full" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="guests">Number of Guests</Label>
|
||||
<select
|
||||
id="guests"
|
||||
className="w-full h-10 px-3 py-2 rounded-md border border-input bg-background text-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 text-foreground"
|
||||
required
|
||||
defaultValue="1"
|
||||
>
|
||||
<option value="1">1 Person</option>
|
||||
<option value="2">2 People</option>
|
||||
<option value="3">3 People</option>
|
||||
<option value="4">4 People</option>
|
||||
<option value="5+">5+ People</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div className="pt-2">
|
||||
<Button text="Confirm Booking" variant="primary" className="w-full justify-center" />
|
||||
</div>
|
||||
</form>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
21
src/pages/HomePage/sections/Faq.tsx
Normal file
21
src/pages/HomePage/sections/Faq.tsx
Normal file
@@ -0,0 +1,21 @@
|
||||
// AUTO-GENERATED by per-section-migrate. Edit freely — Bob will treat this
|
||||
// file as the canonical source for the "faq" section.
|
||||
|
||||
import React from 'react';
|
||||
import FaqSimple from '@/components/sections/faq/FaqSimple';
|
||||
import SectionErrorBoundary from "@/components/ui/SectionErrorBoundary";
|
||||
|
||||
export default function FaqSection(): React.JSX.Element {
|
||||
return (
|
||||
<div id="faq" data-section="faq">
|
||||
<SectionErrorBoundary name="faq">
|
||||
<FaqSimple
|
||||
tag="Support"
|
||||
title="Common Inquiries"
|
||||
description="Answers to your burning coffee questions."
|
||||
items={[{"answer":"We roast our beans weekly to ensure maximum freshness and flavor.","question":"When are your beans roasted?"},{"answer":"Yes, we offer fast, complimentary WiFi for all our guests.","question":"Is there WiFi available?"},{"answer":"Yes, we offer oat, almond, and soy alternatives.","question":"Do you offer plant-based milks?"}]}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
42
src/pages/HomePage/sections/Gallery.tsx
Normal file
42
src/pages/HomePage/sections/Gallery.tsx
Normal file
@@ -0,0 +1,42 @@
|
||||
// AUTO-GENERATED by per-section-migrate. Edit freely — Bob will treat this
|
||||
// file as the canonical source for the "gallery" section.
|
||||
|
||||
import React from 'react';
|
||||
import FeaturesBento from '@/components/sections/features/FeaturesBento';
|
||||
import SectionErrorBoundary from "@/components/ui/SectionErrorBoundary";
|
||||
|
||||
export default function GallerySection(): React.JSX.Element {
|
||||
return (
|
||||
<div id="gallery" data-section="gallery">
|
||||
<SectionErrorBoundary name="gallery">
|
||||
<FeaturesBento
|
||||
tag="Our Space"
|
||||
title="A Sanctuary of Coffee"
|
||||
description="Explore the aesthetic detail that defines Lithos."
|
||||
features={[
|
||||
{
|
||||
title: "Designed for You", description: "Modern minimalist interiors designed for comfort and focus.", bentoComponent: "media-stack", mediaItems: [
|
||||
{
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/hookah-still-life-assortment_23-2149213303.jpg"},
|
||||
{
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/luxury-bar-illuminated-by-modern-lighting-equipment-generated-by-ai_188544-24181.jpg"},
|
||||
{
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/coffee-cup-cheesecake-wooden-table-front-cushion-against-white-wall_23-2148067198.jpg"},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Crafted Details", description: "Every corner is meticulously considered.", bentoComponent: "media-stack", mediaItems: [
|
||||
{
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/pretty-blonde-woman-sitting-cafe_273609-6751.jpg"},
|
||||
{
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/top-view-black-coffee-mug-near-wooden-cutting-board-cheese-copy-space_132075-11328.jpg"},
|
||||
{
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/happy-beautiful-asian-girl-barista-apron-works-with-coffee-machine-counter-standing_1258-203398.jpg"},
|
||||
],
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
28
src/pages/HomePage/sections/Hero.tsx
Normal file
28
src/pages/HomePage/sections/Hero.tsx
Normal file
@@ -0,0 +1,28 @@
|
||||
// AUTO-GENERATED by per-section-migrate. Edit freely — Bob will treat this
|
||||
// file as the canonical source for the "hero" section.
|
||||
|
||||
import React from 'react';
|
||||
import HeroCenteredLogos from '@/components/sections/hero/HeroCenteredLogos';
|
||||
import SectionErrorBoundary from "@/components/ui/SectionErrorBoundary";
|
||||
|
||||
export default function HeroSection(): React.JSX.Element {
|
||||
return (
|
||||
<div id="hero" data-section="hero">
|
||||
<SectionErrorBoundary name="hero">
|
||||
<HeroCenteredLogos
|
||||
avatarsSrc={[
|
||||
"http://img.b2bpic.net/free-photo/happy-portrait-girl-holding-takeaway-coffee-cup_23-2147906477.jpg", "http://img.b2bpic.net/free-photo/high-angle-man-restaurant_23-2148395381.jpg", "http://img.b2bpic.net/free-photo/dreamy-beautiful-woman-student-sitting-cafe-with-books-magazines-smiling-holding-phone-thinking_176420-12422.jpg", "http://img.b2bpic.net/free-photo/medium-shot-smiley-woman-with-coffee-cup_23-2149412558.jpg", "http://img.b2bpic.net/free-photo/pretty-young-woman-enjoying-coffee-cup_23-2148756344.jpg"]}
|
||||
avatarText="Loved by 10,000+ coffee enthusiasts"
|
||||
title="ليثوس | حيث تلتقي الأصالة بفن القهوة المختصة."
|
||||
description="Lithos | Where Heritage Meets the Craft of Specialty Coffee."
|
||||
primaryButton={{"href":"#menu","text":"اكتشف المنيو / Explore Menu"}}
|
||||
secondaryButton={{
|
||||
text: "Our Story", href: "#story"}}
|
||||
names={[
|
||||
"Sarah J.", "Michael R.", "Elena K.", "David W.", "Olivia M."]}
|
||||
imageSrc="http://img.b2bpic.net/free-photo/close-up-barista-hands-preparing-coffee-customer-coffee-shop_93675-135317.jpg"
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
49
src/pages/HomePage/sections/Menu.tsx
Normal file
49
src/pages/HomePage/sections/Menu.tsx
Normal file
@@ -0,0 +1,49 @@
|
||||
// AUTO-GENERATED by per-section-migrate. Edit freely — Bob will treat this
|
||||
// file as the canonical source for the "menu" section.
|
||||
|
||||
import React from 'react';
|
||||
import FeaturesRevealCardsBento from '@/components/sections/features/FeaturesRevealCardsBento';
|
||||
import SectionErrorBoundary from "@/components/ui/SectionErrorBoundary";
|
||||
|
||||
export default function MenuSection(): React.JSX.Element {
|
||||
return (
|
||||
<div id="menu" data-section="menu" className="flex flex-col gap-16 py-12">
|
||||
<SectionErrorBoundary name="menu">
|
||||
<FeaturesRevealCardsBento
|
||||
tag="Menu / المنيو"
|
||||
title="Hot Drinks / مشروبات حارة"
|
||||
description="Carefully crafted hot beverages to warm your soul."
|
||||
items={[
|
||||
{
|
||||
title: "Ethiopian Drip / قهوة مقطرة إثيوبية", description: "Large: 12 | Small: 9", href: "#", imageSrc: "http://img.b2bpic.net/free-photo/man-pouring-syrup-coffee-mixed-with-milk_140725-7036.jpg?_wi=1"},
|
||||
{
|
||||
title: "Brazilian Drip / قهوة مقطرة برازيلية", description: "Large: 10 | Small: 7", href: "#", imageSrc: "http://img.b2bpic.net/free-photo/close-up-hand-holding-coffee-with-milk-cream_23-2148865608.jpg?_wi=1"},
|
||||
{
|
||||
title: "Americano / أمريكانو", description: "Large: 13 | Small: 10", href: "#", imageSrc: "http://img.b2bpic.net/free-photo/small-business-items-serving-coffee_23-2149458023.jpg?_wi=1"},
|
||||
{
|
||||
title: "Espresso / إسبريسو", description: "Price: 8", href: "#", imageSrc: "http://img.b2bpic.net/free-photo/glasses-with-tasty-coffee-assortment_23-2149514291.jpg?_wi=1"},
|
||||
{
|
||||
title: "Cortado/Piccolo / كورتادو/بيكولو", description: "Price: 10", href: "#", imageSrc: "http://img.b2bpic.net/free-photo/close-up-hand-holding-coffee-with-milk-cream_23-2148865608.jpg?_wi=2"},
|
||||
{
|
||||
title: "Latte / لاتيه", description: "Large: 13 | Small: 10", href: "#", imageSrc: "http://img.b2bpic.net/free-photo/man-pouring-syrup-coffee-mixed-with-milk_140725-7036.jpg?_wi=2"},
|
||||
{
|
||||
title: "Cappuccino / كابتشينو", description: "Large: 13 | Small: 10", href: "#", imageSrc: "http://img.b2bpic.net/free-photo/small-business-items-serving-coffee_23-2149458023.jpg?_wi=2"},
|
||||
]}
|
||||
/>
|
||||
<FeaturesRevealCardsBento
|
||||
tag="Menu / المنيو"
|
||||
title="Iced Drinks / مشروبات باردة"
|
||||
description="Refreshing iced beverages to cool you down."
|
||||
items={[
|
||||
{
|
||||
title: "Iced Latte / لاتيه بارد", description: "Large: 15 | Small: 12", href: "#", imageSrc: "http://img.b2bpic.net/free-photo/refreshing-iced-coffee-glass-with-condensation-ice_84443-83820.jpg?_wi=1"},
|
||||
{
|
||||
title: "Iced Americano / أمريكانو بارد", description: "Large: 14 | Small: 11", href: "#", imageSrc: "http://img.b2bpic.net/free-photo/refreshing-iced-coffee-glass-with-condensation-ice_84443-83820.jpg?_wi=2"},
|
||||
{
|
||||
title: "Cold Brew / كولد برو", description: "Price: 16", href: "#", imageSrc: "http://img.b2bpic.net/free-photo/glasses-with-tasty-coffee-assortment_23-2149514291.jpg?_wi=2"},
|
||||
]}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
34
src/pages/HomePage/sections/Metrics.tsx
Normal file
34
src/pages/HomePage/sections/Metrics.tsx
Normal file
@@ -0,0 +1,34 @@
|
||||
// AUTO-GENERATED by per-section-migrate. Edit freely — Bob will treat this
|
||||
// file as the canonical source for the "metrics" section.
|
||||
|
||||
import React from 'react';
|
||||
import MetricsFeatureCards from '@/components/sections/metrics/MetricsFeatureCards';
|
||||
import SectionErrorBoundary from "@/components/ui/SectionErrorBoundary";
|
||||
|
||||
export default function MetricsSection(): React.JSX.Element {
|
||||
return (
|
||||
<div id="metrics" data-section="metrics">
|
||||
<SectionErrorBoundary name="metrics">
|
||||
<MetricsFeatureCards
|
||||
tag="Our Impact"
|
||||
title="Lithos By The Numbers"
|
||||
description="Dedication to quality measured in cups."
|
||||
metrics={[
|
||||
{
|
||||
value: "15k+", title: "Cups Served", features: [
|
||||
"Sustainably sourced", "Small batch roasts"],
|
||||
},
|
||||
{
|
||||
value: "50+", title: "Coffee Origins", features: [
|
||||
"Direct trade", "Premium quality"],
|
||||
},
|
||||
{
|
||||
value: "12", title: "Pastry Flavors", features: [
|
||||
"Daily fresh", "Handmade"],
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
47
src/pages/HomePage/sections/Story.tsx
Normal file
47
src/pages/HomePage/sections/Story.tsx
Normal file
@@ -0,0 +1,47 @@
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck — generated by catalog-eject; runtime-correct but TS strict-mode false-positives on inlined catalog body
|
||||
import Button from "@/components/ui/Button";
|
||||
import TextAnimation from "@/components/ui/TextAnimation";
|
||||
|
||||
const primaryButton = {
|
||||
href: "#",
|
||||
text: "Our Brewing Philosophy"
|
||||
};
|
||||
|
||||
interface AboutTextProps {
|
||||
title: string;
|
||||
primaryButton?: { text: string; href: string };
|
||||
secondaryButton?: { text: string; href: string };
|
||||
}
|
||||
|
||||
const StoryInline = () => {
|
||||
return (
|
||||
<section aria-label="About section" className="py-20">
|
||||
<div className="w-content-width mx-auto flex flex-col gap-2 items-center">
|
||||
<div className="flex flex-col gap-6 max-w-4xl text-center">
|
||||
<p className="text-2xl md:text-3xl font-medium text-foreground leading-relaxed" dir="rtl">
|
||||
في ليثوس، نحن لا نقدم مجرد كوب قهوة، بل نسرد قصة تبدأ من اختيار أجود حبات البن من مزارعها المستدامة، ونتوجها بتحميص دقيق وشغف لا ينتهي. اسمنا مستوحى من الصلابة والعراقة، ليكون كل رشفة تجربة فريدة تأخذك في رحلة حسية لا تُنسى.
|
||||
</p>
|
||||
<p className="text-xl md:text-2xl text-accent leading-relaxed">
|
||||
At Lithos, we don't just serve coffee; we craft an experience. From carefully sourcing premium, sustainable beans to precise roasting, every cup is a testament to our passion. Inspired by raw elegance, Lithos is designed to be your ultimate sanctuary for sensory discovery.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{(primaryButton || undefined) && (
|
||||
<div className="flex flex-wrap gap-3 justify-center mt-2 md:mt-3">
|
||||
{primaryButton && <Button text={primaryButton.text} href={primaryButton.href} variant="primary" />}
|
||||
{undefined && <Button text={undefined.text} href={undefined.href} variant="secondary" animationDelay={0.1} />}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default function StorySection() {
|
||||
return (
|
||||
<div data-webild-section="story" id="story">
|
||||
<StoryInline />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
32
src/pages/HomePage/sections/Testimonials.tsx
Normal file
32
src/pages/HomePage/sections/Testimonials.tsx
Normal file
@@ -0,0 +1,32 @@
|
||||
// AUTO-GENERATED by per-section-migrate. Edit freely — Bob will treat this
|
||||
// file as the canonical source for the "testimonials" section.
|
||||
|
||||
import React from 'react';
|
||||
import TestimonialMarqueeCards from '@/components/sections/testimonial/TestimonialMarqueeCards';
|
||||
import SectionErrorBoundary from "@/components/ui/SectionErrorBoundary";
|
||||
|
||||
export default function TestimonialsSection(): React.JSX.Element {
|
||||
return (
|
||||
<div id="testimonials" data-section="testimonials">
|
||||
<SectionErrorBoundary name="testimonials">
|
||||
<TestimonialMarqueeCards
|
||||
tag="Reviews"
|
||||
title="What Our Community Says"
|
||||
testimonials={[
|
||||
{
|
||||
name: "Sarah J.", role: "Coffee Enthusiast", quote: "The best flat white I have ever had.", imageSrc: "http://img.b2bpic.net/free-photo/portrait-beautiful-girl-dressed-white-pajamas_158538-18356.jpg"},
|
||||
{
|
||||
name: "Michael R.", role: "Regular Patron", quote: "Lithos feels like home away from home.", imageSrc: "http://img.b2bpic.net/free-photo/bearded-male-drinks-coffee-cafe_613910-8838.jpg"},
|
||||
{
|
||||
name: "Elena K.", role: "Design Critic", quote: "Unmatched aesthetic and impeccable coffee.", imageSrc: "http://img.b2bpic.net/free-photo/young-adult-enjoying-beverage_23-2149304428.jpg"},
|
||||
{
|
||||
name: "David W.", role: "Professional", quote: "The perfect spot for my morning meetings.", imageSrc: "http://img.b2bpic.net/free-photo/young-man-texting-cafe-happy-businessman-smiling-texting-smartphone-table_1391-595.jpg"},
|
||||
{
|
||||
name: "Olivia M.", role: "Foodie", quote: "Their danishes are genuinely life-changing.", imageSrc: "http://img.b2bpic.net/free-photo/attractive-casual-african-american-girl-stylish-trench-coat-happily-looking-away-with-coffee-go-cafe-street_574295-2881.jpg"},
|
||||
]}
|
||||
description="Join our community of coffee lovers."
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user