-
Notifications
You must be signed in to change notification settings - Fork 1
[FEAT] auth UI refactor #52
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 22 commits
be4b793
5bebccc
b565650
90c2206
ef40352
a1c7051
0b459da
7c743e7
0f3e7b6
55d439f
33a53a2
91f5177
e9dd6e8
2b77d3b
28cbcc1
80c48cb
559b33f
0b30bfd
e462a70
88820b1
3cb7b88
0ffa09d
692f855
b34d32e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,6 +11,7 @@ import Input from "@/app/components/auth/Input"; | |
|
|
||
| export default function LoginPage() { | ||
| const [loginError, setLoginError] = useState<string | null>(null); | ||
| const [showPassword, setShowPassword] = useState(false); | ||
|
|
||
| const { | ||
| register, | ||
|
|
@@ -25,7 +26,7 @@ export default function LoginPage() { | |
| // ๊ฐ์์ ๋ก๊ทธ์ธ ์คํจ ์๋๋ฆฌ์ค | ||
| await new Promise((resolve) => setTimeout(resolve, 1000)); | ||
| console.log(data); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ๋์ค์ ๋ฐฐํฌํ๊ธฐ ์ ์๋ console.log ์ง์์ฃผ์ ๋ ๋ ๊ฑฐ ๊ฐ์์!
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ์ ๊ทธ๋ฆฌ๊ณ ์ฌ์ฉ์ํํ ๋ณด์ฌ์ฃผ๊ณ ์ถ์ ์๋ฌ๋ฉ์์ง๋ toast ๊ณต์ฉ ์ปดํฌ๋ํธ ํ์ฉํด๋ ์ข์ ๊ฑฐ ๊ฐ์์! |
||
| setLoginError("์ด๋ฉ์ผ ๋๋ ๋น๋ฐ๋ฒํธ๊ฐ ์ฌ๋ฐ๋ฅด์ง ์์ต๋๋ค."); | ||
| setLoginError("์ด๋ฉ์ผ ๋๋ ๋น๋ฐ๋ฒํธ๊ฐ \n ์ฌ๋ฐ๋ฅด์ง ์์ต๋๋ค."); | ||
| }; | ||
|
|
||
| return ( | ||
|
|
@@ -54,9 +55,23 @@ export default function LoginPage() { | |
| <Input | ||
| {...register("password")} | ||
| label="๋น๋ฐ๋ฒํธ" | ||
| type="password" | ||
| type={showPassword ? "text" : "password"} | ||
| placeholder="๋น๋ฐ๋ฒํธ๋ฅผ ์ ๋ ฅํด์ฃผ์ธ์" | ||
| error={errors.password?.message} | ||
| rightAddon={ | ||
| <button | ||
| type="button" | ||
| onClick={() => setShowPassword(!showPassword)} | ||
| className="p-2" | ||
| > | ||
| <Image | ||
| src={showPassword ? "/๋น๋ฐ๋ฒํธ๋ณด๊ธฐ.svg" : "/mdi-light_eye.svg"} | ||
| alt="toggle password visibility" | ||
| width={24} | ||
| height={24} | ||
| /> | ||
| </button> | ||
| } | ||
| /> | ||
|
|
||
| <div className="mt-4"> | ||
|
|
@@ -109,7 +124,7 @@ export default function LoginPage() { | |
| </Button> | ||
|
|
||
| {loginError && ( | ||
| <div className="w-full h-[70px] flex items-center justify-center text-center text-white bg-[rgba(130,130,130,0.5)] rounded-md mt-4"> | ||
| <div className="w-full h-[70px] flex items-center justify-center text-sm text-center text-white bg-[rgba(130,130,130,0.5)] rounded-md mt-4 whitespace-pre-line"> | ||
| {loginError} | ||
| </div> | ||
| )} | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,134 @@ | ||
| "use client"; | ||
|
|
||
| import { useState } from "react"; | ||
| import { useRouter } from "next/navigation"; | ||
| import Image from "next/image"; | ||
| import { useForm } from "react-hook-form"; | ||
| import { zodResolver } from "@hookform/resolvers/zod"; | ||
| import { | ||
| resetPasswordSchema, | ||
| ResetPasswordFormValues, | ||
| } from "@/lib/schemas/auth.schema"; | ||
| import Button from "@/app/components/auth/Button"; | ||
| import Input from "@/app/components/auth/Input"; | ||
| import AlertModal from "@/app/components/auth/AlertModal"; | ||
|
|
||
| export default function ResetPasswordPage() { | ||
| const [showPassword, setShowPassword] = useState(false); | ||
| const [showPasswordConfirm, setShowPasswordConfirm] = useState(false); | ||
| const [isModalOpen, setIsModalOpen] = useState(false); | ||
| const router = useRouter(); | ||
|
|
||
| const { | ||
| register, | ||
| handleSubmit, | ||
| formState: { errors, isSubmitting }, | ||
| } = useForm<ResetPasswordFormValues>({ | ||
| resolver: zodResolver(resetPasswordSchema), | ||
| }); | ||
|
|
||
| const onSubmit = async (data: ResetPasswordFormValues) => { | ||
| console.log(data); | ||
| await new Promise((resolve) => setTimeout(resolve, 1000)); | ||
| setIsModalOpen(true); | ||
| }; | ||
|
|
||
| const handleModalConfirm = () => { | ||
| setIsModalOpen(false); | ||
| router.push("/auth/login"); | ||
| }; | ||
|
|
||
| return ( | ||
| <> | ||
| <div className="flex flex-col items-center w-full gap-8"> | ||
| <div className="flex flex-col gap-3 text-center"> | ||
| <h1 className="text-xl font-medium text-[#393939]"> | ||
| ๋น๋ฐ๋ฒํธ ์ฌ์ค์ | ||
| </h1> | ||
| <p className="text-sm font-normal text-[#828282]"> | ||
| ์ฌ์ฉํ์ค ์๋ก์ด ๋น๋ฐ๋ฒํธ๋ฅผ ์ค์ ํด ์ฃผ์ธ์ | ||
| </p> | ||
| </div> | ||
|
|
||
| <form | ||
| onSubmit={handleSubmit(onSubmit)} | ||
| className="flex flex-col w-full gap-2" | ||
| > | ||
| <Input | ||
| {...register("password")} | ||
| label="์ ๋น๋ฐ๋ฒํธ" | ||
| type={showPassword ? "text" : "password"} | ||
| placeholder="โโโโโโ" | ||
| error={errors.password?.message} | ||
| rightAddon={ | ||
| <button | ||
| type="button" | ||
| onClick={() => setShowPassword(!showPassword)} | ||
| className="p-2" | ||
| > | ||
| <Image | ||
| src={ | ||
| showPassword ? "/๋น๋ฐ๋ฒํธ๋ณด๊ธฐ.svg" : "/mdi-light_eye.svg" | ||
| } | ||
| alt="toggle password visibility" | ||
| width={24} | ||
| height={24} | ||
| /> | ||
| </button> | ||
| } | ||
| /> | ||
| <p className="text-xs text-[#828282] mt-1 -translate-y-2"> | ||
| * ๋์๋ฌธ์, ์ซ์ ๋ฐ ํน์๋ฌธ์ ํฌํจ 8์ ์ด์ | ||
| </p> | ||
|
|
||
| <div className="mt-2"> | ||
| <Input | ||
| {...register("passwordConfirm")} | ||
| label="์ ๋น๋ฐ๋ฒํธ ์ฌํ์ธ" | ||
| type={showPasswordConfirm ? "text" : "password"} | ||
| placeholder="์ ๋น๋ฐ๋ฒํธ๋ฅผ ๋ค์ ์ ๋ ฅํด์ฃผ์ธ์" | ||
| error={errors.passwordConfirm?.message} | ||
| rightAddon={ | ||
| <button | ||
| type="button" | ||
| onClick={() => setShowPasswordConfirm(!showPasswordConfirm)} | ||
| className="p-2" | ||
| > | ||
| <Image | ||
| src={ | ||
| showPasswordConfirm | ||
| ? "/๋น๋ฐ๋ฒํธ๋ณด๊ธฐ.svg" | ||
| : "/mdi-light_eye.svg" | ||
| } | ||
| alt="toggle password visibility" | ||
| width={24} | ||
| height={24} | ||
| /> | ||
| </button> | ||
| } | ||
| /> | ||
| </div> | ||
|
|
||
| <div className="mt-8"> | ||
| <Button | ||
| type="submit" | ||
| variant="red" | ||
| size="large" | ||
| disabled={isSubmitting} | ||
| className="w-full" | ||
| > | ||
| {isSubmitting ? "์ค์ ์ค..." : "๋น๋ฐ๋ฒํธ ์ค์ ํ๊ธฐ"} | ||
| </Button> | ||
| </div> | ||
| </form> | ||
| </div> | ||
| {isModalOpen && ( | ||
| <AlertModal | ||
| title="๋น๋ฐ๋ฒํธ๋ฅผ ์ฌ์ค์ ํ์ด์" | ||
| message="์๋ก์ด ๋น๋ฐ๋ฒํธ๋ก ๋ก๊ทธ์ธํ์ธ์" | ||
| onConfirm={handleModalConfirm} | ||
| /> | ||
| )} | ||
| </> | ||
| ); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
text-[13px] ์ด ๋ถ๋ถ๋ง rem๋จ์๋ก ๋ณ๊ฒฝํด์ฃผ์๋ฉด ์ข์ ๊ฒ ๊ฐ์์!