// app/(tabs)/library/exercises.tsx import React, { useState } from 'react'; import { View, ActivityIndicator, ScrollView } from 'react-native'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Search, Dumbbell, ListFilter } from 'lucide-react-native'; import { FloatingActionButton } from '@/components/shared/FloatingActionButton'; import { NewExerciseSheet } from '@/components/library/NewExerciseSheet'; import { SimplifiedExerciseList } from '@/components/exercises/SimplifiedExerciseList'; import { ExerciseDetails } from '@/components/exercises/ExerciseDetails'; import { ExerciseDisplay, ExerciseType, BaseExercise, Equipment } from '@/types/exercise'; import { useExercises } from '@/lib/hooks/useExercises'; import { FilterSheet, type FilterOptions, type SourceType } from '@/components/library/FilterSheet'; // Default available filters const availableFilters = { equipment: ['Barbell', 'Dumbbell', 'Bodyweight', 'Machine', 'Cables', 'Other'], tags: ['Strength', 'Cardio', 'Mobility', 'Recovery'], source: ['local', 'powr', 'nostr'] as SourceType[] }; // Initial filter state const initialFilters: FilterOptions = { equipment: [], tags: [], source: [] }; export default function ExercisesScreen() { const [showNewExercise, setShowNewExercise] = useState(false); const [searchQuery, setSearchQuery] = useState(''); const [selectedExercise, setSelectedExercise] = useState(null); const [filterSheetOpen, setFilterSheetOpen] = useState(false); const [currentFilters, setCurrentFilters] = useState(initialFilters); const [activeFilters, setActiveFilters] = useState(0); const { exercises, loading, error, createExercise, deleteExercise, refreshExercises, updateFilters, clearFilters } = useExercises(); // Filter exercises based on search query React.useEffect(() => { if (searchQuery) { updateFilters({ searchQuery }); } else { updateFilters({ searchQuery: undefined }); } }, [searchQuery, updateFilters]); const handleExercisePress = (exercise: ExerciseDisplay) => { setSelectedExercise(exercise); }; const handleEdit = async () => { // TODO: Implement edit functionality setSelectedExercise(null); }; const handleCreateExercise = async (exerciseData: BaseExercise) => { // Convert BaseExercise to include required source information const exerciseWithSource: Omit = { ...exerciseData, availability: { source: ['local'] } }; await createExercise(exerciseWithSource); setShowNewExercise(false); }; const handleApplyFilters = (filters: FilterOptions) => { setCurrentFilters(filters); const totalFilters = Object.values(filters).reduce( (acc, curr) => acc + curr.length, 0 ); setActiveFilters(totalFilters); // Update the exercises hook filters with proper type casting if (filters.equipment.length > 0) { // Convert string[] to Equipment[] const typedEquipment = filters.equipment.filter(eq => ['bodyweight', 'barbell', 'dumbbell', 'kettlebell', 'machine', 'cable', 'other'].includes(eq.toLowerCase()) ) as Equipment[]; updateFilters({ equipment: typedEquipment }); } if (filters.tags.length > 0) { updateFilters({ tags: filters.tags }); } if (filters.source.length > 0) { updateFilters({ source: filters.source as any[] }); } if (totalFilters === 0) { clearFilters(); } }; return ( {/* Search bar with filter button */} {/* Filter Sheet */} setFilterSheetOpen(false)} options={currentFilters} onApplyFilters={handleApplyFilters} availableFilters={availableFilters} /> {/* Exercises list */} {/* Exercise details sheet */} {selectedExercise && ( { if (!open) setSelectedExercise(null); }} onEdit={handleEdit} /> )} {/* FAB for adding new exercise */} setShowNewExercise(true)} /> {/* New exercise sheet */} setShowNewExercise(false)} onSubmit={handleCreateExercise} /> ); }