Preparation display when start plan from Plans

This commit is contained in:
AG
2025-12-11 22:16:28 +02:00
parent 138fe0c432
commit e9142d1e1c
5 changed files with 53 additions and 2 deletions

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@@ -44,6 +44,24 @@ const Plans: React.FC<PlansProps> = ({ lang }) => {
const [newExType, setNewExType] = useState<ExerciseType>(ExerciseType.STRENGTH);
const [newExBwPercentage, setNewExBwPercentage] = useState<string>('100');
// Preparation Modal State
const [showPlanPrep, setShowPlanPrep] = useState<WorkoutPlan | null>(null);
const handleStart = (plan: WorkoutPlan) => {
if (plan.description && plan.description.trim().length > 0) {
setShowPlanPrep(plan);
} else {
startSession(plan, currentUser?.profile?.weight);
}
};
const confirmPlanStart = () => {
if (showPlanPrep) {
startSession(showPlanPrep, currentUser?.profile?.weight);
setShowPlanPrep(null);
}
};
useEffect(() => {
const loadData = async () => {
refreshData();
@@ -377,6 +395,8 @@ const Plans: React.FC<PlansProps> = ({ lang }) => {
);
}
return (
<div className="h-full flex flex-col bg-surface relative">
<div className="p-4 bg-surface-container shadow-elevation-1 z-10 shrink-0">
@@ -425,7 +445,7 @@ const Plans: React.FC<PlansProps> = ({ lang }) => {
{plan.steps.length} {t('exercises_count', lang)}
</div>
<Button
onClick={() => startSession(plan)}
onClick={() => handleStart(plan)}
className="flex items-center gap-2"
>
<PlayCircle size={18} />
@@ -445,6 +465,23 @@ const Plans: React.FC<PlansProps> = ({ lang }) => {
>
<Plus size={28} />
</button>
{/* Preparation Modal */}
{showPlanPrep && (
<div className="fixed inset-0 bg-black/60 z-50 flex items-center justify-center p-6 backdrop-blur-sm">
<div className="w-full max-w-sm bg-surface-container rounded-[28px] p-6 shadow-elevation-3">
<h3 className="text-2xl font-normal text-on-surface mb-4">{showPlanPrep.name}</h3>
<div className="bg-surface-container-high p-4 rounded-xl text-on-surface-variant text-sm mb-8">
<div className="text-xs font-bold text-primary mb-2">{t('prep_title', lang)}</div>
{showPlanPrep.description || t('prep_no_instructions', lang)}
</div>
<div className="flex justify-end gap-2">
<button onClick={() => setShowPlanPrep(null)} className="px-6 py-2.5 rounded-full text-primary font-medium hover:bg-white/5">{t('cancel', lang)}</button>
<button onClick={confirmPlanStart} className="px-6 py-2.5 rounded-full bg-primary text-on-primary font-medium">{t('start', lang)}</button>
</div>
</div>
</div>
)}
</div>
);
};

View File

@@ -187,6 +187,13 @@ test.describe('Rest Timer', () => {
// Start the plan.
await page.getByRole('button', { name: 'Start' }).click();
// Expect Preparation Modal
const modal = page.locator('.fixed.inset-0.z-50');
await expect(modal).toBeVisible();
await expect(modal.getByText('Ready to go')).toBeVisible();
// Click Start in the modal (ensure we click the button inside the modal)
await modal.getByRole('button', { name: 'Start' }).click();
// Timer Update: Click FAB
const fab = page.locator('.fixed.bottom-24.right-6');
await fab.click();

View File

@@ -196,6 +196,13 @@ test.describe('II. Workout Management', () => {
.last();
await card.getByRole('button', { name: 'Start' }).click();
// Expect Preparation Modal
const modal = page.locator('.fixed.inset-0.z-50');
await expect(modal).toBeVisible();
await expect(modal.getByText('Ready to go')).toBeVisible();
// Click Start in the modal (ensure we click the button inside the modal)
await modal.getByRole('button', { name: 'Start' }).click();
await expect(page.getByText('Startable Plan', { exact: false })).toBeVisible();
await expect(page.getByRole('button', { name: 'Finish' })).toBeVisible();
});