fix: resolve trainers page issues and add seed data

- Add SQL seed data for trainers and collections
- Fix React hydration warning with suppressHydrationWarning
- Add empty state UI with friendly messaging
- Add error state UI with retry functionality
- Link Add Trainer buttons to /trainers/new page
This commit is contained in:
Millian Lamiaux
2026-03-17 09:37:00 +01:00
parent b397f1fb17
commit 42d9b2671b
3 changed files with 101 additions and 9 deletions

View File

@@ -4,7 +4,8 @@ import { useEffect, useState } from "react";
import { supabase } from "@/lib/supabase";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { Plus, Trash2, Edit, Loader2 } from "lucide-react";
import { Plus, Trash2, Edit, Loader2, Users, AlertCircle } from "lucide-react";
import Link from "next/link";
import type { Database } from "@/lib/supabase";
type Trainer = Database["public"]["Tables"]["trainers"]["Row"];
@@ -12,6 +13,7 @@ type Trainer = Database["public"]["Tables"]["trainers"]["Row"];
export default function TrainersPage() {
const [trainers, setTrainers] = useState<Trainer[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const [deletingId, setDeletingId] = useState<string | null>(null);
useEffect(() => {
@@ -20,11 +22,13 @@ export default function TrainersPage() {
const fetchTrainers = async () => {
try {
const { data, error } = await supabase.from("trainers").select("*");
setError(null);
const { data, error } = await supabase.from("trainers").select("*").order("name");
if (error) throw error;
setTrainers(data || []);
} catch (error) {
console.error("Failed to fetch trainers:", error);
} catch (err) {
console.error("Failed to fetch trainers:", err);
setError(err instanceof Error ? err.message : "Failed to connect to database");
} finally {
setLoading(false);
}
@@ -53,16 +57,52 @@ export default function TrainersPage() {
<h1 className="text-3xl font-bold text-white mb-2">Trainers</h1>
<p className="text-neutral-400">Manage your fitness trainers</p>
</div>
<Button className="bg-orange-500 hover:bg-orange-600">
<Plus className="w-4 h-4 mr-2" />
Add Trainer
</Button>
<Link href="/trainers/new">
<Button className="bg-orange-500 hover:bg-orange-600">
<Plus className="w-4 h-4 mr-2" />
Add Trainer
</Button>
</Link>
</div>
{loading ? (
<div className="flex justify-center p-8">
<Loader2 className="w-8 h-8 animate-spin text-orange-500" />
</div>
) : error ? (
<div className="flex flex-col items-center justify-center p-12 text-center">
<div className="w-16 h-16 rounded-full bg-red-500/10 flex items-center justify-center mb-4">
<AlertCircle className="w-8 h-8 text-red-500" />
</div>
<h3 className="text-xl font-semibold text-white mb-2">Failed to Load Trainers</h3>
<p className="text-neutral-400 mb-2 max-w-md">{error}</p>
<p className="text-sm text-neutral-500 mb-6">
Make sure your Supabase database is running and the trainers table exists.
</p>
<Button
onClick={fetchTrainers}
variant="outline"
className="border-neutral-700 text-neutral-300 hover:bg-neutral-800"
>
Try Again
</Button>
</div>
) : trainers.length === 0 ? (
<div className="flex flex-col items-center justify-center p-12 text-center">
<div className="w-16 h-16 rounded-full bg-orange-500/10 flex items-center justify-center mb-4">
<Users className="w-8 h-8 text-orange-500" />
</div>
<h3 className="text-xl font-semibold text-white mb-2">No Trainers Yet</h3>
<p className="text-neutral-400 mb-6 max-w-md">
Get started by adding your first trainer. Trainers lead workouts and help users achieve their fitness goals.
</p>
<Link href="/trainers/new">
<Button className="bg-orange-500 hover:bg-orange-600">
<Plus className="w-4 h-4 mr-2" />
Add First Trainer
</Button>
</Link>
</div>
) : (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{trainers.map((trainer) => (