Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Agrega validaciones a el formulario de solicitud de préstamo #401

Open
wants to merge 4 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 46 additions & 30 deletions components/LoanRequestForm/LoanRequestForm.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
"use client";

import { Button } from "components/Button/Button";
import TextArea from "components/TextArea/TextArea";
import Input from "components/Input/Input";
import React from "react";
import { Link } from "components/Link/Link";
import { useFormState } from "react-dom";
import { loanReqFormAction } from "./form-action";

export const LoanRequestForm = () => {
const [errorMsg, formAction] = useFormState(loanReqFormAction, {});

return (
<section className="py-5 md:py-10">
<div className="mx-auto max-w-3xl">
Expand All @@ -20,7 +26,7 @@ export const LoanRequestForm = () => {
</Link>
</p>

<form action="" className="mx-auto max-w-2xl" method="POST">
<form action={formAction} method="POST" className="mx-auto max-w-2xl">
<h4 className="mb-8">
Paso 1 de 2: <br />
Completá los datos del formulario.
Expand All @@ -30,142 +36,152 @@ export const LoanRequestForm = () => {
Datos del adulto responsable
</p>
<Input
helperText="Ej: Marísol Hernández"
id="fullname"
name="fullname"
label="Nombre y apellido:"
placeholder="Ej: Marísol Hernández"
type="text"
required
error={!!errorMsg.fullname}
helperText={errorMsg.fullname?.at(0) || "Ej: Marísol Hernández"}
/>
<Input
helperText="Ej: 35764532 (sin puntos)"
id="dni"
name="dni"
label="DNI:"
placeholder="Ej: 35764532 (sin puntos)"
type="number"
required
error={!!errorMsg.dni}
helperText={errorMsg.dni?.at(0) || "Ej: 35764532 (sin puntos)"}
/>
<div className="grid grid-cols-[1fr_1fr] grid-rows-2 gap-4 md:grid-cols-[6fr_2fr_2fr] md:grid-rows-1">
<Input
helperText="Ej: Mitre"
id="calle"
name="calle"
label="Calle:"
placeholder="Ej: Mitre"
type="text"
required
error={!!errorMsg.calle}
helperText={errorMsg.calle?.at(0) || "Ej: Mitre"}
/>
<Input
helperText="Ej: 1200"
id="altura"
name="altura"
label="Altura:"
placeholder="Ej: 1200"
type="number"
required
error={!!errorMsg.altura}
helperText={errorMsg.altura?.at(0) || "Ej: 1200"}
/>
<div className="col-span-2 md:col-span-1">
<Input
helperText="Ej: 4B"
id="depto"
name="depto"
label="Piso y depto:"
placeholder="Ej: 4B"
type="text"
error={!!errorMsg.depto}
helperText={errorMsg.depto?.at(0) || "Ej: 4B"}
/>
</div>
</div>
<div className="grid gap-4 md:grid-cols-[6fr_4fr]">
<Input
helperText="Ej: Mitre"
id="localidad"
name="localidad"
label="Localidad:"
placeholder="Ej: Mitre"
type="text"
required
error={!!errorMsg.localidad}
helperText={errorMsg.localidad?.at(0) || "Ej: Mitre"}
/>
<Input
helperText="Ej: 1870"
id="postal"
name="postal"
label="Codigo postal:"
placeholder="Ej: 1870"
type="number"
required
error={!!errorMsg.postal}
helperText={errorMsg.postal?.at(0) || "Ej: 1870"}
/>
</div>
<div className="grid gap-4 md:grid-cols-[1fr_5fr_4fr]">
<Input
helperText="Ej: 011"
id="area"
name="area"
label="Area:"
placeholder="Ej: 011"
type="text"
pattern="[0-9]{3}"
required
error={!!errorMsg.area}
helperText={errorMsg.area?.at(0) || "Ej: 011"}
/>
<Input
helperText="Ej: 42229845"
id="phone"
name="phone"
label="Teléfono de contacto:"
placeholder="Ej: 42229845"
type="tel"
required
error={!!errorMsg.phone}
helperText={errorMsg.phone?.at(0) || "Ej: 42229845"}
/>
<Input
helperText="Ej: [email protected]"
id="email"
name="email"
label="Email de contacto:"
placeholder="Ej: [email protected]"
type="email"
required
error={!!errorMsg.email}
helperText={errorMsg.email?.at(0) || "Ej: [email protected]"}
/>
</div>
<Input
helperText="Vínculo con el niño o niña:"
id="child-link"
name="child-link"
label="Vínculo con el niño o niña:"
type="url"
required
type="text"
error={!!errorMsg["child-link"]}
helperText={
errorMsg["child-link"]?.at(0) || "Vínculo con el niño o niña:"
}
/>
<p className="mb-8 mt-6 border-b border-blue pb-4 font-outfit font-medium text-blue md:border-none">
Datos del niño o niña
</p>
<Input
helperText="Ej: María Fernández"
id="child-fullname"
name="child-fullname"
placeholder="Ej: María Fernández"
label="Nombre y apellido del niño o niña:"
type="text"
required
error={!!errorMsg["child-fullname"]}
helperText={
errorMsg["child-fullname"]?.at(0) || "Ej: María Fernández"
}
/>
<Input
helperText="Ej: 35764532 (sin puntos)"
id="child-dni"
name="child-dni"
label="DNI del niño o niña:"
placeholder="Ej: 35764532 (sin puntos)"
type="number"
required
error={!!errorMsg["child-dni"]}
helperText={
errorMsg["child-dni"]?.at(0) || "Ej: 35764532 (sin puntos)"
}
/>
<TextArea
helperText="¿Qué problemática motriz tiene?:"
label="¿Qué problemática motriz tiene?"
required
error={!!errorMsg.fullname}
helperText={
errorMsg.fullname?.at(0) || "¿Qué problemática motriz tiene?:"
}
rows={5}
/>
<TextArea
helperText="Información relevante:"
label="Información relevante:"
rows={5}
error={!!errorMsg.fullname}
helperText={errorMsg.fullname?.at(0) || "Información relevante:"}
/>

<div className="flex justify-center md:justify-end">
Expand Down
25 changes: 25 additions & 0 deletions components/LoanRequestForm/form-action.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
"use server";

import {
loanReqFormSchema,
type LoanReqFormSchemaErrors,
} from "./form-schema-validations";

type ErrorMessages = LoanReqFormSchemaErrors["fieldErrors"];

export async function loanReqFormAction(
previousState: ErrorMessages,
formData: FormData
): Promise<ErrorMessages> {
"use server";

const result = loanReqFormSchema.safeParse(Object.fromEntries(formData));

if (!result.success) {
return result.error.flatten().fieldErrors;
}
// TODO: Handle form data
result.data;

return {};
}
33 changes: 33 additions & 0 deletions components/LoanRequestForm/form-schema-validations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { z } from "zod";

const customErrorMap: z.ZodErrorMap = (issue, ctx) => {
if (issue.code === z.ZodIssueCode.too_small) {
return {
message: "Este campo es requerido.",
};
}
return { message: ctx.defaultError };
};

z.setErrorMap(customErrorMap);

export const loanReqFormSchema = z.object({
fullname: z.string().min(1),
dni: z.string().min(1),
calle: z.string().min(1),
altura: z.string().min(1),
depto: z.string().min(1),
localidad: z.string().min(1),
postal: z.string().min(1),
area: z.string().min(1),
phone: z.string().min(1),
email: z.string().min(1).email(),
"child-link": z.string().min(1),
"child-fullname": z.string().min(1),
"child-dni": z.string().min(1),
});

export type LoanReqFormSchema = z.infer<typeof loanReqFormSchema>;
export type LoanReqFormSchemaErrors = z.inferFlattenedErrors<
typeof loanReqFormSchema
>;
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
"react-dom": "^18.2.0",
"sanity": "^3.20.1",
"styled-components": "^6.1.1",
"swiper": "^11.0.5"
"swiper": "^11.0.5",
"zod": "^3.23.4"
},
"devDependencies": {
"@storybook/addon-a11y": "^7.5.3",
Expand Down
8 changes: 8 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -14021,6 +14021,7 @@ __metadata:
tailwindcss: ^3.3.5
tsc-files: ^1.1.4
typescript: ^5.3.2
zod: ^3.23.4
languageName: unknown
linkType: soft

Expand Down Expand Up @@ -20156,3 +20157,10 @@ __metadata:
checksum: 4a73da856738b0634700b52f4ab3fe0bf0a532bea6820ad962d0bda0163d2d5525df4859f89a7238e204a378384e12551985049790c1894c3ac191866e85887f
languageName: node
linkType: hard

"zod@npm:^3.23.4":
version: 3.23.4
resolution: "zod@npm:3.23.4"
checksum: 58f6e298c51d9ae01a1b1a1692ac7f00774b466d9a287a1ff8d61ff1fbe0ae9b0f050ae1cf1a8f71e4c6ccd0333a3cc340f339360fab5f5046cc954d10525a54
languageName: node
linkType: hard