diff --git a/backend/src/controller/AuthController.ts b/backend/src/controller/AuthController.ts index d2ca83278c74c761f0dae19ce5555fdcf3ac7a4b..9fd8a727d1a0b984b2770d70ceb21a31750fc823 100644 --- a/backend/src/controller/AuthController.ts +++ b/backend/src/controller/AuthController.ts @@ -82,7 +82,7 @@ class AuthController { async register(req: Request, res: Response) { try { - const { name, email, password, address } = req.body; + const { fullname, email, username, password, role } = req.body; const user = await Users.findOne({ where: { email: email } }); @@ -93,20 +93,42 @@ class AuthController { return; } - const hashedPassword = await bcrypt.hash( - password, - PASSWORD_HASH_SALT_ROUNDS, - ); + // const hashedPassword = await bcrypt.hash( + // password, + // PASSWORD_HASH_SALT_ROUNDS, + // ); - const newUser = { - name, - email: email.toLowerCase(), - password: hashedPassword, - address, - }; + let maxId = 0; + if (role === "tenant" || role === "cashier") { + maxId = await new UsersRepo().getMaxNonTableId(); + } else if (role === "customer") { + maxId = await new UsersRepo().getMaxTableId(); + } + + const newUser = new Users(); + newUser.id = maxId + 1; + newUser.fullname = fullname; + newUser.email = email.toLowerCase(); + newUser.username = username; + newUser.password = password; + newUser.role = role; + + // const newUser = { + // id: maxId, + // fullname: fullname, + // email: email.toLowerCase(), + // username: username, + // password: hashedPassword, + // role: role, + // }; + + await new UsersRepo().createUser(newUser); + res.status(201).json({ + status: "Created!", + message: "Successfully created user!", + }); - const result = await Users.create(newUser); - res.send(this.generateTokenResponse(result)); + // res.send(this.generateTokenResponse(result)); } catch (err) { console.error(err); res.status(500).json({ diff --git a/backend/src/router/AuthRouterstashed.ts b/backend/src/router/AuthRouterstashed.ts index aac18d347c58c078a0b3559b24ffbbd0c409a2a2..e29ceb705775b94472437f5746b3862939603c54 100644 --- a/backend/src/router/AuthRouterstashed.ts +++ b/backend/src/router/AuthRouterstashed.ts @@ -1,6 +1,7 @@ import { Router, Request, Response } from "express"; import { BAD_REQUEST } from "../constant/httpStatus"; import { Users } from "../model/Users"; +import UsersRepo from "../repository/UsersRepo"; // import auth from "../middleware/auth.mid.js"; import handler from "express-async-handler"; import jwt from "jsonwebtoken"; @@ -38,7 +39,7 @@ router.post( router.post( "/register", handler(async (req: Request, res: Response) => { - const { name, email, password, address } = req.body; + const { fullname, email, username, password, role } = req.body; const user = await Users.findOne({ where: { email: email } }); @@ -52,11 +53,20 @@ router.post( PASSWORD_HASH_SALT_ROUNDS, ); + let maxId: number; + if (role === "customer") { + maxId = (await new UsersRepo().getMaxTableId()) + 1; + } else { + maxId = (await new UsersRepo().getMaxNonTableId()) + 1; + } + const newUser = { - name, - email: email.toLowerCase(), + id: maxId, + fullname: fullname, + email: email, + username: username, password: hashedPassword, - address, + role: role, }; const result = await Users.create(newUser); diff --git a/frontend/src/AppRoutes.tsx b/frontend/src/AppRoutes.tsx index b41c593b575a9aef4006a30927c481dd6eb72687..155beb3fd551c3119b2244c5292d9df5f9145d8e 100644 --- a/frontend/src/AppRoutes.tsx +++ b/frontend/src/AppRoutes.tsx @@ -26,8 +26,7 @@ export default function AppRoutes() { <Route path="/role" element={<ChooseRolePage />} /> <Route path="/login/:role" element={<LoginPage />} /> <Route path="/login/customer" element={<RegisterTable />} /> - <Route path="/register/cashier" element={<RegisterPage />} /> - <Route path="/register/tenant" element={<RegisterPage />} /> + <Route path="/register/:role" element={<RegisterPage />} /> <Route path="/register/tenant/data" element={<SignUpTenant />} /> <Route path="/tenant/:tenantid" element={<TenantInfo />} /> <Route path="/cart" element={<ShoppingCart />} /> diff --git a/frontend/src/components/RegisterForm.tsx b/frontend/src/components/RegisterForm.tsx index 3b410caa8ad45d17e0e4d9e000b3a084bc4da13a..2007b958b579866d5f3e28e8cba3031eb281a8a5 100644 --- a/frontend/src/components/RegisterForm.tsx +++ b/frontend/src/components/RegisterForm.tsx @@ -1,4 +1,57 @@ +import { useState, useEffect } from "react"; +import { useForm, SubmitHandler } from "react-hook-form"; +import { useNavigate, useParams, useSearchParams } from "react-router-dom"; +import { useAuth } from "../hooks/useAuth"; + +interface RegisterFormInput { + fullname: string; + email: string; + username: string; + password: string; + role: string; +} + export default function RegisterForm() { + const { handleSubmit, register } = useForm<RegisterFormInput>(); + const [fullname, setFullname] = useState<string>(""); + const [email, setEmail] = useState<string>(""); + const [username, setUsername] = useState<string>(""); + const [password, setPassword] = useState<string>(""); + + const navigate = useNavigate(); + const { user, registers } = useAuth(); + const params = useParams(); + const [searchParams] = useSearchParams(); + const returnUrl = searchParams.get("returnUrl"); + + const selectedRole = params.role as string; + + useEffect(() => { + if (!user) return; + let targetRoute = ""; + if (selectedRole === "tenant") { + targetRoute = "/tenant/menus"; + } else if (selectedRole === "cashier") { + targetRoute = "/cashier/payments"; + } else if (selectedRole === "customer") { + targetRoute = "/"; + } + returnUrl ? navigate(returnUrl) : navigate(targetRoute); + }, [user]); + + const submit: SubmitHandler<RegisterFormInput> = async ({ + fullname, + email, + username, + password, + role, + }) => { + console.log( + `fullname: ${fullname}, email: ${email}, username: ${username}, password: ${password}, role:${role} MASUK`, + ); + await registers(fullname, email, username, password, selectedRole); + }; + return ( <div className="relative bg-white rounded-xl px-16"> <div className="flex flex-col items-center justify-between mt-4 p-4 md:p-5"> @@ -7,7 +60,11 @@ export default function RegisterForm() { </h1> </div> - <form action="#" className="p-4 md:p-5"> + <form + onSubmit={handleSubmit(submit)} + noValidate + className="p-4 md:p-5" + > <div className="gap-4 mb-4"> <div className="my-2"> <label @@ -18,11 +75,13 @@ export default function RegisterForm() { </label> <input type="text" - name="fullname" id="fullname" className="font-nunito bg-white border border-mealshub-orange text-gray-900 text-m rounded-2xl focus:ring-mealshub-orange focus:border-mealshub-orange block w-96 px-4 p-2.5 h-14" placeholder="Name" required + {...register("fullname", { + required: true, + })} /> </div> <div className="my-2"> @@ -34,11 +93,17 @@ export default function RegisterForm() { </label> <input type="text" - name="email" id="email" className="font-nunito bg-white border border-mealshub-orange text-gray-900 text-m rounded-2xl focus:ring-mealshub-orange focus:border-mealshub-orange block w-96 px-4 p-2.5 h-14" placeholder="Email" required + {...register("email", { + required: true, + pattern: { + value: /^[\w-.]+@([\w-]+\.)+[\w-]{2,63}$/i, + message: "Email is not valid.", + }, + })} /> </div> <div className="my-2"> @@ -50,27 +115,34 @@ export default function RegisterForm() { </label> <input type="text" - name="username" id="username" className="font-nunito bg-white border border-mealshub-orange text-gray-900 text-m rounded-2xl focus:ring-mealshub-orange focus:border-mealshub-orange block w-96 px-4 p-2.5 h-14" placeholder="Username" required + {...register("username", { + required: true, + })} /> </div> <div className="my-2"> <label htmlFor="password" className="block mb-2 text-xl font-bold text-mealshub-orange " + {...register("password", { + required: true, + })} > Password </label> <input - type="text" - name="password" + type="password" id="password" className="font-nunito bg-white border border-mealshub-orange text-gray-900 text-m rounded-2xl focus:ring-mealshub-orange focus:border-mealshub-orange block w-96 px-4 p-2.5 h-14" placeholder="Password" required + {...register("password", { + required: true, + })} /> </div> </div> diff --git a/frontend/src/hooks/useAuth.tsx b/frontend/src/hooks/useAuth.tsx index 80f5f37171ef3e2794f3d52f7900e02663d6effc..72fb43cc4c535cd971b415877512e95c68db0db6 100644 --- a/frontend/src/hooks/useAuth.tsx +++ b/frontend/src/hooks/useAuth.tsx @@ -19,11 +19,27 @@ interface AuthTable { id: number; } +interface newUser { + id: number; + fullname: string; + email: string; + username: string; + password: string; + role: string; +} + interface AuthContextProps { user: AuthUser | AuthTable | null; login: (email: string, password: string, role: string) => Promise<void>; logout: () => void; showUser: () => void; + registers: ( + fullname: string, + email: string, + username: string, + password: string, + role: string, + ) => Promise<void>; } export const AuthContext = createContext<AuthContextProps | null>(null); @@ -35,50 +51,40 @@ export const AuthProvider: React.FC<{ children: ReactNode }> = ({ console.log(user); const login = async (email: string, password: string, role: string) => { - if (role === "tenant-cashier") { - try { - console.log(`email: ${email}, password: ${password}. MASUK`); - const loggedInUser = await userService.login( - email, - password, - "tenant-cashier", - ); - setUser(loggedInUser); - toast.success("Logged in successfully."); - } catch (error: any) { - toast.error( - error.response?.data?.message || - "An error occurred during login.", - ); - } - } else if (role === "customer") { - try { - console.log(`num_seat: ${email}, id_table: ${password}. MASUK`); - const loggedInUser = await userService.login( - email, - password, - "customer", - ); - setUser(loggedInUser); - toast.success("Logged in successfully."); - } catch (error: any) { - toast.error( - error.response?.data?.message || - "An error occurred during login.", - ); - } + try { + console.log(`email: ${email}, password: ${password}. MASUK`); + const loggedInUser = await userService.login(email, password, role); + setUser(loggedInUser); + toast.success("Logged in successfully."); + } catch (error: any) { + toast.error( + error.response?.data?.message || + "An error occurred during login.", + ); } }; - // const register = async (data) => { - // try { - // const user = await userService.register(data); - // setUser(user); - // toast.success("Register Successful"); - // } catch (error: any) { - // toast.error(error.response.data); - // } - // }; + const registers = async ( + fullname: string, + email: string, + username: string, + password: string, + role: string, + ) => { + try { + const user = await userService.register( + fullname, + email, + username, + password, + role, + ); + setUser(user); + toast.success("Register Successful"); + } catch (error: any) { + toast.error(error.response.data); + } + }; const logout = () => { userService.logout(); @@ -107,7 +113,7 @@ export const AuthProvider: React.FC<{ children: ReactNode }> = ({ login, logout, showUser, - // register, + registers, // updateProfile, // changePassword, }; diff --git a/frontend/src/services/userService.ts b/frontend/src/services/userService.ts index a3b189d9cd5558b083163042657026db1623a59a..1a99d9ce320f76e15fbcebd02e5ec6f0d214b711 100644 --- a/frontend/src/services/userService.ts +++ b/frontend/src/services/userService.ts @@ -22,8 +22,20 @@ export const logout = () => { localStorage.removeItem("user"); }; -export const register = async (registerData: any) => { - const { data } = await axios.post("users/register", registerData); +export const register = async ( + fullname: string, + email: string, + username: string, + password: string, + role: string, +) => { + const { data } = await axios.post("http://localhost:8000/auth/register", { + fullname, + email, + username, + password, + role, + }); localStorage.setItem("user", JSON.stringify(data)); return data; };