-
-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
2fefe5e
commit 110698e
Showing
4 changed files
with
139 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,23 +15,50 @@ import { | |
RemixFormProvider, | ||
} from "remix-hook-form"; | ||
import { z } from "zod"; | ||
import { | ||
generateObjectSchema, | ||
stringOptional, | ||
stringRequired, | ||
dateOfBirthRequired, | ||
emailOptional, | ||
booleanOptional, | ||
booleanRequired, | ||
} from "~/zod"; | ||
const MAX_FILE_SIZE = 500000; | ||
const ACCEPTED_IMAGE_TYPES = [ | ||
"image/jpeg", | ||
"image/jpg", | ||
"image/png", | ||
"image/webp", | ||
]; | ||
export const patientBaseSchema = generateObjectSchema({ | ||
id: stringOptional(), | ||
firstName: stringRequired(), | ||
lastName: stringRequired(), | ||
primaryCareProvider: stringOptional(), | ||
dateOfBirth: dateOfBirthRequired(), | ||
email: emailOptional(), | ||
hasThirdPartyCoverage: booleanOptional(), | ||
isForeignCitizen: booleanOptional(), | ||
allergies: z.array(stringRequired()).optional(), | ||
healthCardNumber: stringOptional(), | ||
hasHealthCardNumber: booleanRequired(), | ||
city: stringRequired(), | ||
province: stringRequired(), | ||
street: stringRequired(), | ||
postalCode: stringRequired(), | ||
healthCardProvince: stringRequired(), | ||
}); | ||
const FormDataZodSchema = z.object({ | ||
email: z.string().trim().nonempty("validation.required"), | ||
password: z.string().trim().nonempty("validation.required"), | ||
number: z.number({ coerce: true }).int().positive(), | ||
redirectTo: z.string().optional(), | ||
}); | ||
|
||
type FormData = z.infer<typeof FormDataZodSchema>; | ||
type FormData = z.infer<typeof patientBaseSchema>; | ||
|
||
const resolver = zodResolver(FormDataZodSchema); | ||
const resolver = zodResolver(patientBaseSchema); | ||
|
||
export const action = async ({ request }: ActionFunctionArgs) => { | ||
const { data, errors, receivedValues } = await getValidatedFormData( | ||
|
@@ -57,10 +84,23 @@ export default function Index() { | |
const methods = useRemixForm<FormData>({ | ||
resolver, | ||
defaultValues: { | ||
email: "[email protected]", | ||
password: "12345678", | ||
redirectTo: undefined, | ||
number: 1, | ||
firstName: "a", | ||
lastName: "t", | ||
primaryCareProvider: "", | ||
dateOfBirth: new Date("1997-09-05T00:00:00.000Z"), | ||
|
||
email: "", | ||
|
||
hasThirdPartyCoverage: false, | ||
isForeignCitizen: false, | ||
allergies: [], | ||
city: "Sarajevo", | ||
street: "Radenka Abazovića", | ||
province: "ON", | ||
postalCode: "a5t 5a5", | ||
hasHealthCardNumber: true, | ||
healthCardNumber: "5555555555", | ||
healthCardProvince: "ON", | ||
}, | ||
submitConfig: { | ||
method: "POST", | ||
|
@@ -76,8 +116,6 @@ export default function Index() { | |
<Form method="post" onSubmit={handleSubmit}> | ||
<div className="flex flex-col gap-2"> | ||
<input type="text" {...register("email")} /> | ||
<input type="text" {...register("password")} /> | ||
<input type="number" {...register("number")} /> | ||
</div> | ||
<div> | ||
<button type="submit" className="button"> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import type { ZodRawShape } from "zod"; | ||
import { z } from "zod"; | ||
|
||
const errorMessages = { | ||
required_error: "validation.required", | ||
invalid_type_error: "validation.required", | ||
}; | ||
const customErrorMap: z.ZodErrorMap = (issue, ctx) => { | ||
if (issue.code === z.ZodIssueCode.invalid_union) { | ||
return { message: "validation.required" }; | ||
} | ||
return { message: ctx.defaultError }; | ||
}; | ||
|
||
z.setErrorMap(customErrorMap); | ||
|
||
export const stringRequired = () => | ||
z.string(errorMessages).trim().nonempty("validation.required"); | ||
|
||
export const stringOptional = () => z.string(errorMessages).trim().nullish(); | ||
|
||
export const numberRequired = () => z.number(errorMessages); | ||
|
||
export const numberOptional = () => z.number(errorMessages).nullish(); | ||
|
||
export const booleanRequired = () => z.boolean(errorMessages); | ||
|
||
export const booleanOptional = () => z.boolean(errorMessages).optional(); | ||
|
||
export const passwordRequired = () => | ||
stringRequired().min(8, "validation.min8"); | ||
|
||
const dateOrStringDate = stringRequired() | ||
.pipe( | ||
z.date({ | ||
coerce: true, | ||
...errorMessages, | ||
}), | ||
) | ||
.or(z.date(errorMessages)); | ||
|
||
export const dateOfBirthRequired = () => | ||
stringRequired() | ||
.pipe( | ||
z | ||
.date({ | ||
coerce: true, | ||
...errorMessages, | ||
}) | ||
.min(new Date("1.1.1900"), "validation.min_year") | ||
.max(new Date(), "validation.dob_future"), | ||
) | ||
.or( | ||
z | ||
.date(errorMessages) | ||
.min(new Date("1.1.1900"), "validation.min_year") | ||
.max(new Date(), "validation.dob_future"), | ||
); | ||
|
||
export const dateRequired = () => dateOrStringDate; | ||
|
||
export const dateOptional = () => dateOrStringDate.nullish(); | ||
|
||
export const generateObjectSchema = <T extends ZodRawShape>(obj: T) => | ||
z.object(obj); | ||
|
||
export const generateObjectArraySchema = ( | ||
obj: Record<string, z.ZodSchema>, | ||
required?: boolean, | ||
) => | ||
required | ||
? z.array(generateObjectSchema(obj)).min(1, "validation.required") | ||
: z.array(generateObjectSchema(obj)); | ||
|
||
export const confirmEmail = <T extends { email: string; confirmEmail: string }>( | ||
data: T, | ||
) => data.email === data.confirmEmail; | ||
|
||
export const confirmPassword = < | ||
T extends { password: string; confirmPassword: string }, | ||
>( | ||
data: T, | ||
) => data.password === data.confirmPassword; | ||
|
||
export const emailRequired = () => stringRequired().email("validation.email"); | ||
|
||
export const emailOptional = () => emailRequired().nullish().or(z.literal("")); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters