From 3b9a6cc8b0af3d7c7c9de936eb5b63e40d78d8cf Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Sat, 15 Mar 2025 01:37:07 +0000 Subject: [PATCH] Implement login/signup pages This commit implements the login and signup pages for the application. --- src/App.tsx | 6 ++ src/pages/ForgotPassword.tsx | 109 ++++++++++++++++++++++++ src/pages/Login.tsx | 122 +++++++++++++++++++++++++++ src/pages/Register.tsx | 157 +++++++++++++++++++++++++++++++++++ 4 files changed, 394 insertions(+) create mode 100644 src/pages/ForgotPassword.tsx create mode 100644 src/pages/Login.tsx create mode 100644 src/pages/Register.tsx diff --git a/src/App.tsx b/src/App.tsx index f86d6ab..1076141 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -9,6 +9,9 @@ import Transactions from "./pages/Transactions"; import Analytics from "./pages/Analytics"; import Settings from "./pages/Settings"; import NotFound from "./pages/NotFound"; +import Login from "./pages/Login"; +import Register from "./pages/Register"; +import ForgotPassword from "./pages/ForgotPassword"; const queryClient = new QueryClient(); @@ -23,6 +26,9 @@ const App = () => ( } /> } /> } /> + } /> + } /> + } /> } /> diff --git a/src/pages/ForgotPassword.tsx b/src/pages/ForgotPassword.tsx new file mode 100644 index 0000000..6efb43c --- /dev/null +++ b/src/pages/ForgotPassword.tsx @@ -0,0 +1,109 @@ + +import React, { useState } from "react"; +import { Link } from "react-router-dom"; +import { Label } from "@/components/ui/label"; +import { Input } from "@/components/ui/input"; +import { Button } from "@/components/ui/button"; +import { ArrowLeft, Mail, Check } from "lucide-react"; +import { useToast } from "@/components/ui/use-toast"; + +const ForgotPassword = () => { + const [email, setEmail] = useState(""); + const [isLoading, setIsLoading] = useState(false); + const [isSubmitted, setIsSubmitted] = useState(false); + const { toast } = useToast(); + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + + if (!email) { + toast({ + title: "입력 오류", + description: "이메일을 입력해주세요.", + variant: "destructive", + }); + return; + } + + setIsLoading(true); + + // 실제 비밀번호 찾기 로직은 추후 구현 + // 임시로 2초 후 성공으로 처리 + setTimeout(() => { + setIsLoading(false); + setIsSubmitted(true); + toast({ + title: "이메일 전송 완료", + description: "비밀번호 재설정 링크가 이메일로 전송되었습니다.", + }); + }, 2000); + }; + + return ( +
+
+
+

비밀번호 찾기

+

계정에 등록된 이메일을 입력해주세요

+
+ +
+ {!isSubmitted ? ( +
+
+
+ +
+ + setEmail(e.target.value)} + className="pl-10 neuro-pressed" + /> +
+
+ + +
+
+ ) : ( +
+
+ +
+
+

이메일이 전송되었습니다

+

+ {email}로 비밀번호 재설정 링크를 보냈습니다. 이메일을 확인해주세요. +

+
+ +
+ )} +
+ +
+ + 로그인으로 돌아가기 + +
+
+
+ ); +}; + +export default ForgotPassword; diff --git a/src/pages/Login.tsx b/src/pages/Login.tsx new file mode 100644 index 0000000..87b16f4 --- /dev/null +++ b/src/pages/Login.tsx @@ -0,0 +1,122 @@ + +import React, { useState } from "react"; +import { Link, useNavigate } from "react-router-dom"; +import { Label } from "@/components/ui/label"; +import { Input } from "@/components/ui/input"; +import { Button } from "@/components/ui/button"; +import { ArrowRight, Mail, KeyRound, Eye, EyeOff } from "lucide-react"; +import { useToast } from "@/components/ui/use-toast"; + +const Login = () => { + const [email, setEmail] = useState(""); + const [password, setPassword] = useState(""); + const [showPassword, setShowPassword] = useState(false); + const [isLoading, setIsLoading] = useState(false); + const { toast } = useToast(); + const navigate = useNavigate(); + + const handleLogin = async (e: React.FormEvent) => { + e.preventDefault(); + + if (!email || !password) { + toast({ + title: "입력 오류", + description: "이메일과 비밀번호를 모두 입력해주세요.", + variant: "destructive", + }); + return; + } + + setIsLoading(true); + + // 실제 로그인 로직은 추후 구현 + // 임시로 2초 후 로그인 성공으로 처리 + setTimeout(() => { + setIsLoading(false); + toast({ + title: "로그인 성공", + description: "환영합니다!", + }); + navigate("/"); + }, 2000); + }; + + return ( +
+
+
+

뉴모파이낸스

+

계정에 로그인하여 재정 관리를 시작하세요

+
+ +
+
+
+
+ +
+ + setEmail(e.target.value)} + className="pl-10 neuro-pressed" + /> +
+
+ +
+ +
+ + setPassword(e.target.value)} + className="pl-10 neuro-pressed" + /> + +
+
+ +
+ + 비밀번호를 잊으셨나요? + +
+ + +
+
+
+ +
+

+ 계정이 없으신가요?{" "} + + 회원가입 + +

+
+
+
+ ); +}; + +export default Login; diff --git a/src/pages/Register.tsx b/src/pages/Register.tsx new file mode 100644 index 0000000..24533ca --- /dev/null +++ b/src/pages/Register.tsx @@ -0,0 +1,157 @@ + +import React, { useState } from "react"; +import { Link, useNavigate } from "react-router-dom"; +import { Label } from "@/components/ui/label"; +import { Input } from "@/components/ui/input"; +import { Button } from "@/components/ui/button"; +import { ArrowRight, Mail, KeyRound, User, Eye, EyeOff } from "lucide-react"; +import { useToast } from "@/components/ui/use-toast"; + +const Register = () => { + const [username, setUsername] = useState(""); + const [email, setEmail] = useState(""); + const [password, setPassword] = useState(""); + const [confirmPassword, setConfirmPassword] = useState(""); + const [showPassword, setShowPassword] = useState(false); + const [isLoading, setIsLoading] = useState(false); + const { toast } = useToast(); + const navigate = useNavigate(); + + const handleRegister = async (e: React.FormEvent) => { + e.preventDefault(); + + if (!username || !email || !password || !confirmPassword) { + toast({ + title: "입력 오류", + description: "모든 필드를 입력해주세요.", + variant: "destructive", + }); + return; + } + + if (password !== confirmPassword) { + toast({ + title: "비밀번호 불일치", + description: "비밀번호와 비밀번호 확인이 일치하지 않습니다.", + variant: "destructive", + }); + return; + } + + setIsLoading(true); + + // 실제 회원가입 로직은 추후 구현 + // 임시로 2초 후 회원가입 성공으로 처리 + setTimeout(() => { + setIsLoading(false); + toast({ + title: "회원가입 성공", + description: "로그인 페이지로 이동합니다.", + }); + navigate("/login"); + }, 2000); + }; + + return ( +
+
+
+

뉴모파이낸스

+

새 계정을 만들고 재정 관리를 시작하세요

+
+ +
+
+
+
+ +
+ + setUsername(e.target.value)} + className="pl-10 neuro-pressed" + /> +
+
+ +
+ +
+ + setEmail(e.target.value)} + className="pl-10 neuro-pressed" + /> +
+
+ +
+ +
+ + setPassword(e.target.value)} + className="pl-10 neuro-pressed" + /> + +
+
+ +
+ +
+ + setConfirmPassword(e.target.value)} + className="pl-10 neuro-pressed" + /> +
+
+ + +
+
+
+ +
+

+ 이미 계정이 있으신가요?{" "} + + 로그인 + +

+
+
+
+ ); +}; + +export default Register;