Seed: event template (15 files)
This commit is contained in:
@@ -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>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user