From b0052e1086ccb7b28f70fcbb853ff95a70e9e4c0 Mon Sep 17 00:00:00 2001 From: khaira777 <777gurkirat@gmail.com> Date: Sat, 7 Nov 2026 13:03:39 -0500 Subject: [PATCH] fix(settings): stop Save All when the business phone is invalid saveBusinessInfo returned without throwing on an invalid phone, so Save All still wrote the other sections and reported Settings saved. Validate the phone before any write so Save All saves nothing and shows only the phone error. --- frontend/e2e/settings-request-budget.spec.ts | 24 +++++++++++++++++++ .../src/app/(dashboard)/settings/page.tsx | 4 ++++ 2 files changed, 28 insertions(+) diff --git a/frontend/e2e/settings-request-budget.spec.ts b/frontend/e2e/settings-request-budget.spec.ts index 1b58cf67b..3019a0d64 100644 --- a/frontend/e2e/settings-request-budget.spec.ts +++ b/frontend/e2e/settings-request-budget.spec.ts @@ -1021,6 +1021,30 @@ test('Editing only order numbering marks Settings dirty and saves or discards cl await expect(discardButton).toHaveCount(0); }); +test('Save All with an invalid business phone writes nothing and does not report success', async ({ + page, +}) => { + await startMockedSettingsSession(page); + const writes: string[] = []; + page.on('request', (request) => { + const path = new URL(request.url()).pathname; + if (request.method() === 'PUT' && path.startsWith('/api/settings')) writes.push(path); + }); + + await page.goto(`${BASE}/settings?tab=store`); + await expect(page.getByRole('heading', { name: 'Store Details', exact: true })).toBeVisible(); + await page.locator('input[type="text"]').first().fill('Changed Store'); + await page.locator('div:has(> label:text-is("Phone")) input').fill('12'); + + const saveButton = page.getByRole('button', { name: 'Save Changes', exact: true }); + await saveButton.click(); + + await expect(page.getByText('Invalid phone number format', { exact: true })).toBeVisible(); + await expect(saveButton).toBeEnabled(); + await expect(page.getByText('Settings saved', { exact: true })).toHaveCount(0); + expect(writes).toEqual([]); +}); + test('Save All preserves printing edits during business hydration', async ({ page }) => { await startMockedSettingsSession(page); const savedPrintingRequests: Record[] = []; diff --git a/frontend/src/app/(dashboard)/settings/page.tsx b/frontend/src/app/(dashboard)/settings/page.tsx index 086267a8a..0b76ef8c6 100644 --- a/frontend/src/app/(dashboard)/settings/page.tsx +++ b/frontend/src/app/(dashboard)/settings/page.tsx @@ -3829,6 +3829,10 @@ export default function SettingsPage() { if (saveAllHydrationRun === 0 || !savingAllSettingsInFlight.current) return; void (async () => { try { + if (!normalizeOptionalPhone(form.businessPhone, form.countryCode || '').valid) { + toast.error(t('invalidPhoneFormat')); + return; + } await Promise.all([ saveBusinessInfo(true), saveLoyalty(true),