Check exercise name uniqueness when creating

This commit is contained in:
AG
2025-11-26 22:26:45 +02:00
parent 53d11c6665
commit 94f0a9a17a
4 changed files with 35 additions and 9 deletions

View File

@@ -9,12 +9,14 @@ interface ExerciseModalProps {
onClose: () => void;
onSave: (exercise: ExerciseDef) => Promise<void> | void;
lang: Language;
existingExercises?: ExerciseDef[];
}
const ExerciseModal: React.FC<ExerciseModalProps> = ({ isOpen, onClose, onSave, lang }) => {
const ExerciseModal: React.FC<ExerciseModalProps> = ({ isOpen, onClose, onSave, lang, existingExercises = [] }) => {
const [newName, setNewName] = useState('');
const [newType, setNewType] = useState<ExerciseType>(ExerciseType.STRENGTH);
const [newBwPercentage, setNewBwPercentage] = useState<string>('100');
const [error, setError] = useState<string>('');
const exerciseTypeLabels: Record<ExerciseType, string> = {
[ExerciseType.STRENGTH]: t('type_strength', lang),
@@ -28,9 +30,21 @@ const ExerciseModal: React.FC<ExerciseModalProps> = ({ isOpen, onClose, onSave,
const handleCreateExercise = async () => {
if (!newName.trim()) return;
// Check for duplicate name (case-insensitive)
const trimmedName = newName.trim();
const isDuplicate = existingExercises.some(
ex => ex.name.toLowerCase() === trimmedName.toLowerCase()
);
if (isDuplicate) {
setError(t('exercise_name_exists', lang) || 'An exercise with this name already exists');
return;
}
const newEx: ExerciseDef = {
id: crypto.randomUUID(),
name: newName.trim(),
name: trimmedName,
type: newType,
...(newType === ExerciseType.BODYWEIGHT && { bodyWeightPercentage: parseFloat(newBwPercentage) || 100 })
};
@@ -38,6 +52,7 @@ const ExerciseModal: React.FC<ExerciseModalProps> = ({ isOpen, onClose, onSave,
setNewName('');
setNewType(ExerciseType.STRENGTH);
setNewBwPercentage('100');
setError('');
onClose();
};
@@ -52,13 +67,21 @@ const ExerciseModal: React.FC<ExerciseModalProps> = ({ isOpen, onClose, onSave,
</div>
<div className="space-y-6">
<FilledInput
label={t('ex_name', lang)}
value={newName}
onChange={(e: any) => setNewName(e.target.value)}
type="text"
autoFocus
/>
<div>
<FilledInput
label={t('ex_name', lang)}
value={newName}
onChange={(e: any) => {
setNewName(e.target.value);
setError(''); // Clear error when user types
}}
type="text"
autoFocus
/>
{error && (
<p className="text-xs text-error mt-2 ml-3">{error}</p>
)}
</div>
<div>
<label className="block text-xs text-on-surface-variant font-medium mb-3">{t('ex_type', lang)}</label>

View File

@@ -514,6 +514,7 @@ const Profile: React.FC<ProfileProps> = ({ user, onLogout, lang, onLanguageChang
onClose={() => setIsCreatingEx(false)}
onSave={handleCreateExercise}
lang={lang}
existingExercises={exercises}
/>
)}