-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
로그인 UI 변경
- Loading branch information
Showing
27 changed files
with
767 additions
and
269 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
34 changes: 34 additions & 0 deletions
34
client/src/app/login/components/GithubLoginButton/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
'use client'; | ||
|
||
import { Icon } from '@iconify/react'; | ||
|
||
//hooks | ||
import useModal from '@/hooks/modal/useModal'; | ||
|
||
//constant | ||
import { errorMessage, ModalType } from '@/constants/constant'; | ||
|
||
export default function GithubLoginButton() { | ||
const { openModal } = useModal(); | ||
|
||
return ( | ||
<div className="grid py-4"> | ||
<button | ||
onClick={() => | ||
openModal({ | ||
type: ModalType.ERROR, | ||
message: errorMessage.notComplete, | ||
}) | ||
} | ||
className="relative p-3 border border-gray-900 hover:bg-blue-gray-scale-100 active:bg-blue-gary-scale-100 disabled:bg-gray-scale-50 disabled:border-gray-800 disabled:text-blue-gray-600" | ||
> | ||
<Icon | ||
className="absolute top-2 left-2" | ||
icon="mdi:github" | ||
fontSize={34} | ||
/> | ||
<span>깃허브로 로그인</span> | ||
</button> | ||
</div> | ||
); | ||
} |
34 changes: 34 additions & 0 deletions
34
client/src/app/login/components/GoogleLoginButton/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
'use client'; | ||
|
||
import { Icon } from '@iconify/react'; | ||
|
||
//hooks | ||
import useModal from '@/hooks/modal/useModal'; | ||
|
||
//constant | ||
import { errorMessage, ModalType } from '@/constants/constant'; | ||
|
||
export default function GoogleLoginButton() { | ||
const { openModal } = useModal(); | ||
|
||
return ( | ||
<div className="grid py-4"> | ||
<button | ||
onClick={() => | ||
openModal({ | ||
type: ModalType.ERROR, | ||
message: errorMessage.notComplete, | ||
}) | ||
} | ||
className="relative p-3 border border-gray-900 hover:bg-blue-gray-scale-100 active:bg-blue-gary-scale-100 disabled:bg-gray-scale-50 disabled:border-gray-800 disabled:text-blue-gray-600" | ||
> | ||
<Icon | ||
className="absolute top-2 left-2" | ||
icon="devicon:google" | ||
fontSize={34} | ||
/> | ||
<span>구글로 로그인</span> | ||
</button> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,188 @@ | ||
'use client'; | ||
|
||
import { useState, useCallback } from 'react'; | ||
import { useRouter } from 'next/navigation'; | ||
|
||
//redux | ||
import { useDispatch, useSelector } from 'react-redux'; | ||
import { logIn } from '@/lib/redux/features/auth/authSlice'; | ||
|
||
//components | ||
import { Tooltip } from '@/components'; | ||
|
||
//hooks | ||
import useModal from '@/hooks/modal/useModal'; | ||
|
||
//icons | ||
import { EyeOnIcon, EyeOffIcon } from '@/assets/Icon'; | ||
|
||
//formik | ||
import { Formik, Form, Field, ErrorMessage } from 'formik'; | ||
import * as Yup from 'yup'; | ||
|
||
//services | ||
import { userManager } from '@/service/user'; | ||
|
||
//constant | ||
import { | ||
initialLoginValue, | ||
errorMessage, | ||
errorCodeToMessage, | ||
ModalType, | ||
} from '@/constants/constant'; | ||
|
||
//types | ||
import { IReduxState } from '@/types/redux/IReduxState'; | ||
|
||
const ValidationSchema = Yup.object().shape({ | ||
userId: Yup.string().required(errorMessage.blankID), | ||
password: Yup.string().required(errorMessage.blankPassword), | ||
}); | ||
|
||
interface ILogin { | ||
userId: string; | ||
password: string; | ||
} | ||
|
||
export default function LoginForm() { | ||
const [viewPassword, setViewPassword] = useState(false); | ||
|
||
const dispatch = useDispatch(); | ||
|
||
const router = useRouter(); | ||
|
||
const modalState = useSelector((state: IReduxState) => state.modal); | ||
const { openModal } = useModal(); | ||
|
||
const handleSubmit = useCallback( | ||
async (sendData: ILogin, setSubmitting: (value: boolean) => void) => { | ||
if (modalState.type === ModalType.CLOSE) { | ||
setSubmitting(true); | ||
try { | ||
const userData = await userManager.loginUser({ data: sendData }); | ||
dispatch(logIn(userData)); | ||
router.replace(window.sessionStorage.getItem('previousURL') || '/'); | ||
} catch (error) { | ||
if (error instanceof Error) { | ||
type Code = 'USER_NOT_EXIST' | 'INVALID_PASSWORD'; | ||
openModal({ | ||
type: ModalType.ERROR, | ||
message: | ||
errorCodeToMessage[error.message as Code] || errorMessage.error, | ||
}); | ||
} else { | ||
openModal({ | ||
type: ModalType.ERROR, | ||
message: errorMessage.error, | ||
}); | ||
} | ||
} finally { | ||
setSubmitting(false); | ||
} | ||
} | ||
}, | ||
[modalState] | ||
); | ||
return ( | ||
<Formik | ||
initialValues={initialLoginValue} | ||
validationSchema={ValidationSchema} | ||
onSubmit={(data, { setSubmitting }) => handleSubmit(data, setSubmitting)} | ||
> | ||
{({ errors, touched, isSubmitting }) => ( | ||
<Form> | ||
<div className="flex flex-col gap-5"> | ||
<div className="relative flex flex-col gap-3.5"> | ||
<label className="text-body3" htmlFor="user-id-input"> | ||
아이디 | ||
</label> | ||
<Field | ||
type="text" | ||
name="userId" | ||
id="user-id-input" | ||
placeholder="아이디를 입력하세요." | ||
className={`${ | ||
touched.userId && errors.userId && 'border-red-scale-600' | ||
} border border-blue-gray-scale-50 py-[7px] px-4 text-body3 text-gray-scale-600 focus:outline-none`} | ||
/> | ||
<ErrorMessage | ||
name="userId" | ||
component="span" | ||
className="absolute -bottom-4 left-2 text-caption1 text-red-scale-600" | ||
/> | ||
</div> | ||
<div className="relative flex flex-col gap-3.5"> | ||
<label className="text-body3" htmlFor="password-input"> | ||
비밀번호 | ||
</label> | ||
<div className="relative flex"> | ||
<Field | ||
type={viewPassword ? 'text' : 'password'} | ||
name="password" | ||
id="password-input" | ||
placeholder="비밀번호를 입력하세요." | ||
autoComplete="on" | ||
className={`${ | ||
touched.password && | ||
errors.password && | ||
'border-red-scale-600' | ||
} flex-grow border border-blue-gray-scale-50 py-[7px] px-4 text-body3 text-gray-scale-600 focus:outline-none`} | ||
/> | ||
<div | ||
className="absolute right-2 top-2 hover:cursor-pointer" | ||
onClick={() => setViewPassword((prev) => !prev)} | ||
> | ||
{viewPassword ? <EyeOnIcon /> : <EyeOffIcon />} | ||
</div> | ||
</div> | ||
<ErrorMessage | ||
name="password" | ||
component="span" | ||
className="absolute -bottom-4 left-2 text-caption1 text-red-scale-600" | ||
/> | ||
</div> | ||
</div> | ||
<div className="flex justify-between my-6"> | ||
<Tooltip tooltipText="현재 로그인 유지만 지원합니다"> | ||
<div className="flex items-center gap-2"> | ||
<input | ||
type="checkbox" | ||
id="keep-logged-check" | ||
className="border appearance-none size-[18px] border-gray-scale-500 checked:bg-black checked:bg-[url('/images/check.png')] checked:bg-no-repeat checked:bg-center hover:cursor-not-allowed" | ||
checked={true} | ||
disabled={true} | ||
/> | ||
<label | ||
className="text-body3 text-gray-scale-600 hover:cursor-not-allowed" | ||
htmlFor="keep-logged-check" | ||
> | ||
로그인 상태유지 | ||
</label> | ||
</div> | ||
</Tooltip> | ||
<span | ||
className="underline text-body3 text-blue-gray-scale-500 underline-offset-3 hover:cursor-pointer" | ||
onClick={() => | ||
openModal({ | ||
type: ModalType.ERROR, | ||
message: errorMessage.notComplete, | ||
}) | ||
} | ||
> | ||
비밀번호 찾기 | ||
</span> | ||
</div> | ||
<div className="grid pt-2 pb-6 text-center"> | ||
<button | ||
className="p-3 text-black bg-yellow-scale-400 hover:bg-yellow-scale-500 active:bg-yellow-scale-500 disabled:bg-yellow-scale-100 disabled:text-gray-scale-700" | ||
type="submit" | ||
disabled={isSubmitting} | ||
> | ||
<span className="font-bold text-body2">로그인</span> | ||
</button> | ||
</div> | ||
</Form> | ||
)} | ||
</Formik> | ||
); | ||
} |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.