Seed: wedding template (15 files)
This commit is contained in:
@@ -0,0 +1,204 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card, CardContent } from "@/components/ui/card";
|
||||
import { Heart, Calendar, Clock, MapPin, ArrowRight, Camera } from "lucide-react";
|
||||
import Header from "@/components/Header";
|
||||
import Footer from "@/components/Footer";
|
||||
|
||||
const storyTimeline = [
|
||||
{ year: "2020", title: "How We Met", desc: "A chance encounter at a mutual friends birthday party changed everything. One conversation turned into hours of laughter.", gradient: "from-rose-400 to-pink-300" },
|
||||
{ year: "2020", title: "First Date", desc: "Our first official date was at a cozy Italian restaurant downtown. We closed the place down talking until midnight.", gradient: "from-pink-300 to-rose-200" },
|
||||
{ year: "2025", title: "The Proposal", desc: "A magical sunset proposal on the beach with family hiding behind the dunes, ready to celebrate with champagne.", gradient: "from-rose-300 to-amber-200" },
|
||||
{ year: "2026", title: "The Big Day", desc: "The day we have been dreaming of. Surrounded by our favorite people in our favorite place.", gradient: "from-amber-200 to-rose-300" },
|
||||
];
|
||||
|
||||
const bridesmaids = [
|
||||
{ name: "Emma Wilson", role: "Maid of Honor", initials: "EW", gradient: "from-rose-300 to-pink-200" },
|
||||
{ name: "Lucy Martin", role: "Bridesmaid", initials: "LM", gradient: "from-pink-300 to-rose-200" },
|
||||
{ name: "Julia Chen", role: "Bridesmaid", initials: "JC", gradient: "from-rose-200 to-pink-300" },
|
||||
{ name: "Kate Ross", role: "Bridesmaid", initials: "KR", gradient: "from-pink-200 to-rose-300" },
|
||||
];
|
||||
|
||||
const groomsmen = [
|
||||
{ name: "Mike Torres", role: "Best Man", initials: "MT", gradient: "from-stone-400 to-stone-300" },
|
||||
{ name: "David Park", role: "Groomsman", initials: "DP", gradient: "from-stone-300 to-stone-400" },
|
||||
{ name: "Ryan Kim", role: "Groomsman", initials: "RK", gradient: "from-stone-400 to-stone-300" },
|
||||
{ name: "Ben Hayes", role: "Groomsman", initials: "BH", gradient: "from-stone-300 to-stone-400" },
|
||||
];
|
||||
|
||||
export default function IndexPage() {
|
||||
const [countdown, setCountdown] = useState({ days: 0, hours: 0, minutes: 0, seconds: 0 });
|
||||
|
||||
useEffect(() => {
|
||||
const target = new Date("2026-06-15T16:00:00").getTime();
|
||||
const tick = () => {
|
||||
const now = Date.now();
|
||||
const diff = Math.max(0, target - now);
|
||||
setCountdown({
|
||||
days: Math.floor(diff / (1000 * 60 * 60 * 24)),
|
||||
hours: Math.floor((diff / (1000 * 60 * 60)) % 24),
|
||||
minutes: Math.floor((diff / (1000 * 60)) % 60),
|
||||
seconds: Math.floor((diff / 1000) % 60),
|
||||
});
|
||||
};
|
||||
tick();
|
||||
const id = setInterval(tick, 1000);
|
||||
return () => clearInterval(id);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-white dark:bg-stone-950">
|
||||
<Header />
|
||||
|
||||
{/* ── Hero ─────────────────────────────────────── */}
|
||||
<section className="relative min-h-screen flex items-center justify-center overflow-hidden">
|
||||
<div className="absolute inset-0 bg-gradient-to-br from-rose-100 via-pink-50 to-amber-50 dark:from-stone-900 dark:via-stone-950 dark:to-stone-900" />
|
||||
<div className="absolute inset-0 opacity-20">
|
||||
<div className="absolute top-20 left-10 w-72 h-72 bg-rose-300 rounded-full blur-3xl animate-pulse" />
|
||||
<div className="absolute bottom-20 right-10 w-96 h-96 bg-pink-200 rounded-full blur-3xl animate-pulse" style={{ animationDelay: "1s" }} />
|
||||
</div>
|
||||
<div className="relative text-center px-6 max-w-3xl">
|
||||
<p className="text-rose-400 text-sm uppercase tracking-[0.3em] mb-4 font-medium">We are getting married</p>
|
||||
<h1 className="font-serif text-5xl sm:text-7xl md:text-8xl text-stone-800 dark:text-white leading-tight mb-6">Sarah & James</h1>
|
||||
<div className="w-24 h-px bg-rose-300 mx-auto mb-6" />
|
||||
<p className="text-lg text-stone-600 dark:text-stone-300 mb-10 font-serif">June 15, 2026 · Rosewood Manor</p>
|
||||
<div className="flex justify-center gap-4 sm:gap-8 mb-10">
|
||||
{[{ label: "Days", value: countdown.days }, { label: "Hours", value: countdown.hours }, { label: "Mins", value: countdown.minutes }, { label: "Secs", value: countdown.seconds }].map((unit) => (
|
||||
<div key={unit.label} className="text-center">
|
||||
<div className="text-3xl sm:text-5xl font-serif text-rose-500 dark:text-rose-400">{String(unit.value).padStart(2, "0")}</div>
|
||||
<div className="text-xs uppercase tracking-wider text-stone-500 mt-1">{unit.label}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<Button asChild size="lg" className="bg-rose-400 hover:bg-rose-500 active:scale-[0.98] text-white rounded-full px-10 text-base">
|
||||
<Link to="/rsvp"><Heart className="h-4 w-4 mr-2 fill-white" />RSVP Now</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ── Our Story ────────────────────────────────── */}
|
||||
<section id="story" className="py-24 bg-white dark:bg-stone-950">
|
||||
<div className="mx-auto max-w-4xl px-6">
|
||||
<p className="text-rose-400 text-sm uppercase tracking-[0.2em] text-center mb-2">Our Journey</p>
|
||||
<h2 className="font-serif text-3xl sm:text-4xl text-center text-stone-800 dark:text-white mb-16 animate-fade-up">Our Love Story</h2>
|
||||
<div className="relative">
|
||||
<div className="absolute left-1/2 -translate-x-px top-0 bottom-0 w-px bg-rose-200 dark:bg-stone-700 hidden md:block" />
|
||||
{storyTimeline.map((item, i) => (
|
||||
<div key={i} className={`relative flex flex-col md:flex-row items-center gap-6 mb-16 last:mb-0 animate-fade-up \${i % 2 === 1 ? "md:flex-row-reverse" : ""}`} style={{ animationDelay: `\${i * 150}ms` }}>
|
||||
<div className={`flex-1 backdrop-blur-sm bg-card/80 border border-border/50 rounded-xl p-5 \${i % 2 === 1 ? "md:text-left" : "md:text-right"}`}>
|
||||
<span className="text-sm text-rose-400 font-medium">{item.year}</span>
|
||||
<h3 className="font-serif text-xl text-stone-800 dark:text-white mt-1 mb-2">{item.title}</h3>
|
||||
<p className="text-stone-600 dark:text-stone-400 text-sm leading-relaxed">{item.desc}</p>
|
||||
</div>
|
||||
<div className={`w-12 h-12 rounded-full bg-gradient-to-br \${item.gradient} flex items-center justify-center shadow-lg z-10 shrink-0`}>
|
||||
<Heart className="h-5 w-5 text-white fill-white" />
|
||||
</div>
|
||||
<div className="flex-1 hidden md:block" />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ── Wedding Party ────────────────────────────── */}
|
||||
<section className="py-24 bg-rose-50/50 dark:bg-stone-900">
|
||||
<div className="mx-auto max-w-6xl px-6">
|
||||
<p className="text-rose-400 text-sm uppercase tracking-[0.2em] text-center mb-2">The Wedding Party</p>
|
||||
<h2 className="font-serif text-3xl sm:text-4xl text-center text-stone-800 dark:text-white mb-16 animate-fade-up">Our Closest People</h2>
|
||||
<div className="grid md:grid-cols-2 gap-16">
|
||||
<div>
|
||||
<h3 className="font-serif text-xl text-center text-rose-500 mb-8">Bridesmaids</h3>
|
||||
<div className="grid grid-cols-2 gap-6 stagger">
|
||||
{bridesmaids.map((p, i) => (
|
||||
<Card key={i} className="border-border/50 backdrop-blur-sm bg-card/80 text-center overflow-hidden hover:-translate-y-1 hover:shadow-lg transition-all duration-300">
|
||||
<CardContent className="pt-6 pb-4">
|
||||
<div className={`w-16 h-16 rounded-full bg-gradient-to-br \${p.gradient} flex items-center justify-center mx-auto mb-3 text-white font-serif text-lg`}>{p.initials}</div>
|
||||
<div className="font-medium text-stone-800 dark:text-white text-sm">{p.name}</div>
|
||||
<div className="text-xs text-rose-400 mt-1">{p.role}</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-serif text-xl text-center text-stone-500 dark:text-stone-300 mb-8">Groomsmen</h3>
|
||||
<div className="grid grid-cols-2 gap-6 stagger">
|
||||
{groomsmen.map((p, i) => (
|
||||
<Card key={i} className="border-border/50 backdrop-blur-sm bg-card/80 text-center overflow-hidden hover:-translate-y-1 hover:shadow-lg transition-all duration-300">
|
||||
<CardContent className="pt-6 pb-4">
|
||||
<div className={`w-16 h-16 rounded-full bg-gradient-to-br \${p.gradient} flex items-center justify-center mx-auto mb-3 text-white font-serif text-lg`}>{p.initials}</div>
|
||||
<div className="font-medium text-stone-800 dark:text-white text-sm">{p.name}</div>
|
||||
<div className="text-xs text-stone-400 mt-1">{p.role}</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ── Gallery Preview ──────────────────────────── */}
|
||||
<section className="py-24 bg-white dark:bg-stone-950">
|
||||
<div className="mx-auto max-w-6xl px-6">
|
||||
<p className="text-rose-400 text-sm uppercase tracking-[0.2em] text-center mb-2">Captured Moments</p>
|
||||
<h2 className="font-serif text-3xl sm:text-4xl text-center text-stone-800 dark:text-white mb-16 animate-fade-up">Photo Gallery</h2>
|
||||
<div className="grid grid-cols-2 md:grid-cols-3 gap-4 stagger">
|
||||
{[
|
||||
{ h: "h-64", gradient: "from-rose-300 to-pink-200" },
|
||||
{ h: "h-80", gradient: "from-pink-200 to-rose-300" },
|
||||
{ h: "h-64", gradient: "from-amber-200 to-rose-200" },
|
||||
{ h: "h-80", gradient: "from-rose-200 to-pink-300" },
|
||||
{ h: "h-64", gradient: "from-pink-300 to-amber-200" },
|
||||
{ h: "h-80", gradient: "from-rose-300 to-amber-100" },
|
||||
].map((item, i) => (
|
||||
<div key={i} className={`\${item.h} rounded-xl bg-gradient-to-br \${item.gradient} overflow-hidden group cursor-pointer relative hover:-translate-y-1 hover:shadow-lg transition-all duration-300`}>
|
||||
<div className="absolute inset-0 bg-black/0 group-hover:bg-black/20 transition-colors flex items-center justify-center">
|
||||
<Camera className="h-8 w-8 text-white opacity-0 group-hover:opacity-100 transition-opacity" />
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="text-center mt-10">
|
||||
<Button asChild variant="outline" className="rounded-full border-rose-300 text-rose-500 hover:bg-rose-50 dark:border-stone-600 dark:text-rose-400 dark:hover:bg-stone-800">
|
||||
<Link to="/gallery">View Full Gallery <ArrowRight className="h-4 w-4 ml-2" /></Link>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ── Details Preview ──────────────────────────── */}
|
||||
<section className="py-24 bg-rose-50/50 dark:bg-stone-900">
|
||||
<div className="mx-auto max-w-4xl px-6">
|
||||
<p className="text-rose-400 text-sm uppercase tracking-[0.2em] text-center mb-2">Save the Date</p>
|
||||
<h2 className="font-serif text-3xl sm:text-4xl text-center text-stone-800 dark:text-white mb-16 animate-fade-up">Wedding Details</h2>
|
||||
<div className="grid sm:grid-cols-3 gap-6 stagger">
|
||||
{[
|
||||
{ icon: Calendar, label: "Date", value: "June 15, 2026" },
|
||||
{ icon: Clock, label: "Time", value: "4:00 PM" },
|
||||
{ icon: MapPin, label: "Venue", value: "Rosewood Manor" },
|
||||
].map((item, i) => (
|
||||
<Card key={i} className="border-border/50 backdrop-blur-sm bg-card/80 text-center hover:shadow-lg transition-shadow">
|
||||
<CardContent className="pt-8 pb-6">
|
||||
<div className="w-12 h-12 rounded-full bg-rose-100 dark:bg-stone-700 flex items-center justify-center mx-auto mb-4">
|
||||
<item.icon className="h-5 w-5 text-rose-400" />
|
||||
</div>
|
||||
<div className="text-xs uppercase tracking-wider text-rose-400 mb-1">{item.label}</div>
|
||||
<div className="font-serif text-lg text-stone-800 dark:text-white">{item.value}</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
<div className="text-center mt-10">
|
||||
<Button asChild variant="outline" className="rounded-full border-rose-300 text-rose-500 hover:bg-rose-50 dark:border-stone-600 dark:text-rose-400 dark:hover:bg-stone-800">
|
||||
<Link to="/details">View All Details <ArrowRight className="h-4 w-4 ml-2" /></Link>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user