143 lines
8.5 KiB
TypeScript
143 lines
8.5 KiB
TypeScript
import { useState } from "react";
|
|
import { Button } from "@/components/ui/button";
|
|
import { Card, CardContent } from "@/components/ui/card";
|
|
import { Badge } from "@/components/ui/badge";
|
|
import { Clock, User, Users, Flame } from "lucide-react";
|
|
import { useSaasMutation } from "@/hooks/use-tygarun";
|
|
import { toast } from "sonner";
|
|
import Header from "@/components/Header";
|
|
import Footer from "@/components/Footer";
|
|
|
|
const days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
|
|
|
|
const schedule: Record<string, Array<{ time: string; name: string; trainer: string; difficulty: string; capacity: string }>> = {
|
|
Mon: [
|
|
{ time: "6:00 AM", name: "HIIT Burn", trainer: "Sarah Chen", difficulty: "Advanced", capacity: "20/25" },
|
|
{ time: "12:00 PM", name: "Yoga Flow", trainer: "Priya Sharma", difficulty: "All Levels", capacity: "15/30" },
|
|
{ time: "5:30 PM", name: "Power Lift", trainer: "Marcus Rivera", difficulty: "Intermediate", capacity: "18/20" },
|
|
],
|
|
Tue: [
|
|
{ time: "7:00 AM", name: "Yoga Flow", trainer: "Priya Sharma", difficulty: "All Levels", capacity: "12/25" },
|
|
{ time: "12:00 PM", name: "Power Lift", trainer: "Marcus Rivera", difficulty: "Intermediate", capacity: "16/20" },
|
|
{ time: "6:30 PM", name: "Box Fit", trainer: "Dante Williams", difficulty: "Advanced", capacity: "22/25" },
|
|
],
|
|
Wed: [
|
|
{ time: "6:00 AM", name: "HIIT Burn", trainer: "Sarah Chen", difficulty: "Advanced", capacity: "19/25" },
|
|
{ time: "10:00 AM", name: "Pilates Core", trainer: "Priya Sharma", difficulty: "All Levels", capacity: "10/20" },
|
|
{ time: "5:30 PM", name: "Strength Circuit", trainer: "Marcus Rivera", difficulty: "Intermediate", capacity: "17/20" },
|
|
],
|
|
Thu: [
|
|
{ time: "7:00 AM", name: "Box Fit", trainer: "Dante Williams", difficulty: "Intermediate", capacity: "14/25" },
|
|
{ time: "12:00 PM", name: "Yoga Flow", trainer: "Priya Sharma", difficulty: "All Levels", capacity: "8/25" },
|
|
{ time: "6:00 PM", name: "HIIT Burn", trainer: "Sarah Chen", difficulty: "Advanced", capacity: "23/25" },
|
|
],
|
|
Fri: [
|
|
{ time: "6:00 AM", name: "Power Lift", trainer: "Marcus Rivera", difficulty: "Advanced", capacity: "18/20" },
|
|
{ time: "10:00 AM", name: "Stretch & Recover", trainer: "Priya Sharma", difficulty: "All Levels", capacity: "6/20" },
|
|
{ time: "5:00 PM", name: "Fight Club", trainer: "Dante Williams", difficulty: "Advanced", capacity: "20/25" },
|
|
],
|
|
Sat: [
|
|
{ time: "8:00 AM", name: "Full Body Blast", trainer: "Sarah Chen", difficulty: "Intermediate", capacity: "22/30" },
|
|
{ time: "10:00 AM", name: "Yoga Flow", trainer: "Priya Sharma", difficulty: "All Levels", capacity: "15/25" },
|
|
],
|
|
Sun: [
|
|
{ time: "9:00 AM", name: "Recovery Yoga", trainer: "Priya Sharma", difficulty: "All Levels", capacity: "10/25" },
|
|
{ time: "11:00 AM", name: "Open Gym Session", trainer: "Marcus Rivera", difficulty: "All Levels", capacity: "30/50" },
|
|
],
|
|
};
|
|
|
|
const diffColor: Record<string, string> = {
|
|
"Advanced": "bg-red-500/10 text-red-400 border-red-500/30",
|
|
"Intermediate": "bg-orange-500/10 text-orange-400 border-orange-500/30",
|
|
"All Levels": "bg-emerald-500/10 text-emerald-400 border-emerald-500/30",
|
|
};
|
|
|
|
export default function Classes() {
|
|
const [activeDay, setActiveDay] = useState("Mon");
|
|
const { mutate: bookClass, loading: booking } = useSaasMutation("scheduling", "/bookings");
|
|
|
|
return (
|
|
<div className="min-h-screen bg-slate-950 text-white">
|
|
<Header />
|
|
|
|
{/* ── Hero ── */}
|
|
<section className="pt-32 pb-16 bg-gradient-to-b from-slate-900 to-slate-950">
|
|
<div className="mx-auto max-w-7xl px-6 text-center">
|
|
<Badge className="mb-4 bg-orange-500/10 text-orange-400 border-orange-500/30 uppercase text-xs tracking-wider">Schedule</Badge>
|
|
<h1 className="text-4xl md:text-5xl font-black uppercase text-white animate-fade-up">CLASS SCHEDULE</h1>
|
|
<p className="mt-4 text-slate-400 max-w-xl mx-auto">Find the perfect workout for your goals. Book your spot before classes fill up.</p>
|
|
</div>
|
|
</section>
|
|
|
|
{/* ── Day Tabs ── */}
|
|
<section className="py-16">
|
|
<div className="mx-auto max-w-5xl px-6">
|
|
<div className="flex gap-2 justify-center flex-wrap mb-10">
|
|
{days.map((d) => (
|
|
<Button key={d} variant={activeDay === d ? "default" : "outline"} onClick={() => setActiveDay(d)} className={`rounded-full font-bold uppercase tracking-wide text-sm px-6 transition-all ${activeDay === d ? "bg-gradient-to-r from-orange-500 to-red-500 text-white border-0 shadow-lg shadow-orange-500/25" : "border-slate-700 text-slate-400 hover:text-white hover:border-slate-500"}`}>
|
|
{d}
|
|
</Button>
|
|
))}
|
|
</div>
|
|
|
|
<div className="space-y-4">
|
|
{(schedule[activeDay] || []).map((cls, i) => (
|
|
<Card key={i} className="bg-slate-900/80 backdrop-blur border border-slate-800 hover:border-orange-500/30 transition-all duration-300">
|
|
<CardContent className="p-6 flex flex-col md:flex-row md:items-center gap-4 md:gap-8">
|
|
<div className="flex items-center gap-3 md:w-28 shrink-0">
|
|
<Clock className="h-4 w-4 text-orange-400" />
|
|
<span className="font-mono font-bold text-white">{cls.time}</span>
|
|
</div>
|
|
<div className="flex-1">
|
|
<h3 className="font-bold text-white text-lg">{cls.name}</h3>
|
|
<div className="flex items-center gap-2 mt-1 text-sm text-slate-400">
|
|
<User className="h-3.5 w-3.5" />
|
|
<span>{cls.trainer}</span>
|
|
</div>
|
|
</div>
|
|
<Badge className={`${diffColor[cls.difficulty] || ""} text-xs uppercase tracking-wider`}>{cls.difficulty}</Badge>
|
|
<div className="flex items-center gap-2 text-sm text-slate-400 md:w-24 shrink-0">
|
|
<Users className="h-4 w-4" />
|
|
<span>{cls.capacity}</span>
|
|
</div>
|
|
<Button size="sm" disabled={booking} className="bg-gradient-to-r from-orange-500 to-red-500 hover:from-orange-600 hover:to-red-600 text-white font-bold uppercase text-xs rounded-full px-6 active:scale-[0.97] transition-all shrink-0" onClick={async () => { try { await bookClass({ class: cls.name, day: activeDay, time: cls.time, trainer: cls.trainer }); toast.success("Spot booked! See you on the mat."); } catch { toast.error("Could not book. Please try again."); } }}>
|
|
{booking ? "Booking…" : "Book"}
|
|
</Button>
|
|
</CardContent>
|
|
</Card>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
{/* ── Class Info Cards ── */}
|
|
<section className="py-16 bg-slate-900/50">
|
|
<div className="mx-auto max-w-5xl px-6 grid sm:grid-cols-3 gap-6">
|
|
<Card className="bg-slate-900/80 backdrop-blur border border-slate-800 hover:border-orange-500/30 hover:-translate-y-1 hover:shadow-lg transition-all duration-300">
|
|
<CardContent className="p-6 text-center">
|
|
<Flame className="h-8 w-8 text-orange-400 mx-auto mb-3" />
|
|
<h3 className="font-bold text-white mb-1">First Class Free</h3>
|
|
<p className="text-sm text-slate-400">Try any class with no commitment. Just sign up and show up.</p>
|
|
</CardContent>
|
|
</Card>
|
|
<Card className="bg-slate-900/80 backdrop-blur border border-slate-800 hover:border-orange-500/30 hover:-translate-y-1 hover:shadow-lg transition-all duration-300">
|
|
<CardContent className="p-6 text-center">
|
|
<Clock className="h-8 w-8 text-orange-400 mx-auto mb-3" />
|
|
<h3 className="font-bold text-white mb-1">45-60 Min Sessions</h3>
|
|
<p className="text-sm text-slate-400">Efficient workouts designed to maximize results in minimal time.</p>
|
|
</CardContent>
|
|
</Card>
|
|
<Card className="bg-slate-900/80 backdrop-blur border border-slate-800 hover:border-orange-500/30 hover:-translate-y-1 hover:shadow-lg transition-all duration-300">
|
|
<CardContent className="p-6 text-center">
|
|
<Users className="h-8 w-8 text-orange-400 mx-auto mb-3" />
|
|
<h3 className="font-bold text-white mb-1">Small Groups</h3>
|
|
<p className="text-sm text-slate-400">Capped at 25 so every member gets personal attention from the trainer.</p>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
</section>
|
|
|
|
<Footer />
|
|
</div>
|
|
);
|
|
} |