From 7ec5bb7bad6396b9ab9eb84d21d066f41794b3e3 Mon Sep 17 00:00:00 2001 From: Sergio Brenes Date: Thu, 20 Mar 2025 14:41:01 +0000 Subject: [PATCH 1/5] =?UTF-8?q?Dise=C3=B1o=20logi=20y=20recuperacion=20con?= =?UTF-8?q?trase=C3=B1a?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{83fb8f773037_.py => 2309db853ee5_.py} | 6 +- src/front/js/component/navbar.js | 8 +- .../recuperacionContrase\303\261a.js" | 130 ++++++++---- src/front/js/layout.js | 2 +- src/front/js/pages/loginSignup.js | 196 +++++++++++------- src/front/styles/home.css | 160 -------------- 6 files changed, 226 insertions(+), 276 deletions(-) rename migrations/versions/{83fb8f773037_.py => 2309db853ee5_.py} (97%) diff --git a/migrations/versions/83fb8f773037_.py b/migrations/versions/2309db853ee5_.py similarity index 97% rename from migrations/versions/83fb8f773037_.py rename to migrations/versions/2309db853ee5_.py index 1dbc687610..27d785e2e1 100644 --- a/migrations/versions/83fb8f773037_.py +++ b/migrations/versions/2309db853ee5_.py @@ -1,8 +1,8 @@ """empty message -Revision ID: 83fb8f773037 +Revision ID: 2309db853ee5 Revises: -Create Date: 2025-03-19 01:32:37.695224 +Create Date: 2025-03-20 14:23:41.224215 """ from alembic import op @@ -10,7 +10,7 @@ # revision identifiers, used by Alembic. -revision = '83fb8f773037' +revision = '2309db853ee5' down_revision = None branch_labels = None depends_on = None diff --git a/src/front/js/component/navbar.js b/src/front/js/component/navbar.js index 6673f30114..1bdf738680 100755 --- a/src/front/js/component/navbar.js +++ b/src/front/js/component/navbar.js @@ -42,16 +42,16 @@ export const Navbar = ({ setActiveCategory }) => { // Recibimos setActiveCatego diff --git "a/src/front/js/component/recuperacionContrase\303\261a.js" "b/src/front/js/component/recuperacionContrase\303\261a.js" index 75d04d9eb4..c381632c6c 100644 --- "a/src/front/js/component/recuperacionContrase\303\261a.js" +++ "b/src/front/js/component/recuperacionContrase\303\261a.js" @@ -1,46 +1,100 @@ -import React, { useState } from 'react'; -import { useNavigate } from 'react-router-dom'; // ✅ Importamos useNavigate +import React, { useState } from "react"; +import { useNavigate, Link } from "react-router-dom"; export const RecuperacionContraseña = () => { - const [email, setEmail] = useState(''); - const navigate = useNavigate(); // ✅ Inicializamos el hook de navegación + const [email, setEmail] = useState(""); + const navigate = useNavigate(); - const handleSubmit = async (e) => { - e.preventDefault(); - - try { - const response = await fetch(`${process.env.BACKEND_URL}/api/forgotpassword`, { // ✅ Asegúrate de que esta ruta es correcta - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ email }) - }); + const handleSubmit = async (e) => { + e.preventDefault(); - const data = await response.json(); - - if (response.ok) { - alert("Correo enviado correctamente. Revisa tu bandeja de entrada."); // ✅ Alert con el mensaje - navigate("/loginSignup"); // ✅ Redirigir al inicio de sesión después de aceptar el alert - } else { - alert(`Error: ${data.msg}`); - } - } catch (error) { - alert("Error de conexión con el servidor."); + try { + const response = await fetch( + `${process.env.BACKEND_URL}/api/forgotpassword`, + { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ email }), } - }; + ); - return ( -
-

Recuperar contraseña

-
- setEmail(e.target.value)} - required - /> - -
+ const data = await response.json(); + + if (response.ok) { + alert("Correo enviado correctamente. Revisa tu bandeja de entrada."); + navigate("/loginSignup"); + } else { + alert(`Error: ${data.msg}`); + } + } catch (error) { + alert("Error de conexión con el servidor."); + } + }; + + return ( +
+
+
+

Recuperar Contraseña

+

+ Ingresa tu correo y te enviaremos instrucciones para restablecer tu contraseña. +

+
+
+ setEmail(e.target.value)} + required + onFocus={(e) => e.target.style.borderColor = "#007bff"} + onBlur={(e) => e.target.style.borderColor = "#ddd"} + /> +
+ +
+ + Volver a la página principal +
- ); +
+
+ ); }; diff --git a/src/front/js/layout.js b/src/front/js/layout.js index 7029175067..01ea293517 100755 --- a/src/front/js/layout.js +++ b/src/front/js/layout.js @@ -74,7 +74,7 @@ const Layout = () => { // Nuevo componente para manejar el Navbar const PageWithNavbar = ({ activeCategory, setActiveCategory }) => { const location = useLocation(); - const hideNavbarRoutes = ["/perfilUsuario", "/loginSignup"]; // Rutas donde ocultamos el Navbar + const hideNavbarRoutes = ["/perfilUsuario","/RecuperacionContraseña",]; // Rutas donde ocultamos el Navbar return ( <> diff --git a/src/front/js/pages/loginSignup.js b/src/front/js/pages/loginSignup.js index 59ffd5bff0..12f2841b16 100644 --- a/src/front/js/pages/loginSignup.js +++ b/src/front/js/pages/loginSignup.js @@ -1,18 +1,17 @@ import React, { useState, useContext } from 'react'; import { Context } from '../store/appContext'; import { Link, useNavigate } from 'react-router-dom'; -import "../../styles/home.css"; export const LoginSignup = () => { - const { actions, store } = useContext(Context); + const { actions } = useContext(Context); const navigate = useNavigate(); const [name, setName] = useState(''); const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [isSignup, setIsSignup] = useState(false); - const [loading, setLoading] = useState(false); - const [error, setError] = useState(''); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(''); const [successMessage, setSuccessMessage] = useState(''); const handleSubmit = async (e) => { @@ -25,7 +24,7 @@ export const LoginSignup = () => { const dataUser = { name, email, password }; if (isSignup) { await actions.signup(dataUser, navigate); - setSuccessMessage('¡Registro exitoso! Redirigiendo a inicio de sesión...'); + setSuccessMessage('¡Registro exitoso! Redirigiendo...'); setTimeout(() => { setIsSignup(false); },); @@ -35,79 +34,136 @@ export const LoginSignup = () => { setName(''); setEmail(''); setPassword(''); - } catch (err) { - setError('Error al procesar la solicitud. Por favor, intenta nuevamente.'); + } catch (error) { + setError('Error al procesar la solicitud.'); } finally { setLoading(false); } }; return ( -
-
- {!isSignup && ( -
-

Iniciar sesión

- setEmail(e.target.value)} - required - /> - setPassword(e.target.value)} - required - /> - - {error &&

{error}

} -

setIsSignup(true)}>¿No tienes cuenta? Regístrate

- - {/* NUEVO: Enlace para recuperación de contraseña */} -

- ¿Olvidaste tu contraseña? Recupérala aquí -

-
- )} - {isSignup && ( -
-

Regístrate

- setName(e.target.value)} - required - /> - setEmail(e.target.value)} - required - /> - setPassword(e.target.value)} - required - /> - - {error &&

{error}

} - {successMessage &&

{successMessage}

} -

setIsSignup(false)}>¿Ya tienes cuenta? Inicia sesión

+ + {error &&

{error}

} + {successMessage &&

{successMessage}

}
- )} - -

Volver a la página principal

+ +

+ {isSignup ? ( + <> + ¿Ya tienes cuenta? setIsSignup(false)}>Inicia sesión + + ) : ( + <> + ¿No tienes cuenta? setIsSignup(true)}>Regístrate + + )} +

+ + {!isSignup && ( +

+ ¿Olvidaste tu contraseña? +

+ )} + + + Volver a la página principal + +
); diff --git a/src/front/styles/home.css b/src/front/styles/home.css index 9d39d50a24..e69de29bb2 100755 --- a/src/front/styles/home.css +++ b/src/front/styles/home.css @@ -1,160 +0,0 @@ -/* - home.css: This website contains selectors only used in home.css - - All pages share the styles on index.css but you should create - one more css for each page that will contain the selected used - on that page only (the ones not reused in other pages). -*/ - -.registration-view-container { - font-family: 'Arial', sans-serif; - background-color: #f5f7fa; - display: flex; - justify-content: center; - align-items: center; - height: 100vh; - margin: 0; - } - - .registration-view-container { - display: flex; - justify-content: center; - align-items: center; - width: 100%; - height: 100%; - background: linear-gradient(135deg, #e2efff, #ffffff); - padding: 20px; - } - - /* Form container */ - .form-container { - background-color: #ffffff; - border-radius: 12px; - box-shadow: 0px 4px 20px rgba(0, 0, 0, 0.1); - padding: 30px 40px; - width: 100%; - max-width: 400px; - transition: all 0.3s ease; - } - - /* Form title */ - form h2 { - font-size: 24px; - font-weight: bold; - text-align: center; - color: #333; - margin-bottom: 20px; - text-transform: uppercase; - letter-spacing: 1.2px; - } - - /* Input fields */ - input { - width: 100%; - padding: 12px; - margin: 10px 0; - border-radius: 8px; - border: 2px solid #d1d1d1; - background-color: #f9f9f9; - font-size: 16px; - transition: border-color 0.3s ease, background-color 0.3s ease; - } - - /* Focus effect on inputs */ - input:focus { - outline: none; - border-color: #5b8fcb; - background-color: #e8f0fe; - } - - /* Submit button */ - button { - width: 100%; - padding: 12px; - background-color: #5b8fcb; - color: white; - border: none; - border-radius: 8px; - font-size: 16px; - font-weight: bold; - cursor: pointer; - transition: background-color 0.3s ease; - } - - /* Hover effect on button */ - button:hover { - background-color: #3d6ea5; - } - - button:disabled { - background-color: #a0c6f1; - cursor: not-allowed; - } - - /* Error message styling */ - .error-message { - color: #e74c3c; - font-size: 14px; - margin-top: 10px; - text-align: center; - } - - /* Link styling for switching between login and signup */ - p { - color: #5b8fcb; - text-align: center; - cursor: pointer; - font-size: 14px; - margin-top: 10px; - transition: color 0.3s ease; - } - - /* Hover effect on links */ - p:hover { - color: #3d6ea5; - } - - /* Animations for form entry */ - .auth-form { - opacity: 0; - transform: translateY(20px); - animation: slideIn 0.5s forwards; - } - - .auth-form.login-form { - animation-delay: 0.3s; - } - - .auth-form.signup-form { - animation-delay: 0.3s; - } - - /* Slide-in animation for forms */ - @keyframes slideIn { - to { - opacity: 1; - transform: translateY(0); - } - } - - /* Animation for form container on hover */ - .form-container:hover { - box-shadow: 0px 6px 30px rgba(0, 0, 0, 0.1); - transform: translateY(-5px); - } - - /* Responsive styles */ - @media (max-width: 600px) { - .form-container { - padding: 20px; - } - - form h2 { - font-size: 20px; - } - - input, - button { - font-size: 14px; - } - } \ No newline at end of file From 24dea745318966982c8b3c1092cc7968fbf91ca5 Mon Sep 17 00:00:00 2001 From: Sergio Brenes Date: Thu, 20 Mar 2025 14:54:47 +0000 Subject: [PATCH 2/5] color navbar --- src/front/js/component/navbar.js | 2 +- "src/front/js/component/recuperacionContrase\303\261a.js" | 2 +- src/front/js/pages/loginSignup.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/front/js/component/navbar.js b/src/front/js/component/navbar.js index 1bdf738680..e0385f8f7f 100755 --- a/src/front/js/component/navbar.js +++ b/src/front/js/component/navbar.js @@ -23,7 +23,7 @@ export const Navbar = ({ setActiveCategory }) => { // Recibimos setActiveCatego return (