Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ft028 diseñ restablecimiento y navbar #48

Merged
merged 5 commits into from
Mar 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
"""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
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = '83fb8f773037'
revision = '2309db853ee5'
down_revision = None
branch_labels = None
depends_on = None
Expand Down
32 changes: 11 additions & 21 deletions src/front/js/component/navbar.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,27 @@
import React, { useContext, useEffect } from "react";
import logo from "../../img/Icono puppereats.png";
import { Link } from "react-router-dom";
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { CiSearch } from "react-icons/ci";
import { Context } from "../store/appContext";
import { FaUserCircle, FaShoppingCart, FaSignOutAlt } from "react-icons/fa";

export const Navbar = ({ setActiveCategory }) => { // Recibimos setActiveCategory como prop
export const Navbar = ({ setActiveCategory }) => {
const { store, actions } = useContext(Context);
const { user, cart } = store;

useEffect(() => {
console.log("Usuario en navbar:", user);
}, [user, cart]);
useEffect(() => {
console.log("Usuario en navbar:", user);
}, [user, cart]);

const totalUnidades = store.cart.reduce((total, producto) => total + (producto.cantidad || 1), 0)
const totalUnidades = store.cart.reduce((total, producto) => total + (producto.cantidad || 1), 0);

if (typeof setActiveCategory !== "function") {
console.error("⚠️ Error: setActiveCategory no es una función en Navbar.js.");
return null; // Evitamos que falle si `setActiveCategory` no es válida
return null;
}

return (
<nav className="navbar navbar-expand-lg shadow-lg" style={{
background: "linear-gradient(180deg, #FBD989 5%, #F4C4A4 40%, #EC955B 95%)",
background: "#EABDE6" ,
padding: "15px 30px",
}}>
<div className="container-fluid">
Expand All @@ -33,25 +31,18 @@ export const Navbar = ({ setActiveCategory }) => { // Recibimos setActiveCatego
</Link>

<div className="collapse navbar-collapse" id="navbarSupportedContent">
<form className="d-flex me-auto" role="search">
<input className="form-control me-2" type="search" placeholder="Buscar comida..." aria-label="Search" style={{ borderRadius: "8px", height: "30px", width: "250px", fontSize: "1.1rem" }} />
<button className="btn btn-outline-dark" type="submit" style={{ borderRadius: "8px", padding: "2px 6px" }}>
<CiSearch size={12} />
</button>
</form>

<ul className="navbar-nav mx-auto mb-2 mb-lg-0">
<li className="nav-item m-2">
<button className="nav-link fw-semibold btn btn-link text-dark" onClick={() => setActiveCategory("dogFood")}>Caninos</button>
<Link to="/" className="nav-link fw-semibold btn btn-link text-dark" onClick={() => setActiveCategory("dogFood")}>Caninos</Link>
</li>
<li className="nav-item m-2">
<button className="nav-link fw-semibold btn btn-link text-dark" onClick={() => setActiveCategory("catFood")}>Felinos</button>
<Link to="/" className="nav-link fw-semibold btn btn-link text-dark" onClick={() => setActiveCategory("catFood")}>Felinos</Link>
</li>
<li className="nav-item m-2">
<button className="nav-link fw-semibold btn btn-link text-dark" onClick={() => setActiveCategory("exoticFood")}>Exóticos</button>
<Link to="/" className="nav-link fw-semibold btn btn-link text-dark" onClick={() => setActiveCategory("exoticFood")}>Exóticos</Link>
</li>
<li className="nav-item m-2">
<button className="nav-link fw-semibold btn btn-link text-dark" onClick={() => setActiveCategory("accesories")}>Accesorios</button>
<Link to="/" className="nav-link fw-semibold btn btn-link text-dark" onClick={() => setActiveCategory("accesories")}>Accesorios</Link>
</li>
</ul>

Expand All @@ -63,7 +54,6 @@ export const Navbar = ({ setActiveCategory }) => { // Recibimos setActiveCatego
<span className="fw-semibold">Perfil</span>
</Link>
<Link to="/carrito" className="btn btn-warning d-flex align-items-center">
{/* <FaShoppingCart size={18} className="me-1" /> Cesta {cartItemCount > 0 && `(${cartItemCount})`} */}
<FaShoppingCart size={18} className="me-1" /> Cesta {totalUnidades > 0 && `(${totalUnidades})`}
</Link>
<button className="btn btn-light text-muted border-0 d-flex align-items-center" onClick={actions.logout}>
Expand Down
130 changes: 92 additions & 38 deletions src/front/js/component/recuperacionContraseña.js
Original file line number Diff line number Diff line change
@@ -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 (
<div>
<h2>Recuperar contraseña</h2>
<form onSubmit={handleSubmit}>
<input
type="email"
placeholder="Introduce tu correo electrónico"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
/>
<button type="submit">Enviar</button>
</form>
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 (
<div
className="d-flex justify-content-center align-items-center min-vh-100"
style={{
background: "linear-gradient(to bottom, #FFDCAE, #ffffff)",
backgroundSize: "cover",
padding: "2rem"
}}
>
<div
className="card shadow-lg p-5"
style={{
width: "100%",
maxWidth: "35rem",
borderRadius: "20px",
backgroundColor: "#ffffff",
border: "none",
boxShadow: "0 10px 30px rgba(0, 0, 0, 0.1)"
}}
>
<div className="card-body text-center">
<h2 className="card-title mb-4" style={{ color: "#333", fontWeight: "bold" }}>Recuperar Contraseña</h2>
<p className="text-muted mb-4" style={{ fontSize: "1.1rem" }}>
Ingresa tu correo y te enviaremos instrucciones para restablecer tu contraseña.
</p>
<form onSubmit={handleSubmit}>
<div className="mb-4">
<input
type="email"
className="form-control p-3"
style={{
borderRadius: "10px",
border: "2px solid #ddd",
transition: "border-color 0.3s ease-in-out",
}}
placeholder="Introduce tu correo electrónico"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
onFocus={(e) => e.target.style.borderColor = "#007bff"}
onBlur={(e) => e.target.style.borderColor = "#ddd"}
/>
</div>
<button
type="submit"
className="btn w-100 py-2"
style={{
backgroundColor: "#007bff",
color: "#ffffff",
fontSize: "1.1rem",
borderRadius: "10px",
transition: "0.3s ease-in-out",
}}
onMouseOver={(e) => e.target.style.backgroundColor = "#0056b3"}
onMouseOut={(e) => e.target.style.backgroundColor = "#007bff"}
>
Enviar Correo
</button>
</form>
<Link to="/" className="d-block mt-3 text-secondary" style={{ fontSize: "1rem", textDecoration: "none" }}>
<i className="bi bi-arrow-left"></i> Volver a la página principal
</Link>
</div>
);
</div>
</div>
);
};
2 changes: 1 addition & 1 deletion src/front/js/layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
<>
Expand Down
12 changes: 10 additions & 2 deletions src/front/js/pages/AlertComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,17 @@ const AlertComponent = () => {
<p className='mt-3'>Aww yeah..! Tu pedido se ha realizado correctamente. En unos minutos recibirás la confirmación en tu correo electrónico.</p>
<p className="mb-0">Si necesitas cancelar algún producto o realizar cualquier modificación, ponte en contacto con nosotros a través del formulario de contacto.</p>
<hr/>
<Link className="text-center" to="/">
<p><strong>Volver a la página principal</strong></p>
<Link
className="text-center"
to="/"
onClick={(e) => {
e.preventDefault(); // Evita que React Router haga la navegación interna
window.location.href = "/"; // Redirige y recarga correctamente
}}
>
<p><strong>Volver a la página principal</strong></p>
</Link>

</div>
)}

Expand Down
Loading