From ba89880f8ab174c47c9521720cce9824dd312534 Mon Sep 17 00:00:00 2001 From: LandaMm Date: Wed, 21 May 2025 19:27:03 +0200 Subject: [PATCH] feat: finished register page --- web/src/pages/Register/index.tsx | 259 +++++++++++++++++++++++++++++++ 1 file changed, 259 insertions(+) create mode 100644 web/src/pages/Register/index.tsx diff --git a/web/src/pages/Register/index.tsx b/web/src/pages/Register/index.tsx new file mode 100644 index 0000000..d0710f9 --- /dev/null +++ b/web/src/pages/Register/index.tsx @@ -0,0 +1,259 @@ +import { Card, CardContent } from "@/components/ui/card"; +import { Mail, Lock, User, Phone } from "lucide-react"; +import { Link } from "react-router-dom"; +import { Input } from "@/components/ui/input"; +import { Button } from "@/components/ui/button"; + +import overlay from "@/assets/overlay.jpg"; +import { useCallback, useState } from "react"; +import { useForm, type SubmitHandler } from "react-hook-form"; + +interface RegisterForm { + fullName: string; + email: string; + phoneNumber: string; + password: string; + repeatPassword: string; +} + +export default function RegisterPage() { + const { + register, + handleSubmit, + reset, + formState: { errors }, + } = useForm(); + + const [isLoading, setLoading] = useState(false); + const [error, setError] = useState(""); + const [success, setSuccess] = useState(""); + + const onSubmit: SubmitHandler = useCallback( + async (data) => { + console.log({ data }); + + setLoading(true); + setError(""); + setSuccess(""); + + try { + const response = await fetch("/api/v1/register", { + method: "POST", + body: JSON.stringify({ + full_name: data.fullName, + email: data.email, + ...(data.phoneNumber ? { phone_number: data.phoneNumber } : {}), + password: data.password, + }), + headers: { + "Content-Type": "application/json", + }, + }); + if (response.status != 200) { + const json = await response.json(); + const text = json.error || "Unexpected error happened"; + setError( + `Failed to create an account. ${ + text[0].toUpperCase() + text.slice(1) + }` + ); + } else { + setSuccess( + "Account has been created. You can now log into your new account" + ); + reset(); + } + } catch (err) { + console.log(err); + setError("Failed to create account. Unexpected error happened"); + } finally { + setLoading(false); + } + }, + [reset] + ); + + return ( +
+
+ +
+ icon + +
+

+ Sign Up +

+

+ Fill up this form to start using homelab services and tools. +

+
+ + +
+
+
+ + +
+ {!!errors.fullName && ( +

+ {errors.fullName.message ?? "Full Name is required"} +

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

+ {errors.email.message ?? "Email is required"} +

+ )} +
+ +
+
+ + +
+ {!!errors.phoneNumber && ( +

+ {errors.phoneNumber.message ?? "Phone Number is required"} +

+ )} +
+ +
+
+ + { + 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"; + } + }, + })} + aria-invalid={errors.password ? "true" : "false"} + /> +
+ {!!errors.password && ( +

+ {errors.password.message ?? "Password is required"} +

+ )} +
+ +
+
+ + { + if (repeatPassword != password) { + return "Password does not match"; + } + }, + })} + aria-invalid={errors.repeatPassword ? "true" : "false"} + /> +
+ {!!errors.repeatPassword && ( +

+ {errors.repeatPassword.message ?? "Password is required"} +

+ )} +
+ + {success.length > 0 && ( +
+ {success} +
+ )} + + {error.length > 0 && ( +
+ {error} +
+ )} + + +
+ Already have an account?{" "} + + Login + +
+
+
+
+
+
+
+ ); +}