Seed: event template (15 files)

This commit is contained in:
2026-07-23 22:11:00 +00:00
parent 23312c2f61
commit c0a13d1623
+127
View File
@@ -0,0 +1,127 @@
import { useState } from "react";
import { Link } from "react-router-dom";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Clock, MapPin, Coffee } from "lucide-react";
import Header from "@/components/Header";
import Footer from "@/components/Footer";
const tracks = ["All", "Frontend", "Backend", "Design", "DevOps"];
const typeBadgeColor: Record<string, string> = {
Keynote: "bg-indigo-500/20 text-indigo-300 border-indigo-500/30",
Talk: "bg-cyan-500/20 text-cyan-300 border-cyan-500/30",
Workshop: "bg-emerald-500/20 text-emerald-300 border-emerald-500/30",
Panel: "bg-amber-500/20 text-amber-300 border-amber-500/30",
};
const schedule = {
"Day 1": [
{ time: "09:00", title: "Opening Keynote: The Future of Web", speaker: "Sarah Kim", room: "Main Hall", type: "Keynote", track: "Frontend" },
{ time: "10:00", title: "React Server Components in Production", speaker: "Alex Morgan", room: "Room A", type: "Talk", track: "Frontend" },
{ time: "11:00", title: "", speaker: "", room: "", type: "Break", track: "" },
{ time: "11:30", title: "Building Scalable APIs with Edge Functions", speaker: "Raj Joshi", room: "Workshop Lab", type: "Workshop", track: "Backend" },
{ time: "12:30", title: "", speaker: "", room: "", type: "Lunch", track: "" },
{ time: "14:00", title: "Design Systems That Scale", speaker: "Lisa Park", room: "Room B", type: "Talk", track: "Design" },
{ time: "15:00", title: "Panel: Infrastructure as Code in 2026", speaker: "Diana Nguyen + Panel", room: "Main Hall", type: "Panel", track: "DevOps" },
{ time: "16:30", title: "Signals, Reactivity & Beyond", speaker: "Tom Walsh", room: "Room A", type: "Talk", track: "Frontend" },
],
"Day 2": [
{ time: "09:00", title: "Keynote: AI-Native Development", speaker: "Raj Joshi", room: "Main Hall", type: "Keynote", track: "Backend" },
{ time: "10:00", title: "Zero-Downtime Deployments at Scale", speaker: "Diana Nguyen", room: "Room A", type: "Talk", track: "DevOps" },
{ time: "11:00", title: "", speaker: "", room: "", type: "Break", track: "" },
{ time: "11:30", title: "Figma to Code: Bridging the Gap", speaker: "Lisa Park", room: "Workshop Lab", type: "Workshop", track: "Design" },
{ time: "12:30", title: "", speaker: "", room: "", type: "Lunch", track: "" },
{ time: "14:00", title: "Full-Stack TypeScript Patterns", speaker: "Alex Morgan", room: "Room B", type: "Talk", track: "Frontend" },
{ time: "15:00", title: "Panel: The State of Serverless", speaker: "Tom Walsh + Panel", room: "Main Hall", type: "Panel", track: "Backend" },
{ time: "16:30", title: "Kubernetes for Frontend Developers", speaker: "Diana Nguyen", room: "Workshop Lab", type: "Workshop", track: "DevOps" },
],
"Day 3": [
{ time: "09:00", title: "Keynote: Designing for the AI Era", speaker: "Lisa Park", room: "Main Hall", type: "Keynote", track: "Design" },
{ time: "10:00", title: "GraphQL Federation at Scale", speaker: "Raj Joshi", room: "Room A", type: "Talk", track: "Backend" },
{ time: "11:00", title: "", speaker: "", room: "", type: "Break", track: "" },
{ time: "11:30", title: "Micro-Frontends: Lessons Learned", speaker: "Sarah Kim", room: "Room B", type: "Talk", track: "Frontend" },
{ time: "12:30", title: "", speaker: "", room: "", type: "Lunch", track: "" },
{ time: "14:00", title: "GitOps Workshop: From Zero to Production", speaker: "Diana Nguyen", room: "Workshop Lab", type: "Workshop", track: "DevOps" },
{ time: "15:30", title: "Panel: The Future of JavaScript Runtimes", speaker: "Tom Walsh + Panel", room: "Main Hall", type: "Panel", track: "Frontend" },
{ time: "17:00", title: "Closing Keynote: Building What Matters", speaker: "Sarah Kim", room: "Main Hall", type: "Keynote", track: "Backend" },
],
};
export default function SchedulePage() {
const [activeTrack, setActiveTrack] = useState("All");
return (
<div className="min-h-screen bg-slate-950 text-white">
<Header />
{/* Hero */}
<section className="pt-32 pb-24 text-center px-6">
<h1 className="text-5xl font-black tracking-tight mb-4 animate-fade-up">Schedule</h1>
<p className="text-slate-400 max-w-xl mx-auto">Three days packed with keynotes, workshops, and deep-dive sessions.</p>
</section>
{/* Track Filters */}
<section className="px-6">
<div className="mx-auto max-w-5xl flex flex-wrap gap-2 justify-center mb-8">
{tracks.map((t) => (
<Button key={t} variant={activeTrack === t ? "default" : "outline"} size="sm" onClick={() => setActiveTrack(t)} className={activeTrack === t ? "bg-indigo-600 hover:bg-indigo-500 active:scale-[0.98] text-white" : "border-slate-700 text-slate-300 hover:bg-slate-800 active:scale-[0.98]"}>
{t}
</Button>
))}
</div>
</section>
{/* Day Tabs */}
<section className="px-6 pb-24">
<div className="mx-auto max-w-5xl">
<Tabs defaultValue="Day 1">
<TabsList className="bg-slate-900 border border-slate-800 mb-8">
{Object.keys(schedule).map((day) => (
<TabsTrigger key={day} value={day} className="data-[state=active]:bg-indigo-600 data-[state=active]:text-white">{day}</TabsTrigger>
))}
</TabsList>
{Object.entries(schedule).map(([day, sessions]) => (
<TabsContent key={day} value={day}>
<div className="space-y-4">
{sessions.filter((s) => activeTrack === "All" || s.track === activeTrack || s.type === "Break" || s.type === "Lunch").map((s, i) => (
s.type === "Break" || s.type === "Lunch" ? (
<div key={i} className="flex items-center gap-4 px-4 py-3 rounded-lg bg-slate-800/30 border border-slate-800/50">
<Coffee className="h-4 w-4 text-slate-500" />
<span className="text-sm text-slate-500 italic">{s.time} {s.type === "Break" ? "Coffee Break" : "Lunch Break"}</span>
</div>
) : (
<Card key={i} className={`bg-slate-900/50 border-slate-800 hover:border-indigo-500/50 hover:-translate-x-1 transition-all duration-300 \${s.type === "Keynote" ? "border-l-2 border-l-cyan-400" : s.type === "Workshop" ? "border-l-2 border-l-emerald-400" : s.type === "Panel" ? "border-l-2 border-l-purple-400" : ""}`}>
<CardContent className="p-4 flex flex-col md:flex-row md:items-center gap-4">
<div className="flex items-center gap-2 md:w-24 shrink-0">
<Clock className="h-4 w-4 text-indigo-400" />
<span className="text-sm font-medium text-indigo-400">{s.time}</span>
</div>
<div className="border-l border-slate-700 pl-4 flex-1 relative before:absolute before:left-[-5px] before:top-1/2 before:-translate-y-1/2 before:w-2 before:h-2 before:rounded-full before:bg-indigo-500">
<div className="font-semibold text-white mb-1">{s.title}</div>
<div className="flex items-center gap-2">
<Link to="/speakers" className="text-sm text-slate-400 hover:text-indigo-400 transition-colors">{s.speaker}</Link>
{s.type === "Keynote" && <span className="text-[10px] text-slate-500">~200 seats</span>}
</div>
</div>
<div className="flex items-center gap-2 shrink-0">
<Badge variant="outline" className="border-slate-700 text-slate-400"><MapPin className="h-3 w-3 mr-1" />{s.room}</Badge>
<Badge variant="outline" className={typeBadgeColor[s.type] || ""}>{s.type}</Badge>
</div>
</CardContent>
</Card>
)
))}
</div>
</TabsContent>
))}
</Tabs>
</div>
</section>
<Footer />
</div>
);
}