Skip to content

Commit

Permalink
Migrate to zod for form validation
Browse files Browse the repository at this point in the history
  • Loading branch information
pacholoamit committed Jul 2, 2022
1 parent e9fb005 commit 488f8c8
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 20 deletions.
7 changes: 7 additions & 0 deletions web/api/dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,10 @@ export type CreateProjectRequest = {
name: string;
description: string;
};

export type CreateTaskRequest = {
title: string;
description: string;
status: string;
label: string;
};
38 changes: 23 additions & 15 deletions web/components/project/create-project-modal.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,39 @@
import { Button, Textarea, TextInput, Stack, Text } from "@mantine/core";
import { useForm } from "@mantine/form";
import { useForm, zodResolver } from "@mantine/form";
import { ContextModalProps } from "@mantine/modals";
import { showNotification } from "@mantine/notifications";
import { z } from "zod";
import React from "react";
import useCreateProject from "../../hooks/useCreateProject";

const initialValues = {
name: "",
description: "",
};

const schema = z.object({
name: z
.string()
.min(1, { message: "You can't have a project without a name 🤔" }),
description: z.string(),
});

const CreateProjectModal = ({ context, id }: ContextModalProps) => {
const { mutate, isLoading, isSuccess, isError, error } = useCreateProject();

const form = useForm({
initialValues: {
projectName: "",
projectDescription: "",
},
validate: {
projectName: (value) =>
value.length > 0 ? null : "Can't have a project without a name 🤔",
},
schema: zodResolver(schema),
initialValues,
});
const projectNameProp = form.getInputProps("projectName");

const nameProp = form.getInputProps("name");

React.useEffect(() => {
if (isSuccess) {
context.closeModal(id);
showNotification({
title: `WOOO! New project created 🎉`,
message: `Project ${projectNameProp.value} successfully created!`,
message: `Project ${nameProp.value} successfully created!`,

styles: (theme) => ({
root: {
Expand All @@ -49,23 +57,23 @@ const CreateProjectModal = ({ context, id }: ContextModalProps) => {

return (
<form
onSubmit={form.onSubmit(({ projectName, projectDescription }) =>
mutate({ name: projectName, description: projectDescription })
onSubmit={form.onSubmit(({ name, description }) =>
mutate({ name, description })
)}
>
<Stack>
<TextInput
label="Project Name"
placeholder="My super awesome project!"
disabled={isLoading}
{...form.getInputProps("projectName")}
{...form.getInputProps("name")}
data-autoFocus
/>
<Textarea
label="Project Description"
placeholder="Something about my awesome project!"
disabled={isLoading}
{...form.getInputProps("projectDescription")}
{...form.getInputProps("description")}
/>
{isError && (
<Text color={"red"}>
Expand Down
30 changes: 30 additions & 0 deletions web/components/tasks/create-task-modal.tsx
Original file line number Diff line number Diff line change
@@ -1,2 +1,32 @@
import { ContextModalProps } from "@mantine/modals";
import useCreateTask from "../../hooks/useCreateTask";
import React from "react";
import { useForm, zodResolver } from "@mantine/form";
import { z } from "zod";

const initialValues = {
taskTitle: "",
taskDescription: "",
taskStatus: "",
taskLabel: "",
};

const schema = z.object({
taskTitle: z.string().min(1),
taskDescription: z.string(),
taskStatus: z.string(),
taskLabel: z.string(),
});

const CreateTaskModal = ({ context, id }: ContextModalProps) => {
const { mutate, isLoading, isSuccess, isError, error } = useCreateTask();

const form = useForm({
schema: zodResolver(schema),
initialValues,
});

return <div></div>;
};

export default CreateTaskModal;
19 changes: 15 additions & 4 deletions web/hooks/useCreateTask.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
interface CreateTaskArgs {
name: string;
description: string;
}
import { useMutation } from "react-query";
import { apiInstance } from "../api/config";
import { CreateTaskRequest, Task } from "../api/dto";

const createTask = (data: CreateTaskRequest) => {
return apiInstance
.post("/task", data)
.then((res) => res.data) as Promise<Task>;
};

const useCreateTask = () => {
return useMutation((formData: CreateTaskRequest) => createTask(formData));
};

export default useCreateTask;
3 changes: 2 additions & 1 deletion web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
"react-dom": "18.2.0",
"react-query": "^3.39.1",
"swr": "^1.3.0",
"tabler-icons-react": "^1.52.0"
"tabler-icons-react": "^1.52.0",
"zod": "^3.17.3"
},
"devDependencies": {
"@types/node": "18.0.0",
Expand Down
5 changes: 5 additions & 0 deletions web/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2601,3 +2601,8 @@ yallist@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==

zod@^3.17.3:
version "3.17.3"
resolved "https://registry.yarnpkg.com/zod/-/zod-3.17.3.tgz#86abbc670ff0063a4588d85a4dcc917d6e4af2ba"
integrity sha512-4oKP5zvG6GGbMlqBkI5FESOAweldEhSOZ6LI6cG+JzUT7ofj1ZOC0PJudpQOpT1iqOFpYYtX5Pw0+o403y4bcg==

0 comments on commit 488f8c8

Please sign in to comment.