From ad09e98bba2ab682d77a84316da9ed64b2a2c687 Mon Sep 17 00:00:00 2001 From: LandaMm Date: Thu, 5 Jun 2025 20:50:27 +0200 Subject: [PATCH] feat: `create user` page --- web/src/App.tsx | 3 +- web/src/pages/Admin/Users/Create/index.tsx | 188 +++++++++++++++++++++ 2 files changed, 190 insertions(+), 1 deletion(-) create mode 100644 web/src/pages/Admin/Users/Create/index.tsx diff --git a/web/src/App.tsx b/web/src/App.tsx index ff7d637..ece59e1 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -18,6 +18,7 @@ import NotFoundPage from "./pages/NotFound"; import ApiServiceEditPage from "./pages/Admin/ApiServices/Update"; import AdminUsersPage from "./pages/Admin/Users"; import AdminViewUserPage from "./pages/Admin/Users/View"; +import AdminCreateUserPage from "./pages/Admin/Users/Create"; const router = createBrowserRouter([ { @@ -59,7 +60,7 @@ const router = createBrowserRouter([ path: "users", children: [ { index: true, element: }, - // { path: "create", element: }, + { path: "create", element: }, { path: "view/:userId", element: , diff --git a/web/src/pages/Admin/Users/Create/index.tsx b/web/src/pages/Admin/Users/Create/index.tsx new file mode 100644 index 0000000..d9d496c --- /dev/null +++ b/web/src/pages/Admin/Users/Create/index.tsx @@ -0,0 +1,188 @@ +import Breadcrumbs from "@/components/ui/breadcrumbs"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { useUsers } from "@/store/admin/users"; +import { useCallback, type FC } from "react"; +import { useForm } from "react-hook-form"; +import { Link } from "react-router"; + +interface FormData { + fullName: string; + email: string; + phoneNumber: string; + password: string; + repeatPassword: string; + isAdmin: boolean; +} + +const AdminCreateUserPage: FC = () => { + const { + register, + handleSubmit, + formState: { errors }, + } = useForm(); + + const createUser = useUsers((state) => state.createUser); + + const onSubmit = useCallback( + (data: FormData) => { + console.log("Form submitted:", data); + createUser({ + email: data.email, + full_name: data.fullName, + password: data.password, + is_admin: data.isAdmin, + }); + }, + [createUser], + ); + + return ( +
+ +
+ {/* Personal Information */} +
+
+

+ User Personal Info +

+
+
+
+

Name

+ + {errors.fullName && ( + + {errors.fullName.message} + + )} +
+ +
+

+ Email Address +

+ + {errors.email && ( + + {errors.email.message} + + )} +
+ +
+

+ Password +

+ { + if (password.length < 8) { + return "Password must be at least 8 characters long"; + } + if (!password.match(/[a-zA-Z]+/gi)) { + return "Password must contain characters"; + } + if (password.split("").every((c) => c.toLowerCase() == c)) { + return "Password should contain at least 1 uppercase character"; + } + if (!password.match(/\d+/gi)) { + return "Password should contain at least 1 digit"; + } + }, + })} + className="dark:text-gray-100 border border-gray-300 dark:border-gray-700 rounded placeholder:text-gray-600 text-sm p-2 focus:outline-none focus:ring-2 focus:ring-blue-500" + /> + {errors.password && ( + + {errors.password.message} + + )} +
+ +
+

+ Repeat Password +

+ { + if (repeatPassword != password) { + return "Password does not match"; + } + }, + })} + className="dark:text-gray-100 border border-gray-300 dark:border-gray-700 rounded placeholder:text-gray-600 text-sm p-2 focus:outline-none focus:ring-2 focus:ring-blue-500" + /> + {errors.repeatPassword && ( + + {errors.repeatPassword.message} + + )} +
+
+
+ + {/* Final Section */} +
+
+

+ Final Customization & Submit +

+
+
+ + +
+ + + + +
+
+
+
+
+ ); +}; + +export default AdminCreateUserPage;