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:
@@ -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 />
|
||||
|
||||
@@ -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
52
supabase/seed.sql
Normal 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;
|
||||
Reference in New Issue
Block a user