From f4c8dbc234f23321c6c1c2bfd6d5771792920b56 Mon Sep 17 00:00:00 2001 From: Pooria Mehregan Date: Fri, 19 Apr 2024 14:17:51 +0200 Subject: [PATCH] feat: add form validation --- .eslintrc.json | 7 +- .vscode/settings.json | 3 +- apps/contact-form/app/[lang]/contact-form.tsx | 103 ++++++++++++++ apps/contact-form/app/[lang]/page.module.css | 18 +-- apps/contact-form/app/[lang]/page.tsx | 130 +++--------------- apps/contact-form/app/[lang]/schema.ts | 20 +++ apps/contact-form/app/actions.ts | 28 ++++ apps/contact-form/app/api/hello/route.ts | 4 - apps/contact-form/tsconfig.json | 4 + .../dictionaries/src/lib/dictionaries/en.json | 38 ++--- .../dictionaries/src/lib/dictionaries/nb.json | 38 ++--- .../dictionaries/src/lib/dictionaries/nn.json | 38 ++--- .../dictionaries/src/lib/i18n-config/index.ts | 4 +- libs/types/src/index.ts | 1 + libs/types/src/lib/forms/index.ts | 6 + libs/ui/src/index.ts | 1 + .../button-submit/button-submit.module.css | 3 + libs/ui/src/lib/button-submit/index.tsx | 26 ++++ .../ui/src/lib/container/container.module.css | 7 +- libs/ui/src/lib/container/index.tsx | 18 +-- .../header/components/language-menu/index.tsx | 4 +- libs/ui/src/lib/header/header.module.css | 13 +- libs/ui/src/lib/header/index.tsx | 2 +- .../label-with-tag/text-area-label.module.css | 2 +- .../{root-layout => layout-root}/global.css | 1 + .../{root-layout => layout-root}/index.tsx | 4 +- libs/ui/src/server.ts | 2 +- libs/utils/src/index.ts | 2 + libs/utils/src/lib/form-utils/form-state.ts | 43 ++++++ libs/utils/src/lib/form-utils/index.ts | 2 + libs/utils/src/lib/form-utils/types.ts | 21 +++ .../lib/functions/value-extractors/index.ts | 43 ++++++ libs/utils/tsconfig.json | 5 +- package.json | 4 +- tsconfig.base.json | 3 +- yarn.lock | 16 +++ 36 files changed, 444 insertions(+), 220 deletions(-) create mode 100644 apps/contact-form/app/[lang]/contact-form.tsx create mode 100644 apps/contact-form/app/[lang]/schema.ts create mode 100644 apps/contact-form/app/actions.ts delete mode 100644 apps/contact-form/app/api/hello/route.ts create mode 100644 libs/types/src/lib/forms/index.ts create mode 100644 libs/ui/src/lib/button-submit/button-submit.module.css create mode 100644 libs/ui/src/lib/button-submit/index.tsx rename libs/ui/src/lib/{root-layout => layout-root}/global.css (91%) rename libs/ui/src/lib/{root-layout => layout-root}/index.tsx (97%) create mode 100644 libs/utils/src/lib/form-utils/form-state.ts create mode 100644 libs/utils/src/lib/form-utils/index.ts create mode 100644 libs/utils/src/lib/form-utils/types.ts create mode 100644 libs/utils/src/lib/functions/value-extractors/index.ts diff --git a/.eslintrc.json b/.eslintrc.json index 78bba631..36c579f3 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -61,8 +61,11 @@ "no-implicit-coercion": "warn", "no-magic-numbers": ["warn", {"ignoreArrayIndexes": true }], "no-param-reassign": "error", - "no-shadow": "error", - "prefer-const": "error" + "no-shadow": "off", + "@typescript-eslint/no-shadow": "error", + "prefer-const": "error", + "no-unused-vars": "off", + "@typescript-eslint/no-unused-vars": "error" } }, { diff --git a/.vscode/settings.json b/.vscode/settings.json index 0bf34a9e..2ee98c3d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,5 +6,6 @@ "editor.formatOnSaveMode": "file", "editor.inlineSuggest.suppressSuggestions": false, "files.insertFinalNewline": true, - "files.trimTrailingWhitespace": true + "files.trimTrailingWhitespace": true, + "css.lint.validProperties": ["composes"] } diff --git a/apps/contact-form/app/[lang]/contact-form.tsx b/apps/contact-form/app/[lang]/contact-form.tsx new file mode 100644 index 00000000..cf4ca2e4 --- /dev/null +++ b/apps/contact-form/app/[lang]/contact-form.tsx @@ -0,0 +1,103 @@ +'use client'; + +import { Paragraph, Textarea, Textfield } from '@digdir/designsystemet-react'; +import { LabelWithTag, SubmitButton } from '@fdk-frontend/ui'; +import { type Dictionary } from '@fdk-frontend/dictionaries'; +import { useFormState } from 'react-dom'; +import styles from './page.module.css'; +import { sendEmailAction } from '../actions'; +import { EMPTY_FORM_STATE, extractErrorMessages } from '@fdk-frontend/utils'; + +type Props = { + dictionary: Dictionary; +}; + +const ContactForm = ({ dictionary }: Props) => { + const [state, formAction] = useFormState(sendEmailAction, EMPTY_FORM_STATE); + const textAreaCols = 100; + const textAreaRows = 5; + + return ( +
+