diff --git a/package.json b/package.json index 5ed11bf..6785f6c 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "version": "0.0.0", "type": "module", "scripts": { + "local": "vite --mode local", "dev": "vite", "build": "vite build", "lint": "eslint .", diff --git a/src/App.tsx b/src/App.tsx index 42ebdfa..f87273a 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,6 +1,3 @@ -import { useState } from 'react'; -import reactLogo from './assets/react.svg'; -import viteLogo from '/vite.svg'; import './App.css'; import SignUpPage from './ui/page/signup/SignUpPage'; import Layout from './layouts/Layout'; diff --git a/src/data/response/account/LoginResponse.ts b/src/data/response/account/LoginResponse.ts index 12f4bd8..2eacb89 100644 --- a/src/data/response/account/LoginResponse.ts +++ b/src/data/response/account/LoginResponse.ts @@ -2,4 +2,6 @@ import { BaseResponse } from "../BaseResponse"; export class LoginResponse extends BaseResponse { success!: boolean; + accessToken?: string; + refreshToken?: string; } \ No newline at end of file diff --git a/src/hooks/useModal.tsx b/src/hooks/use-modal.tsx similarity index 100% rename from src/hooks/useModal.tsx rename to src/hooks/use-modal.tsx diff --git a/src/hooks/use-toast.ts b/src/hooks/use-toast.ts new file mode 100644 index 0000000..4fec14d --- /dev/null +++ b/src/hooks/use-toast.ts @@ -0,0 +1 @@ +import { toast } from 'sonner'; \ No newline at end of file diff --git a/src/layouts/Layout.tsx b/src/layouts/Layout.tsx index 7a92732..a19551d 100644 --- a/src/layouts/Layout.tsx +++ b/src/layouts/Layout.tsx @@ -3,21 +3,40 @@ import { Outlet } from "react-router-dom"; import { SidebarProvider } from "@/components/ui/sidebar"; import Header from "@/ui/component/Header"; import { useAuthStore } from '@/store/authStore'; +import { Toaster, type ToasterProps } from "sonner"; +import { + CircleCheckIcon, + InfoIcon, + Loader2Icon, + OctagonXIcon, + TriangleAlertIcon, +} from "lucide-react"; export default function Layout() { const { authData } = useAuthStore(); - return ( - - - - { authData?.isLogedIn ? : null} - {/* */} - - - + <> + , + error: , + info: , + warning: , + loading: + }} + /> + + + + { authData?.isLogedIn ? : null} + {/* */} + + + + > ); } \ No newline at end of file diff --git a/src/main.tsx b/src/main.tsx index bef5202..287939a 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -4,7 +4,7 @@ import './index.css' import App from './App.tsx' createRoot(document.getElementById('root')!).render( - + // - , + // , ) diff --git a/.env b/src/ui/component/Toast.tsx similarity index 100% rename from .env rename to src/ui/component/Toast.tsx diff --git a/src/ui/page/login/LoginPage.tsx b/src/ui/page/login/LoginPage.tsx index 6b72a05..20511db 100644 --- a/src/ui/page/login/LoginPage.tsx +++ b/src/ui/page/login/LoginPage.tsx @@ -14,6 +14,7 @@ import { Validator } from '@/util/Validator'; import { LoginRequest } from '@/data/request/account/LoginRequest'; import { AccountNetwork } from '@/network/AccountNetwork'; import { toast } from 'sonner'; +import { LoginResponse } from '@/data/response'; export default function LoginPage() { const [isLoading, setIsLoading] = useState(false); @@ -26,6 +27,7 @@ export default function LoginPage() { password: "" } }); + const { id, password } = { id: loginForm.watch('id'), password: loginForm.watch('password') }; const moveToSignUpPage = useCallback(() => { navigate(PageRouting["SIGN_UP"].path); @@ -42,28 +44,38 @@ export default function LoginPage() { // TODO 33 로그인 기능 구현 const login = async () => { if (isLoading) return; - - const { id, password } = loginForm.getValues(); const type = Validator.isEmail(id) ? 'email' : 'accountId'; const data: LoginRequest = new LoginRequest(type, id, password); const loginPromise = accountNetwork.login(data); - toast.promise( - loginPromise, + toast.promise<{ message?: string }>( + () => new Promise(async (resolve, reject) => { + try { + loginPromise.then((res) => { + if (res.data.success) { + resolve({message: ''}) + } else { + reject(res.data.message) + } + }) + } catch (err) { + reject ("서버 에러 발생"); + } + }), { loading: "로그인 중입니다.", - success: (res) => res.data.success ? "로그인이 완료되었습니다." : res.data.message, - error: "로그인에 실패하였습니다." + success: "로그인이 완료되었습니다.", + error: (err) => `${err}` } ); - loginPromise.then((res) => { - if (res.data.success) { - moveToMainPage(); - } - }); + // loginPromise.then((res) => { + // if (res.data.success) { + // moveToMainPage(); + // } + // }); } const TextSeparator = ({ text }: { text: string }) => { @@ -89,7 +101,7 @@ export default function LoginPage() { control={loginForm.control} render={({ field, fieldState }) => ( - 이메일 + 아이디 또는 이메일 비밀번호를 잊으셨습니까? @@ -133,17 +146,16 @@ export default function LoginPage() { > + type="button" + disabled={id.trim().length < 1 || password.trim().length < 1} + onClick={login} + > 로그인 회원가입 diff --git a/src/util/Validator.ts b/src/util/Validator.ts index e0518a6..f23e45b 100644 --- a/src/util/Validator.ts +++ b/src/util/Validator.ts @@ -1,5 +1,7 @@ export class Validator { - static isEmail = (value: string): boolean => { - return /^[^\s@]+@[^\s@]+\.[*\s@]+$/.test(value); - } + static isEmail = (value: any) => { + if (typeof value !== 'string') return false; + const email = value.trim(); + return /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/.test(email); +}; } \ No newline at end of file