// app/(tabs)/library/exercises.tsx import React, { useState, useEffect, useRef } from 'react'; import { View, SectionList, TouchableOpacity, SectionListData } from 'react-native'; import { Text } from '@/components/ui/text'; import { ExerciseCard } from '@/components/exercises/ExerciseCard'; import { FloatingActionButton } from '@/components/shared/FloatingActionButton'; import { NewExerciseSheet } from '@/components/library/NewExerciseSheet'; import { Dumbbell } from 'lucide-react-native'; import { Exercise, BaseExercise } from '@/types/exercise'; import { useSQLiteContext } from 'expo-sqlite'; import { ExerciseService } from '@/lib/db/services/ExerciseService'; interface ExerciseSection { title: string; data: Exercise[]; } export default function ExercisesScreen() { const db = useSQLiteContext(); const exerciseService = React.useMemo(() => new ExerciseService(db), [db]); const sectionListRef = useRef(null); const [exercises, setExercises] = useState([]); const [sections, setSections] = useState([]); const [showNewExercise, setShowNewExercise] = useState(false); useEffect(() => { loadExercises(); }, []); useEffect(() => { // Organize exercises into sections when exercises array changes const exercisesByLetter = exercises.reduce((acc, exercise) => { const firstLetter = exercise.title[0].toUpperCase(); if (!acc[firstLetter]) { acc[firstLetter] = []; } acc[firstLetter].push(exercise); return acc; }, {} as Record); // Create sections array sorted alphabetically const newSections = Object.entries(exercisesByLetter) .map(([letter, exercises]) => ({ title: letter, data: exercises.sort((a, b) => a.title.localeCompare(b.title)) })) .sort((a, b) => a.title.localeCompare(b.title)); setSections(newSections); }, [exercises]); const loadExercises = async () => { try { const loadedExercises = await exerciseService.getAllExercises(); setExercises(loadedExercises); } catch (error) { console.error('Error loading exercises:', error); } }; const handleAddExercise = async (exerciseData: BaseExercise) => { try { await exerciseService.createExercise({ ...exerciseData, created_at: Date.now(), source: 'local' }); await loadExercises(); setShowNewExercise(false); } catch (error) { console.error('Error adding exercise:', error); } }; const handleDelete = async (id: string) => { try { await exerciseService.deleteExercise(id); await loadExercises(); } catch (error) { console.error('Error deleting exercise:', error); } }; const handleExercisePress = (exerciseId: string) => { console.log('Selected exercise:', exerciseId); }; const scrollToSection = (letter: string) => { const sectionIndex = sections.findIndex(section => section.title === letter); if (sectionIndex !== -1) { sectionListRef.current?.scrollToLocation({ sectionIndex, itemIndex: 0, animated: true, viewOffset: 20 }); } }; const alphabet = '#ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(''); const availableLetters = new Set(sections.map(section => section.title)); return ( {alphabet.map((letter) => ( scrollToSection(letter)} className="py-0.5" > {letter} ))} item.id} renderSectionHeader={({ section }) => ( {section.title} )} renderItem={({ item }) => ( handleExercisePress(item.id)} onDelete={() => handleDelete(item.id)} /> )} stickySectionHeadersEnabled className="flex-1" /> setShowNewExercise(true)} /> setShowNewExercise(false)} onSubmit={handleAddExercise} /> ); }