Exercise Creation from Plan fixed
This commit is contained in:
@@ -15,6 +15,7 @@ import { Card } from './ui/Card';
|
||||
import { Modal } from './ui/Modal';
|
||||
import { SideSheet } from './ui/SideSheet';
|
||||
import { Checkbox } from './ui/Checkbox';
|
||||
import ExerciseModal from './ExerciseModal';
|
||||
|
||||
interface PlansProps {
|
||||
lang: Language;
|
||||
@@ -42,9 +43,6 @@ const Plans: React.FC<PlansProps> = ({ lang }) => {
|
||||
|
||||
// Create Exercise State
|
||||
const [isCreatingExercise, setIsCreatingExercise] = useState(false);
|
||||
const [newExName, setNewExName] = useState('');
|
||||
const [newExType, setNewExType] = useState<ExerciseType>(ExerciseType.STRENGTH);
|
||||
const [newExBwPercentage, setNewExBwPercentage] = useState<string>('100');
|
||||
|
||||
// Preparation Modal State
|
||||
const [showPlanPrep, setShowPlanPrep] = useState<WorkoutPlan | null>(null);
|
||||
@@ -123,37 +121,16 @@ const Plans: React.FC<PlansProps> = ({ lang }) => {
|
||||
setShowExerciseSelector(false);
|
||||
};
|
||||
|
||||
const handleCreateExercise = async () => {
|
||||
if (!newExName.trim()) return;
|
||||
const newEx: ExerciseDef = {
|
||||
id: generateId(),
|
||||
name: newExName.trim(),
|
||||
type: newExType,
|
||||
...(newExType === ExerciseType.BODYWEIGHT && { bodyWeightPercentage: parseFloat(newExBwPercentage) || 100 })
|
||||
};
|
||||
const handleSaveNewExercise = async (newEx: ExerciseDef) => {
|
||||
await saveExercise(userId, newEx);
|
||||
const exList = await getExercises(userId);
|
||||
setAvailableExercises(exList.filter(e => !e.isArchived));
|
||||
|
||||
// Automatically add the new exercise to the plan
|
||||
addStep(newEx);
|
||||
|
||||
setNewExName('');
|
||||
setNewExType(ExerciseType.STRENGTH);
|
||||
setNewExBwPercentage('100');
|
||||
setIsCreatingExercise(false);
|
||||
};
|
||||
|
||||
const exerciseTypeLabels: Record<ExerciseType, string> = {
|
||||
[ExerciseType.STRENGTH]: t('type_strength', lang),
|
||||
[ExerciseType.BODYWEIGHT]: t('type_bodyweight', lang),
|
||||
[ExerciseType.CARDIO]: t('type_cardio', lang),
|
||||
[ExerciseType.STATIC]: t('type_static', lang),
|
||||
[ExerciseType.HIGH_JUMP]: t('type_height', lang),
|
||||
[ExerciseType.LONG_JUMP]: t('type_dist', lang),
|
||||
[ExerciseType.PLYOMETRIC]: t('type_jump', lang),
|
||||
};
|
||||
|
||||
const toggleWeighted = (stepId: string) => {
|
||||
setSteps(steps.map(s => s.id === stepId ? { ...s, isWeighted: !s.isWeighted } : s));
|
||||
};
|
||||
@@ -328,70 +305,13 @@ const Plans: React.FC<PlansProps> = ({ lang }) => {
|
||||
</div>
|
||||
</SideSheet>
|
||||
|
||||
<SideSheet
|
||||
<ExerciseModal
|
||||
isOpen={isCreatingExercise}
|
||||
onClose={() => setIsCreatingExercise(false)}
|
||||
title={t('create_exercise', lang)}
|
||||
width="md"
|
||||
>
|
||||
<div className="space-y-6 pt-2">
|
||||
<FilledInput
|
||||
label={t('ex_name', lang)}
|
||||
value={newExName}
|
||||
onChange={(e: any) => setNewExName(e.target.value)}
|
||||
type="text"
|
||||
autoFocus
|
||||
autocapitalize="words"
|
||||
onBlur={() => setNewExName(toTitleCase(newExName))}
|
||||
/>
|
||||
|
||||
<div>
|
||||
<label className="block text-xs text-on-surface-variant font-medium mb-3">{t('ex_type', lang)}</label>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{[
|
||||
{ id: ExerciseType.STRENGTH, label: exerciseTypeLabels[ExerciseType.STRENGTH], icon: Dumbbell },
|
||||
{ id: ExerciseType.BODYWEIGHT, label: exerciseTypeLabels[ExerciseType.BODYWEIGHT], icon: User },
|
||||
{ id: ExerciseType.CARDIO, label: exerciseTypeLabels[ExerciseType.CARDIO], icon: Flame },
|
||||
{ id: ExerciseType.STATIC, label: exerciseTypeLabels[ExerciseType.STATIC], icon: TimerIcon },
|
||||
{ id: ExerciseType.HIGH_JUMP, label: exerciseTypeLabels[ExerciseType.HIGH_JUMP], icon: ArrowUp },
|
||||
{ id: ExerciseType.LONG_JUMP, label: exerciseTypeLabels[ExerciseType.LONG_JUMP], icon: Ruler },
|
||||
{ id: ExerciseType.PLYOMETRIC, label: exerciseTypeLabels[ExerciseType.PLYOMETRIC], icon: Footprints },
|
||||
].map((type) => (
|
||||
<button
|
||||
key={type.id}
|
||||
onClick={() => setNewExType(type.id)}
|
||||
className={`px-4 py-2 rounded-lg flex items-center gap-2 text-xs font-medium border transition-all ${newExType === type.id
|
||||
? 'bg-secondary-container text-on-secondary-container border-transparent'
|
||||
: 'bg-transparent text-on-surface-variant border-outline hover:border-on-surface-variant'
|
||||
}`}
|
||||
>
|
||||
<type.icon size={14} /> {type.label}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{newExType === ExerciseType.BODYWEIGHT && (
|
||||
<FilledInput
|
||||
label={t('body_weight_percent', lang)}
|
||||
value={newExBwPercentage}
|
||||
onChange={(e: any) => setNewExBwPercentage(e.target.value)}
|
||||
icon={<Percent size={12} />}
|
||||
/>
|
||||
)}
|
||||
|
||||
<div className="flex justify-end mt-6">
|
||||
<Button
|
||||
onClick={handleCreateExercise}
|
||||
fullWidth
|
||||
size="lg"
|
||||
>
|
||||
<CheckCircle size={20} className="mr-2" />
|
||||
{t('create_btn', lang)}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</SideSheet>
|
||||
onSave={handleSaveNewExercise}
|
||||
lang={lang}
|
||||
existingExercises={availableExercises}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user