Skip to content

Commit

Permalink
Merge pull request #202 from Amsterdam/WON-72-maak-telefoon-veld-nume…
Browse files Browse the repository at this point in the history
…riek-in-zaak-aanmaak-formulier

WON-72 phone numeric
  • Loading branch information
remyvdwereld authored Jan 28, 2025
2 parents c5751f1 + 8386e41 commit 5983ea0
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 7 deletions.
28 changes: 25 additions & 3 deletions src/app/components/forms/TextInputField/TextInputField.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import type {
FieldValues,
RegisterOptions,
UseFormReturn
UseFormReturn,
FieldError,
ValidationValueMessage
} from "react-hook-form"
import {
ErrorMessage,
Field,
Label,
TextInput,
TextInputProps
} from "@amsterdam/design-system-react"
import { getValueByPath } from "app/utils/getValueByPath"

type Props = {
name: string
Expand All @@ -26,19 +30,37 @@ export const TextInputField: React.FC<Props> = ({
formMethods = {},
...rest
}) => {
const { formState, register } = formMethods as UseFormReturn<FieldValues>
const error = formState?.errors?.[name]
const { formState, register, setError, clearErrors, trigger, setValue } =
formMethods as UseFormReturn<FieldValues>
const error = getValueByPath(formState?.errors, name) as FieldError
const hasError = !!error

const handleValidation = (e: React.ChangeEvent<HTMLInputElement>) => {
const value = e.target.value
setValue(name, value)
const pattern = validation?.pattern as ValidationValueMessage<RegExp>
const regex = pattern?.value
const message = pattern?.message || "Ongeldige invoer"
if (!value || !regex) return
if (regex.test(value)) {
clearErrors(name)
} else {
setError(name, { type: "custom", message })
}
void trigger()
}

return (
<Field>
<Label htmlFor={name}>{label}</Label>
{hasError && <ErrorMessage>{error?.message}</ErrorMessage>}
<TextInput
id={name}
invalid={hasError}
type={type}
{...(register ? register(name, validation) : {})}
{...rest}
onChange={handleValidation}
/>
</Field>
)
Expand Down
2 changes: 1 addition & 1 deletion src/app/pages/CaseCreatePage/CaseCreatePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export const CaseCreatePage: React.FC = () => {
) : (
<Form
onSubmit={onSubmit}
hasDummyButton={env.VITE_ENV === "LOCAL"}
hasDummyButton={env.VITE_ENV === "LOCAL" || env.VITE_ENV === "ONT"}
dummyValues={defaultDummyValues}
>
<RadioGroupFieldSet
Expand Down
14 changes: 11 additions & 3 deletions src/app/pages/CaseCreatePage/ContactsFormFields.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,21 @@ type Props = {
}

const emailValidation = {
required: "E-mail is verplicht",
required: true,
pattern: {
value: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/,
message: "Dit is geen geldig e-mailadres"
}
}

const phoneValidation = {
required: true,
pattern: {
value: /^(0031|0)[1-9][0-9]{8,9}$/,
message: "Dit is geen geldig telefoonnummer"
}
}

const requiredValidation = { required: true }

export const ContactsFormFields: React.FC<Props> = ({ formMethods }) => {
Expand All @@ -40,12 +48,12 @@ export const ContactsFormFields: React.FC<Props> = ({ formMethods }) => {
validation={ emailValidation }
formMethods={ formMethods }
/>
<Row wrap>
<Row wrap alignVertical="end">
<TextInputField
name={`phone[${ contact.id }]`}
label="Telefoon"
type="tel"
validation={ requiredValidation }
validation={ phoneValidation }
formMethods={ formMethods }
/>
<TextInputField
Expand Down
40 changes: 40 additions & 0 deletions src/app/utils/getValueByPath.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* Returns a value from an object by following a given path, which can be a string or array.
*
* Example:
*
* const obj = { user: { name: "Alice", age: 25, addresses: [{ city: "Wonderland" } } };
* const result = getValueByPath(obj, "user.address.city"); // Returns "Wonderland"
*
* const obj = { users: [{ name: "Alice" }, { name: "Bob" }] };
* const result = getValueByPath(obj, "users[1].name"); // Returns "Bob"
*
* COPY of Lodash GET function
*/

type Path = string | Array<string | number>
type Value = boolean | string | object

export function getValueByPath<T, R = undefined>(
obj: T,
path: Path,
defaultValue?: R
): R | Value {
if (!obj || !path) return defaultValue as R

const pathArray = Array.isArray(path)
? path
: path.replace(/\[(\d+)]/g, ".$1").split(".")

let current: Value = obj

for (const key of pathArray) {
if (current && typeof current === "object" && key in current) {
current = (current as Record<string | number, Value>)[key]
} else {
return defaultValue as R
}
}

return current
}

0 comments on commit 5983ea0

Please sign in to comment.