Skip to content

Commit 9259f15

Browse files
committed
Develop actualizado
1 parent a75b0c0 commit 9259f15

File tree

7 files changed

+375
-18
lines changed

7 files changed

+375
-18
lines changed

src/api/models.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
db = SQLAlchemy()
1111

1212
class User(db.Model):
13+
1314
id = db.Column(db.Integer, primary_key=True)
1415
name= db.Column(db.String(80), nullable=False)
1516
email = db.Column(db.String(120), unique=True, nullable=False)

src/api/routes.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -113,16 +113,13 @@ def get_all_cat_food():
113113
if not food_cat:
114114
return jsonify({"error": "No cat food found"}), 404
115115

116-
117-
# #obtener todos los alimentos según tipo de animal
118-
@api.route('/foods/cat', methods=['GET'])
119-
def get_all_cat_food():
120-
food_cat = db.session.query(Food).filter(Food.animal_type.ilike("%gato%")).all()
121116
print("Datos obtenidos:", food_cat)
122117
if not food_cat:
123118
return jsonify({"error": "No cat food found"}), 404
124119

125120
return jsonify([food.serialize() for food in food_cat]), 200
121+
122+
126123

127124
@api.route('/foods/dog', methods=['GET'])
128125
def get_all_dog_food():

src/front/js/component/navbar.js

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,21 @@
1-
import React from "react";
1+
import React, {useContext, useEffect} from "react";
22
import { Link } from "react-router-dom";
33
import { CiSearch } from "react-icons/ci";
4+
import { Context } from "../store/appContext";
45

56

67

78
export const Navbar = () => {
9+
const { store, actions } = useContext(Context);
10+
const { user } = store; // Obtenemos el usuario del store
11+
12+
useEffect(() => {
13+
console.log("Usuario en navbar:", user);
14+
}, [user]);
815
return (
916
<nav className="navbar navbar-expand-lg bg-light">
1017
<div className="container-fluid">
11-
<a className="navbar-brand" href="#">Pupper Eats</a>
18+
<Link to="/" className="navbar-brand" href="#">Pupper Eats</Link>
1219
<button className="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
1320
<span className="navbar-toggler-icon"></span>
1421
</button>
@@ -30,11 +37,19 @@ export const Navbar = () => {
3037
<a className="nav-link" href="#">Exóticos</a>
3138
</li>
3239
</ul>
33-
<ul className="navbar-nav mb-2 mb-lg-0">
34-
<li className="nav-item">
35-
<button type="button" className="btn btn-primary" href="#">Registro/Inicio"</button>
36-
{/* <!--Pendiente linkear al formulario de registro cuando esté terminado--> */}
37-
</li>
40+
<ul className="navbar-nav">
41+
{user ? (
42+
// Si el usuario está autenticado, mostramos Perfil y Cesta
43+
<>
44+
<Link to="/perfil" className="btn btn-primary me-2">Perfil</Link>
45+
<Link to="/cesta" className="btn btn-outline-primary me-2">Cesta</Link>
46+
<button className="btn btn-danger" onClick={actions.logout}>Cerrar sesión</button>
47+
</>
48+
) : (
49+
// Si no hay usuario, mostramos los botones de Registro/Login
50+
<Link to="/loginSignup" className="btn btn-primary">Registro / Inicio</Link>
51+
52+
)}
3853
</ul>
3954
</div>
4055
</div>

src/front/js/layout.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ import ScrollToTop from "./component/scrollToTop";
44
import { BackendURL } from "./component/backendURL";
55

66
import { Home } from "./pages/home";
7-
87
import { Demo } from "./pages/demo";
98
import { Single } from "./pages/single";
109
import injectContext from "./store/appContext";
1110

1211
import { Navbar } from "./component/navbar";
1312
import { Footer } from "./component/footer";
13+
import { LoginSignup } from "./pages/loginSignup";
1414

1515

1616
//create your first component
@@ -28,7 +28,7 @@ const Layout = () => {
2828
<Navbar />
2929
<Routes>
3030
<Route element={<Home />} path="/" />
31-
31+
<Route element={<LoginSignup/>} path="/loginSignup" />
3232

3333
<Route element={<Demo />} path="/demo" />
3434
<Route element={<Single />} path="/single/:theid" />

src/front/js/pages/loginSignup.js

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import React, { useState, useContext} from 'react';
2+
import { Context } from '../store/appContext';
3+
import { Link, useNavigate } from 'react-router-dom';
4+
import "../../styles/home.css";
5+
6+
export const LoginSignup = () => {
7+
8+
const { actions } = useContext(Context);
9+
const navigate = useNavigate();
10+
11+
const [username, setUsername] = useState('');
12+
const [email, setEmail] = useState('');
13+
const [password, setPassword] = useState('');
14+
const [isSignup, setIsSignup] = useState(false);
15+
const [loading, setLoading] = useState(false);
16+
const [error, setError] = useState('');
17+
18+
const handleSubmit = async (e) => {
19+
e.preventDefault();
20+
setLoading(true);
21+
setError('');
22+
23+
try {
24+
const dataUser = { username, email, password };
25+
if (isSignup) {
26+
await actions.signup(dataUser, navigate);
27+
} else {
28+
await actions.login(email, password, navigate);
29+
}
30+
setUsername('');
31+
setEmail('');
32+
setPassword('');
33+
} catch (err) {
34+
setError('Error al procesar la solicitud. Por favor, intenta nuevamente.');
35+
} finally {
36+
setLoading(false);
37+
}
38+
39+
};
40+
return (
41+
<div className="registration-view-container">
42+
<div className="form-container">
43+
{!isSignup && (
44+
<form className="auth-form login-form" onSubmit={handleSubmit}>
45+
<h2>Iniciar sesión</h2>
46+
<input
47+
type="email"
48+
placeholder="Correo electrónico"
49+
value={email}
50+
onChange={(e) => setEmail(e.target.value)}
51+
required
52+
/>
53+
<input
54+
type="password"
55+
placeholder="Contraseña"
56+
value={password}
57+
onChange={(e) => setPassword(e.target.value)}
58+
required
59+
/>
60+
<button type="submit" disabled={loading}>
61+
{loading ? 'Cargando...' : 'Iniciar sesión'}
62+
</button>
63+
{error && <p className="error-message">{error}</p>}
64+
<p onClick={() => setIsSignup(true)}>¿No tienes cuenta? Regístrate</p>
65+
</form>
66+
)}
67+
{isSignup && (
68+
<form className="auth-form signup-form" onSubmit={handleSubmit}>
69+
<h2>Regístrate</h2>
70+
<input
71+
type="username"
72+
placeholder="Nombre de usuario"
73+
value={username}
74+
onChange={(e) => setUsername(e.target.value)}
75+
required
76+
/>
77+
<input
78+
type="email"
79+
placeholder="Correo electrónico"
80+
value={email}
81+
onChange={(e) => setEmail(e.target.value)}
82+
required
83+
/>
84+
<input
85+
type="password"
86+
placeholder="Contraseña"
87+
value={password}
88+
onChange={(e) => setPassword(e.target.value)}
89+
required
90+
/>
91+
<button type="submit" disabled={loading}>
92+
{loading ? 'Cargando...' : 'Registrar'}
93+
</button>
94+
{error && <p className="error-message">{error}</p>}
95+
<p onClick={() => setIsSignup(false)}>¿Ya tienes cuenta? Inicia sesión</p>
96+
</form>
97+
)}
98+
</div>
99+
</div>
100+
);
101+
};

src/front/js/store/flux.js

Lines changed: 95 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
const getState = ({ getStore, getActions, setStore }) => {
22
return {
33
store: {
4+
user: null,
5+
token: null,
46
message: null,
57
demo: [
68
{
@@ -24,6 +26,95 @@ const getState = ({ getStore, getActions, setStore }) => {
2426
getActions().changeColor(0, "green");
2527
},
2628

29+
login: async (email, password, navigate) => {
30+
try {
31+
const resp = await fetch(`${process.env.BACKEND_URL}api/login/user`, {
32+
method: "POST",
33+
headers: {
34+
"Content-Type": "application/json"
35+
},
36+
body: JSON.stringify({ email, password })
37+
});
38+
39+
if (!resp.ok) {
40+
throw new Error("Error al iniciar sesión");
41+
}
42+
43+
const data = await resp.json();
44+
console.log("Inicio de sesión exitoso:", data);
45+
46+
const token = data.token;
47+
if (!token) {
48+
throw new Error("No se recibió el token");
49+
}
50+
51+
localStorage.setItem("token", token);
52+
setStore({ token });
53+
54+
const actions = getActions();
55+
actions.getUser();
56+
navigate("/");
57+
} catch (error) {
58+
console.log("Error al iniciar sesión", error);
59+
alert("Error al iniciar sesión");
60+
}
61+
},
62+
signup: async (dataUser, navigate) => {
63+
try {
64+
const resp = await fetch(`${process.env.BACKEND_URL}api/signup`, {
65+
method: "POST",
66+
headers: {
67+
"Content-Type": "application/json"
68+
},
69+
body: JSON.stringify(dataUser)
70+
});
71+
72+
if (!resp.ok) {
73+
throw new Error("Error en el registro");
74+
}
75+
76+
const data = await resp.json();
77+
console.log("Usuario registrado exitosamente", data);
78+
79+
const token = data.token;
80+
if (!token) {
81+
throw new Error("No se recibió el token");
82+
}
83+
84+
localStorage.setItem("token", token);
85+
setStore({ token });
86+
87+
const actions = getActions();
88+
actions.getUser();
89+
navigate("/");
90+
} catch (error) {
91+
}
92+
},
93+
getUser: async () => {
94+
try {
95+
const token = localStorage.getItem("token");
96+
if (!token) throw new Error("No token found");
97+
98+
const resp = await fetch(`${process.env.BACKEND_URL}api/user`, {
99+
headers: {
100+
"Authorization": `Bearer ${token}`
101+
}
102+
});
103+
104+
if (!resp.ok) throw new Error("Error al obtener el usuario");
105+
106+
const data = await resp.json();
107+
setStore({ user: data });
108+
} catch (error) {
109+
console.log("Error al obtener usuario", error);
110+
}
111+
},
112+
logout: () => {
113+
localStorage.removeItem('token');
114+
setStore({token: null, user: null})
115+
116+
},
117+
27118
getDogFood: async () => {
28119
const myHeaders = new Headers();
29120
myHeaders.append("Cookie", ".Tunnels.Relay.WebForwarding.Cookies=CfDJ8Cs4yarcs6pKkdu0hlKHsZs0q_CxPIxRcsYOazLvQz4rP7s5FWFmvGJndFqy0N7fvoY5B6Jou5i4ZPgwsQZsEYGDV4DoaNhJP3xwIvv1aGmoRIVdScF1G2c_hWBWqeCTHFNCvGD1Dy0sm3kBmaNdXiMsSO0myHKUFvlWHCed2AdtyCiC6CHBqk9DHs32cYjJV4GQr4cxW2IXl6QDukWwCPSYuzTnP699Rz_4pCbB8OPOQNBDyDtdks_LUoMZR2Qt6IWKmUnLGt-n3JLFjeQMZiSeKEXKNTcJknrz4p25p9-5rh3BY2FBX_kg6MtH3cLbqOyS6yqrG4cjJPpyZbVfN3iEYSR6lzEGiGZDFPvokcj_PM8fq32HR1_olrhti8nYtDctNR_8YRewW5quhBNW6mtF_-SqGTbCQVH1CiLUF2UKK_H_nGmwvWAce2n4Cdw1BLUCZhlCr3GAKWJWHqLI1K5n9OekmI4zs0TI_60R6urTRxIQx2IgkRPYizg-AUdyr6bORhYr7s3c6oFBrdA4yBShqyJFOo4fuMkQuHflmg717cZeB1MDnWgSm9Xnl4qmOlcta0fCSq15GNUPvXhAwvclIoK9NTrmSSd1wvRhoqz7ypodxTSOafQx0ybhJZwTxDeS_gv-4KjbyFngwj7Bj1TluB2qE5Hijbi4uhZb2KILE9AGYHKWSW-IWoSmEXW71c7HhH8mBEbBxidpsSi_Rip3CdXL2oUO-8TGtLx2HgJtExj_7AyTD1trSanlKgDurPSEfDuXuwtqxawfWf0a1sbp9BGk0pRLOA-tVKrxmMiFAPiNCVC1W2EXb95TKydzKIwtbcC70YyDJ4dFwnHrQmgPYxzIz7PYzICzKqZ-VDpO4lf7C3jf4OBJ9ZMV4JRvPiR2kUwMNX_c5CuMLaKrZNzqCFwZBUa4N4AUyTT83mtzFQGAZjMXDeZNok7mjTYBp121qquiSKX8ft05b1MTsVtRfg3ETiFdOHmYQ2-1EcSwBY-VhjWIlkQiFr1yBWXk-g");
@@ -35,7 +126,7 @@ const getState = ({ getStore, getActions, setStore }) => {
35126
};
36127

37128
try {
38-
const response = await fetch("https://silver-meme-jj4x947jg76ghqjg9-3001.app.github.dev/api/foods/dog", requestOptions);
129+
const response = await fetch(process.env.BACKEND_URL +"/api/foods/dog", requestOptions);
39130

40131
if (!response.ok) {
41132
throw new Error('Network response was not ok');
@@ -65,7 +156,7 @@ const getState = ({ getStore, getActions, setStore }) => {
65156
};
66157

67158
try {
68-
const response = await fetch("https://silver-meme-jj4x947jg76ghqjg9-3001.app.github.dev/api/foods/cat", requestOptions);
159+
const response = await fetch(process.env.BACKEND_URL + "/api/foods/cat", requestOptions);
69160
if (!response.ok) {
70161
throw new Error('Network response was not ok');
71162
}
@@ -90,7 +181,7 @@ const getState = ({ getStore, getActions, setStore }) => {
90181
};
91182

92183
try {
93-
const response = await fetch("https://silver-meme-jj4x947jg76ghqjg9-3001.app.github.dev/api/foods/exotic", requestOptions);
184+
const response = await fetch(process.env.BACKEND_URL +"/api/foods/exotic", requestOptions);
94185
if (!response.ok) {
95186
throw new Error('Network response was not ok');
96187
}
@@ -139,4 +230,4 @@ const getState = ({ getStore, getActions, setStore }) => {
139230
};
140231
};
141232

142-
export default getState;
233+
export default getState;

0 commit comments

Comments
 (0)