From 4073b2f57eb679d91b88f7a2532124c449ad34fa Mon Sep 17 00:00:00 2001 From: Steven Date: Mon, 26 Jun 2023 20:00:38 +0800 Subject: [PATCH] feat: add sign up page --- api/v1/auth.go | 3 +- web/src/helpers/api.ts | 3 +- web/src/pages/{Auth.tsx => SignIn.tsx} | 77 ++++++++-------- web/src/pages/SignUp.tsx | 117 +++++++++++++++++++++++++ web/src/routers/index.tsx | 9 +- 5 files changed, 164 insertions(+), 45 deletions(-) rename web/src/pages/{Auth.tsx => SignIn.tsx} (55%) create mode 100644 web/src/pages/SignUp.tsx diff --git a/api/v1/auth.go b/api/v1/auth.go index bf11e59..f913aa6 100644 --- a/api/v1/auth.go +++ b/api/v1/auth.go @@ -18,6 +18,7 @@ type SignInRequest struct { } type SignUpRequest struct { + Nickname string `json:"nickname"` Email string `json:"email"` Password string `json:"password"` } @@ -77,7 +78,7 @@ func (s *APIV1Service) registerAuthRoutes(g *echo.Group, secret string) { create := &store.User{ Email: signup.Email, - Nickname: signup.Email, + Nickname: signup.Nickname, PasswordHash: string(passwordHash), } existingUsers, err := s.Store.ListUsers(ctx, &store.FindUser{}) diff --git a/web/src/helpers/api.ts b/web/src/helpers/api.ts index 6be713f..a86030f 100644 --- a/web/src/helpers/api.ts +++ b/web/src/helpers/api.ts @@ -11,9 +11,10 @@ export function signin(email: string, password: string) { }); } -export function signup(email: string, password: string) { +export function signup(email: string, nickname: string, password: string) { return axios.post("/api/v1/auth/signup", { email, + nickname, password, }); } diff --git a/web/src/pages/Auth.tsx b/web/src/pages/SignIn.tsx similarity index 55% rename from web/src/pages/Auth.tsx rename to web/src/pages/SignIn.tsx index b8217c8..a106f3f 100644 --- a/web/src/pages/Auth.tsx +++ b/web/src/pages/SignIn.tsx @@ -1,17 +1,18 @@ import { Button, Input } from "@mui/joy"; import React, { useEffect, useState } from "react"; -import { useNavigate } from "react-router-dom"; +import { Link, useNavigate } from "react-router-dom"; import { toast } from "react-hot-toast"; import * as api from "../helpers/api"; import { userService } from "../services"; import useLoading from "../hooks/useLoading"; import Icon from "../components/Icon"; -const Auth: React.FC = () => { +const SignIn: React.FC = () => { const navigate = useNavigate(); const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const actionBtnLoadingState = useLoading(false); + const allowConfirm = email.length > 0 && password.length > 0; useEffect(() => { userService.doSignOut(); @@ -50,29 +51,6 @@ const Auth: React.FC = () => { actionBtnLoadingState.setFinish(); }; - const handleSignupBtnClick = async () => { - if (actionBtnLoadingState.isLoading) { - return; - } - - try { - actionBtnLoadingState.setLoading(); - await api.signup(email, password); - const user = await userService.doSignIn(); - if (user) { - navigate("/", { - replace: true, - }); - } else { - toast.error("Signup failed"); - } - } catch (error: any) { - console.error(error); - toast.error(error.response.data.message); - } - actionBtnLoadingState.setFinish(); - }; - return (
@@ -84,28 +62,45 @@ const Auth: React.FC = () => { {actionBtnLoadingState.isLoading && }
-
-
- Email - +
+
+
+ Email + +
+
+ Password + +
-
- Password - +
+
-
-
- - -
+ +

); }; -export default Auth; +export default SignIn; diff --git a/web/src/pages/SignUp.tsx b/web/src/pages/SignUp.tsx new file mode 100644 index 0000000..1ee6127 --- /dev/null +++ b/web/src/pages/SignUp.tsx @@ -0,0 +1,117 @@ +import { Button, Input } from "@mui/joy"; +import React, { useEffect, useState } from "react"; +import { Link, useNavigate } from "react-router-dom"; +import { toast } from "react-hot-toast"; +import * as api from "../helpers/api"; +import { userService } from "../services"; +import useLoading from "../hooks/useLoading"; +import Icon from "../components/Icon"; + +const SignUp: React.FC = () => { + const navigate = useNavigate(); + const [email, setEmail] = useState(""); + const [nickname, setNickname] = useState(""); + const [password, setPassword] = useState(""); + const actionBtnLoadingState = useLoading(false); + const allowConfirm = email.length > 0 && nickname.length > 0 && password.length > 0; + + useEffect(() => { + userService.doSignOut(); + }, []); + + const handleEmailInputChanged = (e: React.ChangeEvent) => { + const text = e.target.value as string; + setEmail(text); + }; + + const handleNicknameInputChanged = (e: React.ChangeEvent) => { + const text = e.target.value as string; + setNickname(text); + }; + + const handlePasswordInputChanged = (e: React.ChangeEvent) => { + const text = e.target.value as string; + setPassword(text); + }; + + const handleSignupBtnClick = async () => { + if (actionBtnLoadingState.isLoading) { + return; + } + + try { + actionBtnLoadingState.setLoading(); + await api.signup(email, nickname, password); + const user = await userService.doSignIn(); + if (user) { + navigate("/", { + replace: true, + }); + } else { + toast.error("Signup failed"); + } + } catch (error: any) { + console.error(error); + toast.error(error.response.data.message); + } + actionBtnLoadingState.setFinish(); + }; + + return ( +
+
+
+
+ +
+ Shortify + {actionBtnLoadingState.isLoading && } +
+
+

Create your account

+
+
+
+ Email + +
+
+ Nickname + +
+
+ Password + +
+
+
+ +
+
+

+ {"Already has an account?"} + + Sign in + +

+
+
+
+ ); +}; + +export default SignUp; diff --git a/web/src/routers/index.tsx b/web/src/routers/index.tsx index 65b68f0..2c0df29 100644 --- a/web/src/routers/index.tsx +++ b/web/src/routers/index.tsx @@ -2,14 +2,19 @@ import { createBrowserRouter, redirect } from "react-router-dom"; import { isNullorUndefined } from "../helpers/utils"; import { userService } from "../services"; import Root from "../layouts/Root"; -import Auth from "../pages/Auth"; +import SignIn from "../pages/SignIn"; +import SignUp from "../pages/SignUp"; import Home from "../pages/Home"; import Setting from "../pages/Setting"; const router = createBrowserRouter([ { path: "/auth", - element: , + element: , + }, + { + path: "/auth/signup", + element: , }, { path: "/",