Files
tabatago/app/admin/trainers.tsx
Millian Lamiaux 4458044d0e fix: resolve all 228 TypeScript errors across the project
- Exclude admin-web and supabase/functions from root tsconfig (185 errors)
- Add missing constant exports: FONT_FAMILY_SANS_BOLD/SEMIBOLD, BRAND_DANGER (9 errors)
- Fix React Query API destructuring in admin screens: data/isLoading aliases (12 errors)
- Add getWorkoutsByCategory to data layer, fix category screen types (5 errors)
- Add type assertions for Supabase never types in adminService and sync.ts (13 errors)
- Add missing vitest imports (vi, beforeEach) and replace removed PRIMARY_DARK (5 errors)
- Fix seed.ts to use program.weeks[].workouts[] instead of missing props (4 errors)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 17:53:02 +02:00

195 lines
4.7 KiB
TypeScript

import { useState } from 'react'
import {
View,
Text,
ScrollView,
TouchableOpacity,
StyleSheet,
ActivityIndicator,
Alert,
} from 'react-native'
import { useRouter } from 'expo-router'
import { useTrainers } from '../../src/shared/hooks/useSupabaseData'
import { adminService } from '../../src/admin/services/adminService'
import type { Trainer } from '../../src/shared/types'
export default function AdminTrainersScreen() {
const router = useRouter()
const { data: trainers = [], isLoading: loading, refetch } = useTrainers()
const [deletingId, setDeletingId] = useState<string | null>(null)
const handleDelete = (trainer: Trainer) => {
Alert.alert(
'Delete Trainer',
`Are you sure you want to delete "${trainer.name}"?`,
[
{ text: 'Cancel', style: 'cancel' },
{
text: 'Delete',
style: 'destructive',
onPress: async () => {
setDeletingId(trainer.id)
try {
await adminService.deleteTrainer(trainer.id)
await refetch()
} catch (err) {
Alert.alert('Error', err instanceof Error ? err.message : 'Failed to delete')
} finally {
setDeletingId(null)
}
}
},
]
)
}
if (loading) {
return (
<View style={[styles.container, styles.centered]}>
<ActivityIndicator size="large" color="#FF6B35" />
</View>
)
}
return (
<View style={styles.container}>
<View style={styles.header}>
<TouchableOpacity onPress={() => router.back()} style={styles.backButton}>
<Text style={styles.backText}> Back</Text>
</TouchableOpacity>
<Text style={styles.title}>Trainers</Text>
<TouchableOpacity style={styles.addButton}>
<Text style={styles.addButtonText}>+ Add</Text>
</TouchableOpacity>
</View>
<ScrollView style={styles.content}>
{trainers.map((trainer) => (
<View key={trainer.id} style={styles.trainerCard}>
<View style={[styles.colorIndicator, { backgroundColor: trainer.color }]} />
<View style={styles.trainerInfo}>
<Text style={styles.trainerName}>{trainer.name}</Text>
<Text style={styles.trainerMeta}>
{trainer.specialty} {trainer.workoutCount} workouts
</Text>
</View>
<View style={styles.actions}>
<TouchableOpacity style={styles.editButton}>
<Text style={styles.editText}>Edit</Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.deleteButton, deletingId === trainer.id && styles.disabledButton]}
onPress={() => handleDelete(trainer)}
disabled={deletingId === trainer.id}
>
<Text style={styles.deleteText}>
{deletingId === trainer.id ? '...' : 'Delete'}
</Text>
</TouchableOpacity>
</View>
</View>
))}
</ScrollView>
</View>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#000',
},
centered: {
justifyContent: 'center',
alignItems: 'center',
},
header: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
padding: 20,
paddingTop: 60,
borderBottomWidth: 1,
borderBottomColor: '#1C1C1E',
},
backButton: {
padding: 8,
},
backText: {
color: '#FF6B35',
fontSize: 16,
},
title: {
fontSize: 20,
fontWeight: 'bold',
color: '#fff',
},
addButton: {
backgroundColor: '#FF6B35',
paddingHorizontal: 16,
paddingVertical: 8,
borderRadius: 8,
},
addButtonText: {
color: '#000',
fontWeight: 'bold',
},
content: {
flex: 1,
padding: 16,
},
trainerCard: {
backgroundColor: '#1C1C1E',
borderRadius: 12,
padding: 16,
marginBottom: 12,
flexDirection: 'row',
alignItems: 'center',
},
colorIndicator: {
width: 12,
height: 12,
borderRadius: 6,
marginRight: 12,
},
trainerInfo: {
flex: 1,
},
trainerName: {
fontSize: 16,
fontWeight: 'bold',
color: '#fff',
marginBottom: 4,
},
trainerMeta: {
fontSize: 14,
color: '#999',
},
actions: {
flexDirection: 'row',
gap: 8,
},
editButton: {
backgroundColor: '#2C2C2E',
paddingHorizontal: 12,
paddingVertical: 8,
borderRadius: 6,
},
editText: {
color: '#5AC8FA',
},
deleteButton: {
backgroundColor: '#2C2C2E',
paddingHorizontal: 12,
paddingVertical: 8,
borderRadius: 6,
},
disabledButton: {
opacity: 0.5,
},
deleteText: {
color: '#FF3B30',
},
})