Files
juanitosport/app/admin/classes/classes-admin.tsx
T

117 lines
3.7 KiB
TypeScript

"use client";
import { useState } from "react";
import { useRouter } from "next/navigation";
const SPORT_LABEL: Record<string, { icon: string; name: string }> = {
"muay-thai": { icon: "🥊", name: "Muay Thai" },
yoga: { icon: "🧘", name: "Yoga" },
};
export default function AdminClasses({ slots }: { slots: any[] }) {
const router = useRouter();
return (
<div className="space-y-4">
<h2 className="text-lg font-bold">📅 Cours & places disponibles</h2>
<p className="text-sm text-white/60">
Renseigne le nombre de places pour chaque cours. Quand les places sont
épuisées, le cours s&apos;affiche «&nbsp;COMPLET&nbsp;» sur le site.
</p>
<div className="space-y-4">
{slots.map((slot) => (
<SlotCard key={slot.id} slot={slot} onUpdate={() => router.refresh()} />
))}
</div>
</div>
);
}
function SlotCard({ slot, onUpdate }: { slot: any; onUpdate: () => void }) {
const sport = SPORT_LABEL[slot.sport] || { icon: "🏅", name: slot.sport };
const [capacity, setCapacity] = useState(String(slot.capacity));
const [booked, setBooked] = useState(String(slot.booked));
const [isFull, setIsFull] = useState(slot.isFull);
const [saving, setSaving] = useState(false);
const capacityNum = Math.max(0, parseInt(capacity) || 0);
const bookedNum = Math.max(0, parseInt(booked) || 0);
const remaining = Math.max(0, capacityNum - bookedNum);
const full = isFull || remaining === 0;
async function save() {
setSaving(true);
const res = await fetch("/api/admin/classes", {
method: "PATCH",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ id: slot.id, capacity, booked, isFull }),
});
setSaving(false);
if (res.ok) onUpdate();
}
return (
<div className="card">
<div className="mb-3 flex items-center justify-between">
<div className="flex items-center gap-3">
<span className="text-2xl">{sport.icon}</span>
<div>
<p className="font-bold">
{sport.name} — {slot.label}
</p>
<p className="text-xs text-white/50">{slot.time}</p>
</div>
</div>
<span
className={`rounded-full px-3 py-1 text-xs font-bold ${
full
? "bg-red-500/20 text-red-300"
: remaining <= 3
? "bg-amber-500/20 text-amber-300"
: "bg-emerald-500/20 text-emerald-300"
}`}
>
{full ? "❌ COMPLET" : `${remaining} places libres`}
</span>
</div>
<div className="grid grid-cols-2 gap-3">
<div>
<label className="label">Capacité totale</label>
<input
type="number"
min="0"
className="input"
value={capacity}
onChange={(e) => setCapacity(e.target.value)}
/>
</div>
<div>
<label className="label">Places occupées</label>
<input
type="number"
min="0"
className="input"
value={booked}
onChange={(e) => setBooked(e.target.value)}
/>
</div>
</div>
<label className="mt-3 flex cursor-pointer items-center gap-2 rounded-xl bg-white/5 px-4 py-2 text-sm">
<input
type="checkbox"
checked={isFull}
onChange={(e) => setIsFull(e.target.checked)}
className="h-4 w-4 accent-red-600"
/>
<span className="font-semibold text-red-300">Marquer ce cours comme COMPLET</span>
</label>
<button onClick={save} className="btn-primary mt-3 w-full" disabled={saving}>
{saving ? "Enregistrement..." : "💾 Enregistrer"}
</button>
</div>
);
}