Skip to content

Commit

Permalink
validation form
Browse files Browse the repository at this point in the history
  • Loading branch information
mtguerson committed Apr 9, 2024
1 parent 704cf51 commit fe8c41b
Show file tree
Hide file tree
Showing 7 changed files with 154 additions and 34 deletions.
8 changes: 7 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,15 @@
"preview": "vite preview"
},
"dependencies": {
"@hookform/resolvers": "^3.3.4",
"@radix-ui/react-icons": "^1.3.0",
"clsx": "^2.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.22.3"
"react-hook-form": "^7.51.2",
"react-router-dom": "^6.22.3",
"tailwind-merge": "^2.2.2",
"zod": "^3.22.4"
},
"devDependencies": {
"@types/react": "^18.2.66",
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/app/utils/cn.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { twMerge } from "tailwind-merge";
import clsx, { ClassValue } from "clsx";

export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
9 changes: 6 additions & 3 deletions frontend/src/view/components/Button.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { ComponentProps } from "react";
import { cn } from "../../app/utils/cn";

interface ButtonProps extends ComponentProps<'button'> {}

export function Button(props: ButtonProps) {
export function Button({ className, ...props }: ButtonProps) {
return (
<button
{...props}
className="bg-teal-900 hover:bg-teal-800 disabled:bg-gray-100 disabled:text-gray-400 disabled:cursor-not-allowed
px-6 h-12 rounded-2xl font-medium text-white transition-all"
className={cn(
"bg-teal-900 hover:bg-teal-800 disabled:bg-gray-100 disabled:text-gray-400 disabled:cursor-not-allowed px-6 h-12 rounded-2xl font-medium text-white transition-all",
className,
)}
/>
);
}
63 changes: 39 additions & 24 deletions frontend/src/view/components/Input.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,46 @@
import { ComponentProps } from "react";
import { ComponentProps, forwardRef } from "react";
import { CrossCircledIcon } from "@radix-ui/react-icons";
import { cn } from "../../app/utils/cn";

interface InputProps extends ComponentProps<'input'> {
name: string;
error?: string;
}

export function Input({ placeholder, name, id, ...props }: InputProps) {
const inputId = id ?? name;
export const Input = forwardRef<HTMLInputElement, InputProps>(
({ placeholder, name, id, error, className, ...props }, ref) => {
const inputId = id ?? name;

return (
<div className="relative">
<input
{...props}
name={name}
id={inputId}
className="bg-white w-full rounded-lg border border-gray-500 px-3 h-[52px]
text-gray-800 pt-4 peer placeholder-shown:pt-0 focus:border-gray-800 transition-all
outline-none"
placeholder=" "
/>
return (
<div className="relative">
<input
{...props}
ref={ref}
name={name}
id={inputId}
placeholder=" "
className={cn(
"bg-white w-full rounded-lg border border-gray-500 px-3 h-[52px] text-gray-800 pt-4 peer placeholder-shown:pt-0 focus:border-gray-800 transition-all outline-none",
error && "!border-red-900",
className,
)}
/>

<label
htmlFor={inputId}
className="absolute text-xs left-[13px] top-2 pointer-events-none text-gray-700
peer-placeholder-shown:text-base peer-placeholder-shown:top-3.5 transition-all"
>
{placeholder}
</label>
</div>
);
}
<label
htmlFor={inputId}
className="absolute text-xs left-[13px] top-2 pointer-events-none text-gray-700
peer-placeholder-shown:text-base peer-placeholder-shown:top-3.5 transition-all"
>
{placeholder}
</label>

{error && (
<div className="flex gap-2 items-center mt-2 text-red-900">
<CrossCircledIcon />
<span className="text-xs">{error}</span>
</div>
)}
</div>
);
}
);
11 changes: 8 additions & 3 deletions frontend/src/view/pages/Login/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { Link } from "react-router-dom";
import { Input } from "../../components/Input";
import { Button } from "../../components/Button";
import { useLoginController } from "./useLoginController";

export function Login() {
const { handleSubmit, register, errors } = useLoginController();

return (
<>
<header className="flex flex-col items-center gap-4 text-center">
Expand All @@ -24,16 +27,18 @@ export function Login() {
</p>
</header>

<form className="mt-[60px] flex flex-col gap-4">
<form className="mt-[60px] flex flex-col gap-4" onSubmit={handleSubmit}>
<Input
type="email"
placeholder="E-mail"
name="email"
error={errors.email?.message}
{...register("email")}
/>
<Input
type="password"
placeholder="Senha"
name="password"
error={errors.password?.message}
{...register("password")}
/>

<Button type="submit" className="mt-2">
Expand Down
26 changes: 26 additions & 0 deletions frontend/src/view/pages/Login/useLoginController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';

const schema = z.object({
email: z.string().min(1, "E-mail é obrigatório").email("Informe um e-mail válido"),
password: z.string().min(8, "Senha deve ter no mínimo 8 caracteres"),
});

type FormData = z.infer<typeof schema>;

export function useLoginController() {
const {
register,
handleSubmit: hookFormHandleSubmit,
formState: { errors },
} = useForm<FormData>({
resolver: zodResolver(schema),
});

const handleSubmit = hookFormHandleSubmit((data) => {
console.log("Chama a Api com:", data);
});

return { handleSubmit, register, errors };
}
65 changes: 62 additions & 3 deletions frontend/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@
resolved "https://registry.yarnpkg.com/@alloc/quick-lru/-/quick-lru-5.2.0.tgz#7bf68b20c0a350f936915fcae06f58e32007ce30"
integrity sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==

"@babel/runtime@^7.24.0":
version "7.24.4"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.4.tgz#de795accd698007a66ba44add6cc86542aff1edd"
integrity sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==
dependencies:
regenerator-runtime "^0.14.0"

"@esbuild/aix-ppc64@0.20.2":
version "0.20.2"
resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz#a70f4ac11c6a1dfc18b8bbb13284155d933b9537"
Expand Down Expand Up @@ -159,6 +166,11 @@
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.57.0.tgz#a5417ae8427873f1dd08b70b3574b453e67b5f7f"
integrity sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==

"@hookform/resolvers@^3.3.4":
version "3.3.4"
resolved "https://registry.yarnpkg.com/@hookform/resolvers/-/resolvers-3.3.4.tgz#de9b668c2835eb06892290192de6e2a5c906229b"
integrity sha512-o5cgpGOuJYrd+iMKvkttOclgwRW86EsWJZZRC23prf0uU2i48Htq4PuT73AVb9ionFyZrwYEITuOFGF+BydEtQ==

"@humanwhocodes/config-array@^0.11.14":
version "0.11.14"
resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.14.tgz#d78e481a039f7566ecc9660b4ea7fe6b1fec442b"
Expand Down Expand Up @@ -248,6 +260,11 @@
resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33"
integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==

"@radix-ui/react-icons@^1.3.0":
version "1.3.0"
resolved "https://registry.yarnpkg.com/@radix-ui/react-icons/-/react-icons-1.3.0.tgz#c61af8f323d87682c5ca76b856d60c2312dbcb69"
integrity sha512-jQxj/0LKgp+j9BiTXz3O3sgs26RNet2iLWmsPyRz2SIcR4q/4SbazXfnYwbAr+vLYKSfc7qxzyGQA1HLlYiuNw==

"@remix-run/router@1.15.3":
version "1.15.3"
resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.15.3.tgz#d2509048d69dbb72d5389a14945339f1430b2d3c"
Expand Down Expand Up @@ -704,6 +721,11 @@ chokidar@^3.5.3:
optionalDependencies:
fsevents "~2.3.2"

clsx@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.0.tgz#e851283bcb5c80ee7608db18487433f7b23f77cb"
integrity sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==

color-convert@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
Expand Down Expand Up @@ -1546,6 +1568,11 @@ react-dom@^18.2.0:
loose-envify "^1.1.0"
scheduler "^0.23.0"

react-hook-form@^7.51.2:
version "7.51.2"
resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.51.2.tgz#79f7f72ee217c5114ff831012d1a7ec344096e7f"
integrity sha512-y++lwaWjtzDt/XNnyGDQy6goHskFualmDlf+jzEZvjvz6KWDf7EboL7pUvRCzPTJd0EOPpdekYaQLEvvG6m6HA==

react-router-dom@^6.22.3:
version "6.22.3"
resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.22.3.tgz#9781415667fd1361a475146c5826d9f16752a691"
Expand Down Expand Up @@ -1582,6 +1609,11 @@ readdirp@~3.6.0:
dependencies:
picomatch "^2.2.1"

regenerator-runtime@^0.14.0:
version "0.14.1"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f"
integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==

resolve-from@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
Expand Down Expand Up @@ -1680,8 +1712,16 @@ source-map-js@^1.2.0:
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.0.tgz#16b809c162517b5b8c3e7dcd315a2a5c2612b2af"
integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==

"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0:
name string-width-cjs
"string-width-cjs@npm:string-width@^4.2.0":
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
dependencies:
emoji-regex "^8.0.0"
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"

string-width@^4.1.0:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
Expand All @@ -1699,7 +1739,14 @@ string-width@^5.0.1, string-width@^5.1.2:
emoji-regex "^9.2.2"
strip-ansi "^7.0.1"

"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
dependencies:
ansi-regex "^5.0.1"

strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
Expand Down Expand Up @@ -1743,6 +1790,13 @@ supports-preserve-symlinks-flag@^1.0.0:
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==

tailwind-merge@^2.2.2:
version "2.2.2"
resolved "https://registry.yarnpkg.com/tailwind-merge/-/tailwind-merge-2.2.2.tgz#87341e7604f0e20499939e152cd2841f41f7a3df"
integrity sha512-tWANXsnmJzgw6mQ07nE3aCDkCK4QdT3ThPMCzawoYA2Pws7vSTCvz3Vrjg61jVUGfFZPJzxEP+NimbcW+EdaDw==
dependencies:
"@babel/runtime" "^7.24.0"

tailwindcss@^3.4.3:
version "3.4.3"
resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.4.3.tgz#be48f5283df77dfced705451319a5dffb8621519"
Expand Down Expand Up @@ -1899,3 +1953,8 @@ yocto-queue@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==

zod@^3.22.4:
version "3.22.4"
resolved "https://registry.yarnpkg.com/zod/-/zod-3.22.4.tgz#f31c3a9386f61b1f228af56faa9255e845cf3fff"
integrity sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==

0 comments on commit fe8c41b

Please sign in to comment.