From 10fe57893775437dce81b3737b31cac435d9f1d0 Mon Sep 17 00:00:00 2001 From: Silas Date: Mon, 16 Feb 2026 21:18:40 -0300 Subject: [PATCH 1/4] feature: login page initial design --- src/App.tsx | 2 + src/components/login/index.tsx | 80 ++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 src/components/login/index.tsx diff --git a/src/App.tsx b/src/App.tsx index 9a8022a..458c7f0 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -5,6 +5,7 @@ import 'react-toastify/dist/ReactToastify.css'; import LandingPage from "./components/landing"; import ConfigurationPage from "./components/configuration"; import DocumentationPage from "./components/documentation"; +import LoginPage from "./components/login"; const App: React.FC = () => { return ( @@ -12,6 +13,7 @@ const App: React.FC = () => {
} /> + } /> } /> } /> diff --git a/src/components/login/index.tsx b/src/components/login/index.tsx new file mode 100644 index 0000000..edb1e66 --- /dev/null +++ b/src/components/login/index.tsx @@ -0,0 +1,80 @@ +import React, { useState } from "react"; +import { LogIn, Eye, EyeOff } from "lucide-react"; + +const LoginPage: React.FC = () => { + const [email, setEmail] = useState(""); + const [password, setPassword] = useState(""); + const [showPassword, setShowPassword] = useState(false); + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + // Logica de autenticacao vira aqui + console.log("Login attempt:", { email, password }); + }; + + return ( +
+
+
+
+ +
+

+ Acessar Prisma +

+
+ +
+
+
+ + setEmail(e.target.value)} + /> +
+
+ + {/* Esta div 'relative' é o segredo para o ícone ficar dentro do input */} +
+ setPassword(e.target.value)} + /> + +
+
+
+ + +
+
+
+ ); +}; + +export default LoginPage; + From 85fa90dcb46616b18ad2f65f385ae44a844ed554 Mon Sep 17 00:00:00 2001 From: Silas Date: Mon, 16 Feb 2026 22:04:01 -0300 Subject: [PATCH 2/4] feature: signup page --- src/components/login/index.tsx | 116 +++++++++++++++++++++++++++------ 1 file changed, 96 insertions(+), 20 deletions(-) diff --git a/src/components/login/index.tsx b/src/components/login/index.tsx index edb1e66..af63686 100644 --- a/src/components/login/index.tsx +++ b/src/components/login/index.tsx @@ -1,50 +1,87 @@ import React, { useState } from "react"; -import { LogIn, Eye, EyeOff } from "lucide-react"; +import { LogIn, UserPlus, Eye, EyeOff } from "lucide-react"; const LoginPage: React.FC = () => { + const [isLogin, setIsLogin] = useState(true); + // Estados dos campos + const [firstName, setFirstName] = useState(""); const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); + const [confirmPassword, setConfirmPassword] = useState(""); + // Visibilidade independente const [showPassword, setShowPassword] = useState(false); + const [showConfirmPassword, setShowConfirmPassword] = useState(false); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); - // Logica de autenticacao vira aqui - console.log("Login attempt:", { email, password }); + if (isLogin) { + console.log("Login attempt:", { email, password }); + } else { + console.log("Register attempt:", { firstName, email, password, confirmPassword }); + } + }; + + const togglePanel = () => { + setIsLogin(!isLogin); + setFirstName(""); + setEmail(""); + setPassword(""); + setConfirmPassword(""); + setShowPassword(false); + setShowConfirmPassword(false); }; return (
-
+
-
- +
+ {isLogin ? : }

- Acessar Prisma + {isLogin ? "Acessar Prisma" : "Criar sua conta"}

-
+
+ + {/* Primeiro Nome */} + {!isLogin && ( +
+ + setFirstName(e.target.value)} + /> +
+ )} + + {/* Email */}
setEmail(e.target.value)} />
+ + {/* Senha */}
- {/* Esta div 'relative' é o segredo para o ícone ficar dentro do input */}
setPassword(e.target.value)} @@ -54,27 +91,66 @@ const LoginPage: React.FC = () => { onClick={() => setShowPassword(!showPassword)} className="absolute inset-y-0 right-0 flex items-center pr-3 text-gray-400 hover:text-indigo-400 transition-colors" > - {showPassword ? ( - - ) : ( - - )} + {showPassword ? : }
+ {isLogin && ( +
+ +
+ )}
+ + {/* Confirmar Senha */} + {!isLogin && ( +
+ +
+ setConfirmPassword(e.target.value)} + /> + +
+
+ )}
+ +
+

+ {isLogin ? "Não tem uma conta?" : "Já possui uma conta?"}{' '} + +

+
); }; -export default LoginPage; - +export default LoginPage; \ No newline at end of file From 8185b7fc264ba80182d1aa60a8f558fa94cd2df2 Mon Sep 17 00:00:00 2001 From: Silas Date: Mon, 16 Feb 2026 22:20:18 -0300 Subject: [PATCH 3/4] fix: signup password validation --- src/components/login/index.tsx | 39 ++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/src/components/login/index.tsx b/src/components/login/index.tsx index af63686..a2515d6 100644 --- a/src/components/login/index.tsx +++ b/src/components/login/index.tsx @@ -3,20 +3,23 @@ import { LogIn, UserPlus, Eye, EyeOff } from "lucide-react"; const LoginPage: React.FC = () => { const [isLogin, setIsLogin] = useState(true); - // Estados dos campos const [firstName, setFirstName] = useState(""); const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const [confirmPassword, setConfirmPassword] = useState(""); - // Visibilidade independente const [showPassword, setShowPassword] = useState(false); const [showConfirmPassword, setShowConfirmPassword] = useState(false); + const passwordsMatch = isLogin || !confirmPassword || password === confirmPassword; const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); if (isLogin) { console.log("Login attempt:", { email, password }); } else { + if (password !== confirmPassword) { + return; + } + console.log("Register attempt:", { firstName, email, password, confirmPassword }); } }; @@ -45,8 +48,6 @@ const LoginPage: React.FC = () => {
- - {/* Primeiro Nome */} {!isLogin && (
@@ -61,7 +62,6 @@ const LoginPage: React.FC = () => {
)} - {/* Email */}
{ />
- {/* Senha */}
@@ -94,16 +93,8 @@ const LoginPage: React.FC = () => { {showPassword ? : }
- {isLogin && ( -
- -
- )}
- {/* Confirmar Senha */} {!isLogin && (
@@ -111,7 +102,11 @@ const LoginPage: React.FC = () => { setConfirmPassword(e.target.value)} @@ -124,17 +119,25 @@ const LoginPage: React.FC = () => { {showConfirmPassword ? : }
+ {!passwordsMatch && ( +

+ As senhas não coincidem. +

+ )}
)}
- -

{isLogin ? "Não tem uma conta?" : "Já possui uma conta?"}{' '} From a12ffe529a526211b7e6762985534485c1826db4 Mon Sep 17 00:00:00 2001 From: Silas Date: Mon, 16 Feb 2026 22:35:08 -0300 Subject: [PATCH 4/4] feature: add password reset page --- src/App.tsx | 2 + src/components/login/index.tsx | 10 ++- src/components/password-reset/index.tsx | 90 +++++++++++++++++++++++++ 3 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 src/components/password-reset/index.tsx diff --git a/src/App.tsx b/src/App.tsx index 458c7f0..955a8fa 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -6,6 +6,7 @@ import LandingPage from "./components/landing"; import ConfigurationPage from "./components/configuration"; import DocumentationPage from "./components/documentation"; import LoginPage from "./components/login"; +import PasswordResetPage from "./components/password-reset"; const App: React.FC = () => { return ( @@ -14,6 +15,7 @@ const App: React.FC = () => { } /> } /> + } /> } /> } /> diff --git a/src/components/login/index.tsx b/src/components/login/index.tsx index a2515d6..abd7417 100644 --- a/src/components/login/index.tsx +++ b/src/components/login/index.tsx @@ -1,4 +1,5 @@ import React, { useState } from "react"; +import { Link } from "react-router-dom"; import { LogIn, UserPlus, Eye, EyeOff } from "lucide-react"; const LoginPage: React.FC = () => { @@ -75,7 +76,14 @@ const LoginPage: React.FC = () => {

- +
+ + {isLogin && ( + + Esqueceu a senha? + + )} +
{ + const [email, setEmail] = useState(""); + const [isSubmitted, setIsSubmitted] = useState(false); + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + // logica de envio de email de recuperacao + console.log("Reset password attempt:", { email }); + setIsSubmitted(true); + }; + + return ( +
+
+ + + Voltar para login + + +
+
+ +
+

+ Recuperar Senha +

+

+ {isSubmitted + ? "Verifique seu email" + : "Digite seu email para receber um link de recuperação"} +

+
+ + {!isSubmitted ? ( + +
+ + setEmail(e.target.value)} + /> +
+ + + + ) : ( +
+
+ +

+ Enviamos um link de recuperação para {email} +

+

+ Verifique sua caixa de entrada e clique no link para redefinir sua senha. +

+
+ + +
+ )} +
+
+ ); +}; + +export default PasswordResetPage;