From 9147df3dadd86838e4a368d26f910dc6f09c1665 Mon Sep 17 00:00:00 2001 From: yondo123 <46988995+yondo123@users.noreply.github.com> Date: Thu, 17 Aug 2023 23:27:06 +0900 Subject: [PATCH 1/5] =?UTF-8?q?=F0=9F=8F=97=EF=B8=8F=20=20structure:=20reo?= =?UTF-8?q?rganize=20directories=20by=20display,=20action=20structure=20#6?= =?UTF-8?q?0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/auth/components/SigninModal.tsx | 2 +- src/auth/components/SignupModal.tsx | 4 ++-- .../components/{ => action}/EmailPasswordForm.tsx | 10 +++++----- src/auth/components/{ => action}/UserProfileForm.tsx | 12 ++++++------ 4 files changed, 14 insertions(+), 14 deletions(-) rename src/auth/components/{ => action}/EmailPasswordForm.tsx (87%) rename src/auth/components/{ => action}/UserProfileForm.tsx (88%) diff --git a/src/auth/components/SigninModal.tsx b/src/auth/components/SigninModal.tsx index 5b3dd32..9ea9341 100644 --- a/src/auth/components/SigninModal.tsx +++ b/src/auth/components/SigninModal.tsx @@ -2,7 +2,7 @@ import { GitHubIcon, GoogleIcon, Loading } from '@shared/components/Icons'; import { Modal, Stack, Button } from '@jdesignlab/react'; import { useMachine } from '@xstate/react'; import { Mail } from '@jdesignlab/react-icons'; -import { EmailPasswordForm } from './EmailPasswordForm'; +import { EmailPasswordForm } from './action/EmailPasswordForm'; import { useSigninWithProvider } from '../hooks/useSigninWithProvider'; import { signMachine } from '../machines/signMachine'; diff --git a/src/auth/components/SignupModal.tsx b/src/auth/components/SignupModal.tsx index 7f4657d..a85cf14 100644 --- a/src/auth/components/SignupModal.tsx +++ b/src/auth/components/SignupModal.tsx @@ -1,7 +1,7 @@ import { Modal, Button } from '@jdesignlab/react'; import { useMachine } from '@xstate/react'; -import { UserProfileForm } from './UserProfileForm'; -import { EmailPasswordForm } from './EmailPasswordForm'; +import { UserProfileForm } from './action/UserProfileForm'; +import { EmailPasswordForm } from './action/EmailPasswordForm'; import { signMachine } from '../machines/signMachine'; import { useSetUserAuthData } from '../hooks/useSetUserAuthData'; diff --git a/src/auth/components/EmailPasswordForm.tsx b/src/auth/components/action/EmailPasswordForm.tsx similarity index 87% rename from src/auth/components/EmailPasswordForm.tsx rename to src/auth/components/action/EmailPasswordForm.tsx index ba230a8..b82fcb9 100644 --- a/src/auth/components/EmailPasswordForm.tsx +++ b/src/auth/components/action/EmailPasswordForm.tsx @@ -1,12 +1,12 @@ import { Text, TextInput, Button, Modal } from '@jdesignlab/react'; import { useForm } from 'react-hook-form'; import { useActor } from '@xstate/react'; -import { Flex } from '../styles/Profile'; -import { useAccountEmailWithPassword } from '../hooks/useAccountEmailWithPassword'; -import { useCreateUserMutation } from '../hooks/useCreateUserMutation'; +import { Flex } from '../../styles/Profile'; +import { useAccountEmailWithPassword } from '../../hooks/useAccountEmailWithPassword'; +import { useCreateUserMutation } from '../../hooks/useCreateUserMutation'; import type { InterpreterFrom } from 'xstate'; -import type { SignMachineType } from '../machines/signMachine'; -import type { EmailPasswordField } from '../types'; +import type { SignMachineType } from '../../machines/signMachine'; +import type { EmailPasswordField } from '../../types'; interface Props { signMachine: InterpreterFrom; diff --git a/src/auth/components/UserProfileForm.tsx b/src/auth/components/action/UserProfileForm.tsx similarity index 88% rename from src/auth/components/UserProfileForm.tsx rename to src/auth/components/action/UserProfileForm.tsx index cccbc89..56504b6 100644 --- a/src/auth/components/UserProfileForm.tsx +++ b/src/auth/components/action/UserProfileForm.tsx @@ -4,13 +4,13 @@ import { Loading } from '@shared/components/Icons'; import { useForm } from 'react-hook-form'; import { useActor } from '@xstate/react'; import { TextInput, Button, Modal } from '@jdesignlab/react'; -import { useProfileUpdate } from '../hooks/useProfileUpdate'; -import { useSetUserAuthData } from '../hooks/useSetUserAuthData'; -import { parseUserInfo } from '../parseUserInfo'; -import { Flex } from '../styles/Profile'; +import { useProfileUpdate } from '../../hooks/useProfileUpdate'; +import { useSetUserAuthData } from '../../hooks/useSetUserAuthData'; +import { parseUserInfo } from '../../parseUserInfo'; +import { Flex } from '../../styles/Profile'; import type { InterpreterFrom } from 'xstate'; -import type { SignMachineType } from '../machines/signMachine'; -import type { UserProfile } from '../types'; +import type { SignMachineType } from '../../machines/signMachine'; +import type { UserProfile } from '../../types'; interface Props { signupMachineRef: InterpreterFrom; From a1ffb7c01438702255b84cbbc9a6bd28eefa17b0 Mon Sep 17 00:00:00 2001 From: yondo123 <46988995+yondo123@users.noreply.github.com> Date: Thu, 17 Aug 2023 23:58:11 +0900 Subject: [PATCH 2/5] =?UTF-8?q?=E2=9C=A8=20feat:=20separate=20login/signup?= =?UTF-8?q?=20pages=20#60?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/action/AuthLoginButtons.tsx | 54 +++++++++++++++ src/auth/styles/signPageStyle.ts | 22 +++++++ src/layout/components/Header.tsx | 19 ++++-- src/pages/login.tsx | 41 ++++++++++++ src/pages/signup.tsx | 66 +++++++++++++++++++ 5 files changed, 197 insertions(+), 5 deletions(-) create mode 100644 src/auth/components/action/AuthLoginButtons.tsx create mode 100644 src/auth/styles/signPageStyle.ts create mode 100644 src/pages/login.tsx create mode 100644 src/pages/signup.tsx diff --git a/src/auth/components/action/AuthLoginButtons.tsx b/src/auth/components/action/AuthLoginButtons.tsx new file mode 100644 index 0000000..5bd3a6f --- /dev/null +++ b/src/auth/components/action/AuthLoginButtons.tsx @@ -0,0 +1,54 @@ +import { GitHubIcon, GoogleIcon, Loading } from '@shared/components/Icons'; +import { useActor } from '@xstate/react'; +import { Button, Flex } from '@jdesignlab/react'; +import { Mail } from '@jdesignlab/react-icons'; +import { useSigninWithProvider } from '../../hooks/useSigninWithProvider'; +import type { SignMachineType } from '../../machines/signMachine'; +import type { InterpreterFrom } from 'xstate'; + +interface Props { + signMachine: InterpreterFrom; +} + +export const AuthLoginButtons = (props: Props) => { + const { signMachine } = props; + const [, refSend] = useActor(signMachine); + const { isLoading: loadingWithGitHubLogin, mutate: signinGithub } = useSigninWithProvider('GITHUB', refSend); + const { isLoading: loadingWithGoogleLogin, mutate: signinGoogle } = useSigninWithProvider('GOOGLE', refSend); + return ( + + + + + + ); +}; diff --git a/src/auth/styles/signPageStyle.ts b/src/auth/styles/signPageStyle.ts new file mode 100644 index 0000000..a011190 --- /dev/null +++ b/src/auth/styles/signPageStyle.ts @@ -0,0 +1,22 @@ +import { css } from '@emotion/react'; + +export const signFormContainer = css({ + height: 'fit-content', + position: 'absolute', + top: '50%', + left: '50%', + transform: 'translate(-50%, -50%)', + padding: '24px 16px' +}); + +export const title = css({ + textAlign: 'center' +}); + +export const signButtonWrapper = css({ + display: 'flex', + marginTop: '32px', + flexDirection: 'column', + alignItems: 'center', + justifyContent: 'center' +}); diff --git a/src/layout/components/Header.tsx b/src/layout/components/Header.tsx index 1e86b01..cb2f5c5 100644 --- a/src/layout/components/Header.tsx +++ b/src/layout/components/Header.tsx @@ -1,6 +1,4 @@ import { useSignout } from '@auth/hooks/useSignout'; -import { SigninModal } from '@auth/components/SigninModal'; -import { SignupModal } from '@auth/components/SignupModal'; import { ErrorModal } from '@shared/components/ErrorModal'; import { Layout } from '@shared/components/dataDisplay/FlexLayout'; import { headerWrapper, headerContents } from '@layout/styles/headerStyle'; @@ -8,7 +6,7 @@ import { useGetUserInfoById } from '@challenge/hooks/useGetUserInfoById'; import { Avatar } from '@shared/components/dataDisplay/Avatar'; import { Loading } from '@shared/components/Icons/Loading'; import { CompositionBoundaryReactQuery } from '@shared/boundaries'; -import { Dropdown, Text } from '@jdesignlab/react'; +import { Button, Dropdown, Text } from '@jdesignlab/react'; import { useRouter } from 'next/router'; import Image from 'next/image'; import { useSession } from 'next-auth/react'; @@ -19,6 +17,15 @@ export const Header = () => { const moveToMain = () => { router.push('/'); }; + + const moveToSigninPage = () => { + router.push('/login'); + }; + + const moveToSignupPage = () => { + router.push('/signup'); + }; + const { data } = useSession(); const { userInfo } = useGetUserInfoById(data?.user?.uid); const { mutate: signout } = useSignout(); @@ -86,8 +93,10 @@ export const Header = () => { ) : ( - - + + )} diff --git a/src/pages/login.tsx b/src/pages/login.tsx new file mode 100644 index 0000000..523b795 --- /dev/null +++ b/src/pages/login.tsx @@ -0,0 +1,41 @@ +import * as Style from '@auth/styles/signPageStyle'; +import { CompositionBoundaryReactQuery } from '@shared/boundaries'; +import { ErrorModal } from '@shared/components/ErrorModal'; +import { signMachine } from '@auth/machines/signMachine'; +import { AuthLoginButtons } from '@auth/components/action/AuthLoginButtons'; +import { Loading } from '@shared/components/Icons'; +import { EmailPasswordForm } from '@auth/components/action/EmailPasswordForm'; +import { Button, Text } from '@jdesignlab/react'; +import { useMachine } from '@xstate/react'; +import { useRouter } from 'next/router'; + +const Login = () => { + const [state, , service] = useMachine(signMachine); + const { value: signState } = state; + const router = useRouter(); + + const moveToLoginPage = () => { + router.push('/signup'); + }; + + return ( + } error={(props) => }> +
+
+ + 로그인 + + +
+
+ {signState === 'selection' && } + {signState === 'email' && } +
+
+
+ ); +}; + +export default Login; diff --git a/src/pages/signup.tsx b/src/pages/signup.tsx new file mode 100644 index 0000000..a33a4cb --- /dev/null +++ b/src/pages/signup.tsx @@ -0,0 +1,66 @@ +import * as Style from '@auth/styles/signPageStyle'; +import { Loading } from '@shared/components/Icons'; +import { CompositionBoundaryReactQuery } from '@shared/boundaries'; +import { ErrorModal } from '@shared/components/ErrorModal'; +import { EmailPasswordForm } from '@auth/components/action/EmailPasswordForm'; +import { signMachine } from '@auth/machines/signMachine'; +import { UserProfileForm } from '@auth/components/action/UserProfileForm'; +import { useSetUserAuthData } from '@auth/hooks/useSetUserAuthData'; +import { Button, Text } from '@jdesignlab/react'; +import { useMachine } from '@xstate/react'; +import { useRouter } from 'next/router'; + +const SignUpPage = () => { + const [state, send, service] = useMachine(signMachine); + const { value: signState, context } = state; + const userInfo = context.user; + const { updateUserData } = useSetUserAuthData(); + const router = useRouter(); + + const moveToPage = (url: string, callback?: () => void) => { + if (callback) { + callback(); + } + router.push(url); + }; + + const onUpdateUserData = () => { + if (userInfo) { + updateUserData(userInfo); + } + send('CLEAR'); + }; + + if (state.matches('done')) { + moveToPage('/'); + } + + return ( + } error={(props) => }> +
+
+ + 회원가입 + + +
+
+ {signState === 'registry' ? ( + + ) : ( + + )} +
+
+
+ ); +}; + +export default SignUpPage; From 31f489f40574e3e450cea271ca14e352e270c63c Mon Sep 17 00:00:00 2001 From: yondo123 <46988995+yondo123@users.noreply.github.com> Date: Fri, 18 Aug 2023 00:02:22 +0900 Subject: [PATCH 3/5] =?UTF-8?q?=F0=9F=94=A7=20modify:=20add=20error=20mess?= =?UTF-8?q?age=20for=20'auth/wrong-password'=20Firebase=20error?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/shared/constants/firebaseError.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/shared/constants/firebaseError.ts b/src/shared/constants/firebaseError.ts index 235e596..92835fa 100644 --- a/src/shared/constants/firebaseError.ts +++ b/src/shared/constants/firebaseError.ts @@ -15,6 +15,7 @@ export type FirebaseErrorCode = | 'auth/invalid-display-name' | 'auth/invalid-dynamic-link-domain' | 'auth/invalid-email' + | 'auth/wrong-password' | 'auth/invalid-email-verified' | 'auth/invalid-hash-algorithm' | 'auth/invalid-hash-block-size' @@ -119,5 +120,6 @@ export const CustomFirebaseError: Record = { 'auth/uid-already-exists': '제공된 uid를 기존 사용자가 이미 사용하고 있습니다. 각 사용자마다 uid가 고유해야 합니다.', 'auth/unauthorized-continue-uri': '연결 URL의 도메인이 허용 목록에 포함되어 있지 않습니다. Firebase Console에서 도메인을 허용해야 합니다.', - 'auth/user-not-found': '제공된 식별자에 해당하는 기존 사용자 레코드가 없습니다.' + 'auth/user-not-found': '제공된 식별자에 해당하는 기존 사용자 레코드가 없습니다.', + 'auth/wrong-password': '비밀번호가 맞지 않습니다.' }; From 7f90df65303e2950904b6bbc04454bb67ebed8aa Mon Sep 17 00:00:00 2001 From: yondo123 <46988995+yondo123@users.noreply.github.com> Date: Fri, 18 Aug 2023 00:25:27 +0900 Subject: [PATCH 4/5] =?UTF-8?q?=F0=9F=90=9B=20fix:=20fix=20incorrectly=20a?= =?UTF-8?q?ssigned=20css=20object?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/login.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/login.tsx b/src/pages/login.tsx index 523b795..7775771 100644 --- a/src/pages/login.tsx +++ b/src/pages/login.tsx @@ -20,7 +20,7 @@ const Login = () => { return ( } error={(props) => }> -
+
로그인 From 2b21c15bcadeaf98abedbbe9110738735ef4e51f Mon Sep 17 00:00:00 2001 From: yondo123 <46988995+yondo123@users.noreply.github.com> Date: Fri, 18 Aug 2023 00:48:45 +0900 Subject: [PATCH 5/5] =?UTF-8?q?=E2=9E=96=20remove:=20remove=20unnecessary?= =?UTF-8?q?=20modal=20dependency?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/action/EmailPasswordForm.tsx | 34 +++++++++---------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/src/auth/components/action/EmailPasswordForm.tsx b/src/auth/components/action/EmailPasswordForm.tsx index b82fcb9..8e6a37c 100644 --- a/src/auth/components/action/EmailPasswordForm.tsx +++ b/src/auth/components/action/EmailPasswordForm.tsx @@ -1,4 +1,4 @@ -import { Text, TextInput, Button, Modal } from '@jdesignlab/react'; +import { Text, TextInput, Button } from '@jdesignlab/react'; import { useForm } from 'react-hook-form'; import { useActor } from '@xstate/react'; import { Flex } from '../../styles/Profile'; @@ -61,24 +61,22 @@ export const EmailPasswordForm = (props: Props) => { Password {errors.password && {errors.password.message as string}} - - - {!signup && ( - - )} - - - + )} + + ); };