// components/exercises/SimplifiedExerciseList.tsx import React, { useRef, useState, useCallback } from 'react'; import { View, SectionList, TouchableOpacity, ViewToken } from 'react-native'; import { Text } from '@/components/ui/text'; import { Badge } from '@/components/ui/badge'; import { ExerciseDisplay, WorkoutExercise } from '@/types/exercise'; import { Trash2 } from 'lucide-react-native'; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, } from '@/components/ui/alert-dialog'; // Create a combined interface for exercises that could have workout data interface DisplayWorkoutExercise extends ExerciseDisplay, WorkoutExercise {} interface SimplifiedExerciseListProps { exercises: ExerciseDisplay[]; onExercisePress: (exercise: ExerciseDisplay) => void; onDeletePress?: (exercise: ExerciseDisplay) => void; // Add this } export const SimplifiedExerciseList = ({ exercises, onExercisePress, onDeletePress }: SimplifiedExerciseListProps) => { const sectionListRef = useRef(null); const [currentSection, setCurrentSection] = useState(''); const [exerciseToDelete, setExerciseToDelete] = useState(null); const [showDeleteAlert, setShowDeleteAlert] = useState(false); const handleDeletePress = (exercise: ExerciseDisplay) => { setExerciseToDelete(exercise); setShowDeleteAlert(true); }; // Organize exercises into sections const sections = React.useMemo(() => { 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); return 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)); }, [exercises]); const handleViewableItemsChanged = useCallback(({ viewableItems }: { viewableItems: ViewToken[]; }) => { const firstSection = viewableItems.find(item => item.section)?.section?.title; if (firstSection) { setCurrentSection(firstSection); } }, []); const getItemLayout = useCallback((data: any, index: number) => ({ length: 85, // Approximate height of each item offset: 85 * index, index, }), []); const alphabet = '#ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(''); const availableLetters = new Set(sections.map(section => section.title)); // Updated type guard function isWorkoutExercise(exercise: ExerciseDisplay): exercise is DisplayWorkoutExercise { return 'sets' in exercise && Array.isArray((exercise as any).sets); } const renderExerciseItem = ({ item }: { item: ExerciseDisplay }) => { const firstLetter = item.title.charAt(0).toUpperCase(); const canDelete = item.source === 'local'; return ( onExercisePress(item)} className="flex-row items-center px-4 py-3 border-b border-border" > {/* Image placeholder or first letter */} {firstLetter} {/* Title */} {item.title} {/* Tags row */} {/* Category Badge */} {item.category} {/* Equipment Badge (if available) */} {item.equipment && ( {item.equipment} )} {/* Type Badge */} {item.type} {/* Source Badge - colored for 'powr' */} {item.source && ( {item.source} )} {/* Weight/Rep information if it was a WorkoutExercise */} {isWorkoutExercise(item) && ( {item.sets?.[0]?.weight && `${item.sets[0].weight} lb`} {item.sets?.[0]?.weight && item.sets?.[0]?.reps && ' '} {item.sets?.[0]?.reps && `(×${item.sets[0].reps})`} )} {/* Delete button (only for local exercises) */} {canDelete && onDeletePress && ( { e.stopPropagation(); // Prevent triggering the parent TouchableOpacity onDeletePress(item); }} className="p-2" hitSlop={{ top: 10, right: 10, bottom: 10, left: 10 }} > )} ); }; return ( {/* Main List */} item.id} getItemLayout={getItemLayout} renderSectionHeader={({ section }) => ( {section.title} )} renderItem={renderExerciseItem} stickySectionHeadersEnabled initialNumToRender={15} maxToRenderPerBatch={10} windowSize={5} onViewableItemsChanged={handleViewableItemsChanged} viewabilityConfig={{ itemVisiblePercentThreshold: 50 }} /> ); }; export default SimplifiedExerciseList;