diff --git a/src/admin/BulkUserCreationPage.tsx b/src/admin/BulkUserCreationPage.tsx index bc1691e..8e47762 100644 --- a/src/admin/BulkUserCreationPage.tsx +++ b/src/admin/BulkUserCreationPage.tsx @@ -78,7 +78,9 @@ const BulkUserCreationPage: FC = () => { }); const fieldError = (key: keyof FormFields) => - form.submitCount > 0 && form.errors[key] ? {form.errors[key]} : null; + (form.submitCount > 0 || form.touched[key]) && form.errors[key] ? ( + {form.errors[key]} + ) : null; return ( <> diff --git a/src/i18n/en.json b/src/i18n/en.json index 1960b7f..524af4c 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -99,5 +99,6 @@ "addTestToIdentifierPage.form.identifier.invalid.magicLink": "Please check the email address", "addTestToIdentifierPage.form.identifier.invalid.estonianId": "Please check the identification code", "addTestToIdentifierPage.button": "Add test result", - "addTestToIdentifierPage.success": "Test result for {{ identifier }} added." + "addTestToIdentifierPage.success": "Test result for {{ identifier }} added.", + "testFields.error.generic": "Please check the input" } diff --git a/src/i18n/et.json b/src/i18n/et.json index 4fcef32..1af2f9e 100644 --- a/src/i18n/et.json +++ b/src/i18n/et.json @@ -99,5 +99,6 @@ "addTestToIdentifierPage.form.identifier.invalid.magicLink": "Palun kontrolli meiliaadressi", "addTestToIdentifierPage.form.identifier.invalid.estonianId": "Palun kontrolli isikukoodi", "addTestToIdentifierPage.button": "Lisa testitulemus", - "addTestToIdentifierPage.success": "Testitulemus isikule {{ identifier }} lisatud." + "addTestToIdentifierPage.success": "Testitulemus isikule {{ identifier }} lisatud.", + "testFields.error.generic": "Palun kontrolli sisestatud väärtust" } diff --git a/src/identity/AddressForm.tsx b/src/identity/AddressForm.tsx index cf91db4..32f8cfd 100644 --- a/src/identity/AddressForm.tsx +++ b/src/identity/AddressForm.tsx @@ -50,7 +50,9 @@ export const AddressForm = ({ onComplete }: { onComplete: (address: Address) => }); const fieldError = (key: keyof AddressFormFields) => - form.touched[key] && form.errors[key] ? {form.errors[key]} : null; + (form.submitCount > 0 || form.touched[key]) && form.errors[key] ? ( + {form.errors[key]} + ) : null; const field = (name: keyof AddressFormFields, label: string) => { const id = `identity-${name}`; diff --git a/src/identity/ProfileForm.tsx b/src/identity/ProfileForm.tsx index 889b010..7acbde8 100644 --- a/src/identity/ProfileForm.tsx +++ b/src/identity/ProfileForm.tsx @@ -46,7 +46,9 @@ export const ProfileForm = ({ onComplete }: { onComplete: (profile: Profile) => }); const fieldError = (key: keyof ProfileFormFields) => - form.touched[key] && form.errors[key] ? {form.errors[key]} : null; + (form.submitCount > 0 || form.touched[key]) && form.errors[key] ? ( + {form.errors[key]} + ) : null; return ( diff --git a/src/testing/AddTestToIdentifierPage.test.tsx b/src/testing/AddTestToIdentifierPage.test.tsx index ea657d4..3867bf7 100644 --- a/src/testing/AddTestToIdentifierPage.test.tsx +++ b/src/testing/AddTestToIdentifierPage.test.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { screen, waitFor, waitForElementToBeRemoved } from '@testing-library/react'; +import { screen, waitForElementToBeRemoved } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import nock, { Scope } from 'nock'; @@ -25,35 +25,23 @@ describe(AddTestToIdentifierPage, () => { expect(identifierInput()).toHaveFocus(); }); - it('only allows submitting the form once the identifier is valid and required test fields are filled, showing validation errors', async () => { + it('creates a user and adds a PCR test for that user only when identifier is valid and required test fields are filled', async () => { mockHttp().get('/api/v1/test-types').reply(200, [aTestType()]); renderWrapped(); - const positiveOption = await screen.findByRole('radio', { name: 'Positive' }); + const negativeOption = await screen.findByRole('radio', { name: 'Negative' }); + const positiveOption = screen.getByRole('radio', { name: 'Positive' }); userEvent.type(identifierInput(), '79210030814'); // invalid id code submit(); await screen.findByText(/check the identification code/i); // validation error userEvent.type(identifierInput(), '39210030814'); // valid id code + submit(); await waitForElementToBeRemoved(screen.queryByText(/check the identification code/i)); // no validation error await userEvent.type(notesInput(), 'Some notes'); - expect(submitButton()).toBeDisabled(); // as a radio option has not been selected - userEvent.click(positiveOption); - await waitFor(() => expect(submitButton()).not.toBeDisabled()); - }); - - it('creates a user and and adds a PCR test for that user', async () => { - mockHttp().get('/api/v1/test-types').reply(200, [aTestType()]); - renderWrapped(); - - const negativeOption = await screen.findByRole('radio', { name: 'Negative' }); - const positiveOption = screen.getByRole('radio', { name: 'Positive' }); - - userEvent.type(identifierInput(), '39210030814'); - await userEvent.type(notesInput(), 'Some notes'); userEvent.click(negativeOption); userEvent.click(positiveOption); // to confirm the latest value is sent diff --git a/src/testing/AddTestToIdentifierPage.tsx b/src/testing/AddTestToIdentifierPage.tsx index 1b9f33b..7b786de 100644 --- a/src/testing/AddTestToIdentifierPage.tsx +++ b/src/testing/AddTestToIdentifierPage.tsx @@ -85,7 +85,9 @@ export const AddTestToIdentifierPage: FC = () => { }); const fieldError = (key: keyof FormFields) => - form.touched[key] && form.errors[key] ? {form.errors[key]} : null; + (form.submitCount > 0 || form.touched[key]) && form.errors[key] ? ( + {form.errors[key]} + ) : null; return ( <> @@ -128,7 +130,7 @@ export const AddTestToIdentifierPage: FC = () => { {selectedTestType && } - diff --git a/src/testing/TestFields.tsx b/src/testing/TestFields.tsx index 8883217..2fcf474 100644 --- a/src/testing/TestFields.tsx +++ b/src/testing/TestFields.tsx @@ -13,7 +13,11 @@ interface TestFieldsProps { export const TestFields: FC = ({ form, testType }) => { const fieldError = (key: keyof TestType['resultsSchema']['properties']) => - form.touched[key] && form.errors[key] ? {form.errors[key]} : null; + (form.submitCount > 0 || form.touched[key]) && form.errors[key] ? ( + + testFields.error.generic + + ) : null; // TODO: Extract generic JSON schema generator return ( diff --git a/src/theme.ts b/src/theme.ts index 417ff5d..5255583 100644 --- a/src/theme.ts +++ b/src/theme.ts @@ -18,6 +18,8 @@ const theme = { colors: { ...baseTheme.colors, primary: '#096DD9', + success: '#52c41a', // Primary green from https://ant.design/docs/spec/colors + error: '#f5222d', // Primary red from https://ant.design/docs/spec/colors }, sizes: { pageWidth: '600px', @@ -102,10 +104,10 @@ const theme = { paddingRight: 4, }, success: { - background: '#52c41a', // Primary green from https://ant.design/docs/spec/colors + backgroundColor: 'success', }, error: { - background: '#f5222d', // Primary red from https://ant.design/docs/spec/colors + backgroundColor: 'error', }, }, badges: { @@ -148,6 +150,12 @@ const theme = { borderBottom: '1px solid #DEDEDE', }, }, + text: { + validation: { + color: 'error', + fontSize: 1, + }, + }, }; export default theme;