diff --git a/src/app/NavBar.tsx b/src/app/NavBar.tsx index cd10b6c..2351efe 100644 --- a/src/app/NavBar.tsx +++ b/src/app/NavBar.tsx @@ -118,7 +118,7 @@ export default function NavBar() { 내 정보 - + 로그아웃 @@ -152,14 +152,23 @@ export default function NavBar() { setIsUserMenuOpen(false)} > 내 정보 수정 diff --git a/src/app/find-id/page.tsx b/src/app/find-id/page.tsx index cce58cb..69247fb 100644 --- a/src/app/find-id/page.tsx +++ b/src/app/find-id/page.tsx @@ -30,7 +30,7 @@ export default function FindIdPage() { async function handleSubmit(e: React.FormEvent) { e.preventDefault(); if (!validateAll()) return; - + try { const response = await fetch('https://hrdi.coconutmeet.net/auth/find-id', { method: 'POST', @@ -87,7 +87,7 @@ export default function FindIdPage() { />
- +
아이디 찾기 @@ -111,7 +111,7 @@ export default function FindIdPage() { onFocus={() => setFocused((p) => ({ ...p, name: true }))} onBlur={() => setFocused((p) => ({ ...p, name: false }))} placeholder="이름을 입력해 주세요." - className="h-[40px] px-[12px] py-[7px] w-full rounded-[8px] border border-neutral-40 focus:outline-none focus:border-neutral-700 text-[18px] text-neutral-700 placeholder:text-input-placeholder-text pr-[40px]" + className="h-[40px] px-[12px] py-[7px] w-full rounded-[8px] mt-3 border border-neutral-40 focus:outline-none focus:border-neutral-700 text-[18px] text-neutral-700 placeholder:text-input-placeholder-text pr-[40px]" /> {name.trim().length > 0 && focused.name && ( diff --git a/src/app/login/page.tsx b/src/app/login/page.tsx index 4063e11..5101ccc 100644 --- a/src/app/login/page.tsx +++ b/src/app/login/page.tsx @@ -1,6 +1,6 @@ "use client"; -import { useState } from "react"; +import { useState, useEffect } from "react"; import { useRouter } from "next/navigation"; import Link from "next/link"; import MainLogo from "@/app/svgs/mainlogosvg" @@ -22,9 +22,43 @@ export default function LoginPage() { const [idError, setIdError] = useState(""); const [passwordError, setPasswordError] = useState(""); + // 컴포넌트 마운트 시 저장된 아이디 불러오기 + useEffect(() => { + const savedId = localStorage.getItem('savedUserId'); + if (savedId) { + setUserId(savedId); + setRememberId(true); + } + }, []); + + // 아이디 기억하기 상태나 아이디가 변경될 때마다 저장 처리 + useEffect(() => { + if (rememberId && userId.trim()) { + localStorage.setItem('savedUserId', userId); + } else if (!rememberId) { + localStorage.removeItem('savedUserId'); + } + }, [rememberId, userId]); + async function handleSubmit(e: React.FormEvent) { e.preventDefault(); - if (userId.trim().length === 0 || password.trim().length === 0) { + + // 에러 초기화 + setIdError(""); + setPasswordError(""); + + // 입력 검증 + let hasError = false; + if (userId.trim().length === 0) { + setIdError("아이디를 입력해 주세요."); + hasError = true; + } + if (password.trim().length === 0) { + setPasswordError("비밀번호를 입력해 주세요."); + hasError = true; + } + + if (hasError) { return; } @@ -74,6 +108,7 @@ export default function LoginPage() { // 토큰이 없어도 로그인은 성공했으므로 진행 } + // 리다이렉트 경로 확인 const searchParams = new URLSearchParams(window.location.search); const redirectPath = searchParams.get('redirect') || '/'; @@ -112,7 +147,7 @@ export default function LoginPage() {
{/* 폼 */} -
+
{/* 아이디 */}
@@ -123,17 +158,14 @@ export default function LoginPage() { id="userId" name="userId" value={userId} - onChange={(e) => setUserId(e.target.value)} + onChange={(e) => { + setUserId(e.target.value); + if (idError) setIdError(""); + }} onFocus={() => setIsUserIdFocused(true)} onBlur={() => setIsUserIdFocused(false)} - placeholder="아이디 (이메일)" - className=" - h-[40px] px-[12px] py-[7px] w-full rounded-[8px] border border-neutral-40 - focus:outline-none focus:ring-0 focus:ring-offset-0 focus:shadow-none - focus:appearance-none focus:border-neutral-700 - text-[18px] text-neutral-700 font-normal leading-[150%] placeholder:text-input-placeholder-text - pr-[40px] - " + placeholder="아이디(이메일)" + className={`h-[56px] px-[12px] py-[7px] w-full rounded-[8px] border focus:outline-none focus:ring-0 focus:ring-offset-0 focus:shadow-none focus:appearance-none text-[18px] text-neutral-700 font-normal leading-[150%] placeholder:text-input-placeholder-text pr-[40px] ${idError ? 'border-error' : 'border-neutral-40 focus:border-neutral-700'}`} /> {userId.trim().length > 0 && isUserIdFocused && (
+ {idError &&

{idError}

} {/* 비밀번호 */}
+ {passwordError &&

{passwordError}

}
{/* 체크박스들 */} @@ -222,7 +253,7 @@ export default function LoginPage() { {/* 로그인 버튼 */} diff --git a/src/app/register/RegisterForm.tsx b/src/app/register/RegisterForm.tsx index 8d737ac..fd76923 100644 --- a/src/app/register/RegisterForm.tsx +++ b/src/app/register/RegisterForm.tsx @@ -290,7 +290,7 @@ export default function RegisterForm({ onOpenDone, onOpenCodeError }: RegisterFo onFocus={() => setFocused((p) => ({ ...p, name: true }))} onBlur={() => setFocused((p) => ({ ...p, name: false }))} placeholder="이름을 입력해 주세요." - className="h-[40px] px-[12px] py-[7px] w-full rounded-[8px] border border-neutral-40 focus:outline-none focus:border-neutral-700 text-[18px] text-neutral-700 placeholder:text-input-placeholder-text pr-[40px]" + className={`h-[40px] px-[12px] py-[7px] w-full rounded-[8px] border focus:outline-none text-[18px] text-neutral-700 placeholder:text-input-placeholder-text pr-[40px] ${errors.name ? 'border-error' : 'border-neutral-40 focus:border-neutral-700'}`} /> {name.trim().length > 0 && focused.name && (
- {errors.name &&

{errors.name}

} + {errors.name &&

{errors.name}

}
{/* 휴대폰 번호 */} @@ -320,7 +320,7 @@ export default function RegisterForm({ onOpenDone, onOpenCodeError }: RegisterFo onChange={(e) => setPhone(e.target.value.replace(/[^0-9]/g, ""))} onFocus={() => setFocused((p) => ({ ...p, phone: true }))} onBlur={() => setFocused((p) => ({ ...p, phone: false }))} - className="h-[40px] px-[12px] py-[7px] w-full rounded-[8px] border border-neutral-40 focus:outline-none focus:border-neutral-700 text-[18px] text-neutral-700 placeholder:text-input-placeholder-text pr-[40px]" + className={`h-[40px] px-[12px] py-[7px] w-full rounded-[8px] border focus:outline-none text-[18px] text-neutral-700 placeholder:text-input-placeholder-text pr-[40px] ${errors.phone ? 'border-error' : 'border-neutral-40 focus:border-neutral-700'}`} /> {phone.trim().length > 0 && focused.phone && (