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

@@ -19,7 +19,7 @@ export default function RootLayout({
children: React.ReactNode;
}>) {
return (
<html lang="en" className="dark">
<html lang="en" className="dark" suppressHydrationWarning>
<body className={`${geistSans.variable} antialiased bg-neutral-950 text-white`}>
<div className="flex min-h-screen">
<Sidebar />

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) => (

52
supabase/seed.sql Normal file
View File

@@ -0,0 +1,52 @@
-- ============================================================
-- TabataFit Seed Data
-- ============================================================
-- Run this SQL in Supabase SQL Editor to populate your database with sample data
-- Sample Trainers
INSERT INTO public.trainers (name, specialty, color, workout_count) VALUES
('Sarah Chen', 'HIIT & Cardio', '#FF6B35', 12),
('Marcus Johnson', 'Strength Training', '#5AC8FA', 8),
('Elena Rodriguez', 'Yoga & Mobility', '#30D158', 15),
('David Kim', 'Full Body Conditioning', '#FF9500', 10);
-- Sample Collections
INSERT INTO public.collections (title, description, icon, gradient) VALUES
('Quick Burns', 'High-intensity workouts under 10 minutes', 'flame', ARRAY['#FF6B35', '#FF9500']),
('Core Strength', 'Build a solid foundation', 'shield', ARRAY['#5AC8FA', '#30D158']),
('Cardio Blast', 'Get your heart pumping', 'heart', ARRAY['#FF6B35', '#FF3B30']),
('Total Body', 'Full body workouts for maximum results', 'body', ARRAY['#30D158', '#5856D6']);
-- Note: Workouts will be added after trainers are created (they reference trainer_ids)
-- To add workouts, first note the UUIDs generated for trainers above, then:
-- Sample Workout (uncomment and update trainer_id after running above)
-- INSERT INTO public.workouts (
-- title, trainer_id, category, level, duration, calories, rounds,
-- prep_time, work_time, rest_time, equipment, music_vibe, exercises, is_featured
-- ) VALUES (
-- 'Morning Ignite',
-- 'PASTE_TRAINER_UUID_HERE',
-- 'full-body',
-- 'Beginner',
-- 4,
-- 45,
-- 8,
-- 10,
-- 20,
-- 10,
-- ARRAY['yoga-mat'],
-- 'electronic',
-- '[{"name": "Jumping Jacks", "duration": 20}, {"name": "Push-ups", "duration": 20}, {"name": "Squats", "duration": 20}, {"name": "Plank", "duration": 20}]'::jsonb,
-- true
-- );
-- Update trainer workout counts
UPDATE public.trainers SET workout_count = 12 WHERE name = 'Sarah Chen';
UPDATE public.trainers SET workout_count = 8 WHERE name = 'Marcus Johnson';
UPDATE public.trainers SET workout_count = 15 WHERE name = 'Elena Rodriguez';
UPDATE public.trainers SET workout_count = 10 WHERE name = 'David Kim';
-- Verify data
SELECT * FROM public.trainers ORDER BY name;
SELECT * FROM public.collections ORDER BY title;