diff --git a/src/app/(auth)/register/page.tsx b/src/app/(auth)/register/page.tsx index f0544db..82450fb 100644 --- a/src/app/(auth)/register/page.tsx +++ b/src/app/(auth)/register/page.tsx @@ -1,6 +1,10 @@ "use client"; -import createUser from "@/modules/auth/actions/createUser"; +import createUserAction from "@/modules/auth/actions/createUserAction"; +import createUser from "@/modules/auth/actions/createUserAction"; +import { CreateUserSchema } from "@/modules/auth/formSchemas/CreateUserFormSchema"; +import DashboardError from "@/modules/dashboard/errors/DashboardError"; +import withServerAction from "@/modules/dashboard/utils/withServerAction"; import { Paper, PasswordInput, @@ -12,65 +16,53 @@ import { Button, } from "@mantine/core"; import { useForm } from "@mantine/form"; +import { showNotification } from "@mantine/notifications"; import React, { useEffect, useState } from "react"; -export interface RegisterFormSchema { - email: string; - password: string; - passwordConfirmation: string; - name: string; -} - export default function RegisterPage() { const [errorMessage, setErrorMessage] = useState(""); - const form = useForm({ + const form = useForm({ initialValues: { email: "", - password: "", - passwordConfirmation: "", + plainPassword: "", + plainPasswordConfirmation: "", name: "", }, validate: { email: (value: string) => /^\S+@\S+$/.test(value) ? null : "Invalid email", - password: (value: string) => + plainPassword: (value: string) => value.length >= 6 ? null : "Password should be at least 6 characters", - passwordConfirmation: (value: string, values: RegisterFormSchema) => - value === values.password ? null : "Passwords should match", + plainPasswordConfirmation: (value: string, values: CreateUserSchema) => + value === values.plainPassword ? null : "Passwords should match", name: (value: string) => value.length > 0 ? null : "Name is required", }, }); - const handleSubmit = async (values: RegisterFormSchema) => { - const formData = new FormData(); - Object.entries(values).forEach(([key, value]) => { - formData.append(key, value); - }); - - const response = await createUser(formData); - - if (!response.success) { - setErrorMessage(response.error.message); - - if (response.error.errors) { - const errors = Object.entries(response.error.errors).reduce( - (prev, [k, v]) => { - prev[k] = v[0]; - return prev; - }, - {} as { [k: string]: string } - ); - - form.setErrors(errors); - console.log(form.errors); - } else { - form.clearErrors(); - } - } + const handleSubmit = async (values: CreateUserSchema) => { + withServerAction(createUserAction, form.values) + .then((response) => { + showNotification({message: "Register Success", color: "green"}) + }) + .catch((e) => { + if (e instanceof DashboardError) { + if (e.errorCode === "INVALID_FORM_DATA") { + form.setErrors(e.formErrors ?? {}); + } else { + setErrorMessage(`ERROR: ${e.message} (${e.errorCode})`); + } + } else if (e instanceof Error) { + setErrorMessage(`ERROR: ${e.message}`); + } else { + setErrorMessage( + `Unkown error is occured. Please contact administrator` + ); + } + }) }; return ( @@ -102,14 +94,14 @@ export default function RegisterPage() { placeholder="Your password" name="password" autoComplete="new-password" - {...form.getInputProps("password")} + {...form.getInputProps("plainPassword")} /> diff --git a/src/modules/auth/actions/createUser.ts b/src/modules/auth/actions/createUser.ts deleted file mode 100644 index e52b685..0000000 --- a/src/modules/auth/actions/createUser.ts +++ /dev/null @@ -1,43 +0,0 @@ -"use server"; -import { z } from "zod"; -import prisma from "@/core/db"; -import { cookies } from "next/headers"; -import { redirect } from "next/navigation"; -import { hashPassword } from "../utils/hashPassword"; -import { createJwtToken } from "../utils/createJwtToken"; -import createUser from "../services/createUser"; - -/** - * Creates a new user in the system. - * - * @param formData - The form data containing user details. - * @returns An object indicating the result of the operation. - */ -export default async function createUserAction(formData: FormData) { - //TODO: Add Throttling - //TODO: Add validation check if the user is already logged in - - try { - const parsedData = { - email: formData.get("email")?.toString() ?? "", - name: formData.get("name")?.toString() ?? "", - plainPassword: formData.get("password")?.toString() ?? "", - plainPasswordConfirmation: - formData.get("passwordConfirmation")?.toString() ?? "", - }; - await createUser(parsedData); - redirect("/dashboard"); - } catch (e: unknown) { - // Handle unexpected errors - console.error(e); - //@ts-ignore - console.log(e.message); - return { - success: false, - error: { - message: - "An unexpected error occurred on the server. Please try again or contact the administrator.", - }, - }; - } -} diff --git a/src/modules/auth/actions/createUserAction.ts b/src/modules/auth/actions/createUserAction.ts new file mode 100644 index 0000000..5fe52e0 --- /dev/null +++ b/src/modules/auth/actions/createUserAction.ts @@ -0,0 +1,29 @@ +"use server"; +import { z } from "zod"; +import prisma from "@/core/db"; +import { cookies } from "next/headers"; +import { redirect } from "next/navigation"; +import { hashPassword } from "../utils/hashPassword"; +import { createJwtToken } from "../utils/createJwtToken"; +import createUser from "../services/createUser"; +import ServerResponseAction from "@/modules/dashboard/types/ServerResponseAction"; +import handleCatch from "@/modules/dashboard/utils/handleCatch"; +import { CreateUserSchema } from "../formSchemas/CreateUserFormSchema"; + +/** + * Creates a new user in the system. + * + * @param formData - The form data containing user details. + * @returns An object indicating the result of the operation. + */ +export default async function createUserAction(formData: CreateUserSchema): Promise { + //TODO: Add Throttling + //TODO: Add validation check if the user is already logged in + + try { + await createUser(formData); + redirect("/dashboard"); + } catch (e) { + return handleCatch(e) + } +}