// components/workout/SetInput.tsx import React, { useState, useCallback } from 'react'; import { View, TextInput, TouchableOpacity } from 'react-native'; import { Text } from '@/components/ui/text'; import { Circle, CheckCircle } from 'lucide-react-native'; // Lucide React icons import { cn } from '@/lib/utils'; import { useWorkoutStore } from '@/stores/workoutStore'; import { useColorScheme } from '@/lib/theme/useColorScheme'; import type { WorkoutSet } from '@/types/workout'; import debounce from 'lodash/debounce'; interface SetInputProps { exerciseIndex: number; setIndex: number; setNumber: number; weight?: number; reps?: number; isCompleted?: boolean; previousSet?: WorkoutSet; } export default function SetInput({ exerciseIndex, setIndex, setNumber, weight = 0, reps = 0, isCompleted = false, previousSet }: SetInputProps) { // Get theme colors const { isDarkColorScheme } = useColorScheme(); // Local state for controlled inputs const [weightValue, setWeightValue] = useState(weight.toString()); const [repsValue, setRepsValue] = useState(reps.toString()); // Get actions from store const { updateSet, completeSet } = useWorkoutStore.getState(); // Debounced update functions to prevent too many state updates const debouncedUpdateWeight = useCallback( debounce((value: number) => { updateSet(exerciseIndex, setIndex, { weight: value }); }, 500), [exerciseIndex, setIndex] ); const debouncedUpdateReps = useCallback( debounce((value: number) => { updateSet(exerciseIndex, setIndex, { reps: value }); }, 500), [exerciseIndex, setIndex] ); const handleWeightChange = (value: string) => { if (value === '' || /^\d*\.?\d*$/.test(value)) { setWeightValue(value); const numValue = parseFloat(value); if (!isNaN(numValue)) { debouncedUpdateWeight(numValue); } } }; const handleRepsChange = (value: string) => { if (value === '' || /^\d*$/.test(value)) { setRepsValue(value); const numValue = parseInt(value, 10); if (!isNaN(numValue)) { debouncedUpdateReps(numValue); } } }; const handleCompleteSet = useCallback(() => { completeSet(exerciseIndex, setIndex); }, [exerciseIndex, setIndex, completeSet]); const handleCopyPreviousWeight = useCallback(() => { if (previousSet?.weight) { handleWeightChange(previousSet.weight.toString()); } }, [previousSet]); const handleCopyPreviousReps = useCallback(() => { if (previousSet?.reps) { handleRepsChange(previousSet.reps.toString()); } }, [previousSet]); // Get the appropriate colors based on theme variables const purpleColor = 'hsl(261, 90%, 66%)'; // --purple from your constants const mutedForegroundColor = isDarkColorScheme ? 'hsl(240, 5%, 64.9%)' // --muted-foreground dark : 'hsl(240, 3.8%, 46.1%)'; // --muted-foreground light return ( {/* Set Number */} {setNumber} {/* Previous Set */} {previousSet ? `${previousSet.weight}×${previousSet.reps}` : '—'} {/* Weight Input */} {/* Reps Input */} {/* Complete Button using Lucide React icons - without fill */} {isCompleted ? ( ) : ( )} ); }