From 21cdf1b5db539b86fb0e0ae06efd81c33bede6e1 Mon Sep 17 00:00:00 2001 From: CarlosAguayo1 Date: Fri, 18 Jul 2025 10:40:11 +0000 Subject: [PATCH] pagina principal --- Pipfile | 1 + Pipfile.lock | 60 ++++++++- src/front/components/Navbar.jsx | 31 ++--- src/front/main.jsx | 1 + src/front/pages/Home.jsx | 219 +++++++++++++++++++++++++------- 5 files changed, 244 insertions(+), 68 deletions(-) diff --git a/Pipfile b/Pipfile index 44e04f14ff..921f9d2b89 100644 --- a/Pipfile +++ b/Pipfile @@ -20,6 +20,7 @@ typing-extensions = "*" flask-jwt-extended = "==4.6.0" wtforms = "==3.1.2" sqlalchemy = "*" +bcrypt = "*" [requires] python_version = "3.13" diff --git a/Pipfile.lock b/Pipfile.lock index b201c3decc..e56f1c489e 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "d2e672e650278aeeee2fe49bd76d76497d8b65a50f8b5dbb121d265cbc6ef4e5" + "sha256": "dc64a1f0dd7551608933a91632e5eb1245b4768aa8ddf4f8f02467a6f71e4744" }, "pipfile-spec": 6, "requires": { @@ -24,6 +24,64 @@ "markers": "python_version >= '3.8'", "version": "==1.14.1" }, + "bcrypt": { + "hashes": [ + "sha256:0042b2e342e9ae3d2ed22727c1262f76cc4f345683b5c1715f0250cf4277294f", + "sha256:0142b2cb84a009f8452c8c5a33ace5e3dfec4159e7735f5afe9a4d50a8ea722d", + "sha256:08bacc884fd302b611226c01014eca277d48f0a05187666bca23aac0dad6fe24", + "sha256:0d3efb1157edebfd9128e4e46e2ac1a64e0c1fe46fb023158a407c7892b0f8c3", + "sha256:0e30e5e67aed0187a1764911af023043b4542e70a7461ad20e837e94d23e1d6c", + "sha256:107d53b5c67e0bbc3f03ebf5b030e0403d24dda980f8e244795335ba7b4a027d", + "sha256:12fa6ce40cde3f0b899729dbd7d5e8811cb892d31b6f7d0334a1f37748b789fd", + "sha256:17a854d9a7a476a89dcef6c8bd119ad23e0f82557afbd2c442777a16408e614f", + "sha256:191354ebfe305e84f344c5964c7cd5f924a3bfc5d405c75ad07f232b6dffb49f", + "sha256:2ef6630e0ec01376f59a006dc72918b1bf436c3b571b80fa1968d775fa02fe7d", + "sha256:3004df1b323d10021fda07a813fd33e0fd57bef0e9a480bb143877f6cba996fe", + "sha256:335a420cfd63fc5bc27308e929bee231c15c85cc4c496610ffb17923abf7f231", + "sha256:33752b1ba962ee793fa2b6321404bf20011fe45b9afd2a842139de3011898fef", + "sha256:3a3fd2204178b6d2adcf09cb4f6426ffef54762577a7c9b54c159008cb288c18", + "sha256:3b8d62290ebefd49ee0b3ce7500f5dbdcf13b81402c05f6dafab9a1e1b27212f", + "sha256:3e36506d001e93bffe59754397572f21bb5dc7c83f54454c990c74a468cd589e", + "sha256:41261d64150858eeb5ff43c753c4b216991e0ae16614a308a15d909503617732", + "sha256:50e6e80a4bfd23a25f5c05b90167c19030cf9f87930f7cb2eacb99f45d1c3304", + "sha256:531457e5c839d8caea9b589a1bcfe3756b0547d7814e9ce3d437f17da75c32b0", + "sha256:55a935b8e9a1d2def0626c4269db3fcd26728cbff1e84f0341465c31c4ee56d8", + "sha256:57967b7a28d855313a963aaea51bf6df89f833db4320da458e5b3c5ab6d4c938", + "sha256:584027857bc2843772114717a7490a37f68da563b3620f78a849bcb54dc11e62", + "sha256:59e1aa0e2cd871b08ca146ed08445038f42ff75968c7ae50d2fdd7860ade2180", + "sha256:5bd3cca1f2aa5dbcf39e2aa13dd094ea181f48959e1071265de49cc2b82525af", + "sha256:5c1949bf259a388863ced887c7861da1df681cb2388645766c89fdfd9004c669", + "sha256:62f26585e8b219cdc909b6a0069efc5e4267e25d4a3770a364ac58024f62a761", + "sha256:67a561c4d9fb9465ec866177e7aebcad08fe23aaf6fbd692a6fab69088abfc51", + "sha256:6fb1fd3ab08c0cbc6826a2e0447610c6f09e983a281b919ed721ad32236b8b23", + "sha256:74a8d21a09f5e025a9a23e7c0fd2c7fe8e7503e4d356c0a2c1486ba010619f09", + "sha256:79e70b8342a33b52b55d93b3a59223a844962bef479f6a0ea318ebbcadf71505", + "sha256:7a4be4cbf241afee43f1c3969b9103a41b40bcb3a3f467ab19f891d9bc4642e4", + "sha256:7c03296b85cb87db865d91da79bf63d5609284fc0cab9472fdd8367bbd830753", + "sha256:842d08d75d9fe9fb94b18b071090220697f9f184d4547179b60734846461ed59", + "sha256:864f8f19adbe13b7de11ba15d85d4a428c7e2f344bac110f667676a0ff84924b", + "sha256:97eea7408db3a5bcce4a55d13245ab3fa566e23b4c67cd227062bb49e26c585d", + "sha256:a839320bf27d474e52ef8cb16449bb2ce0ba03ca9f44daba6d93fa1d8828e48a", + "sha256:afe327968aaf13fc143a56a3360cb27d4ad0345e34da12c7290f1b00b8fe9a8b", + "sha256:b4d4e57f0a63fd0b358eb765063ff661328f69a04494427265950c71b992a39a", + "sha256:b6354d3760fcd31994a14c89659dee887f1351a06e5dac3c1142307172a79f90", + "sha256:b693dbb82b3c27a1604a3dff5bfc5418a7e6a781bb795288141e5f80cf3a3492", + "sha256:bdc6a24e754a555d7316fa4774e64c6c3997d27ed2d1964d55920c7c227bc4ce", + "sha256:beeefe437218a65322fbd0069eb437e7c98137e08f22c4660ac2dc795c31f8bb", + "sha256:c5eeac541cefd0bb887a371ef73c62c3cd78535e4887b310626036a7c0a817bb", + "sha256:c950d682f0952bafcceaf709761da0a32a942272fad381081b51096ffa46cea1", + "sha256:d9af79d322e735b1fc33404b5765108ae0ff232d4b54666d46730f8ac1a43676", + "sha256:e53e074b120f2877a35cc6c736b8eb161377caae8925c17688bd46ba56daaa5b", + "sha256:e965a9c1e9a393b8005031ff52583cedc15b7884fce7deb8b0346388837d6cfe", + "sha256:f01e060f14b6b57bbb72fc5b4a83ac21c443c9a2ee708e04a10e9192f90a6281", + "sha256:f1e3ffa1365e8702dc48c8b360fef8d7afeca482809c5e45e653af82ccd088c1", + "sha256:f6746e6fec103fcd509b96bacdfdaa2fbde9a553245dbada284435173a6f1aef", + "sha256:f81b0ed2639568bf14749112298f9e4e2b28853dab50a8b357e31798686a036d" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==4.3.0" + }, "blinker": { "hashes": [ "sha256:b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf", diff --git a/src/front/components/Navbar.jsx b/src/front/components/Navbar.jsx index 30d43a2636..55fcda2a79 100644 --- a/src/front/components/Navbar.jsx +++ b/src/front/components/Navbar.jsx @@ -1,19 +1,14 @@ -import { Link } from "react-router-dom"; +import React from 'react'; +import { Link } from 'react-router-dom'; -export const Navbar = () => { - - return ( - - ); -}; \ No newline at end of file +export const Navbar = () => ( + +); \ No newline at end of file diff --git a/src/front/main.jsx b/src/front/main.jsx index a5a3c781dc..168d0e5f34 100644 --- a/src/front/main.jsx +++ b/src/front/main.jsx @@ -1,3 +1,4 @@ + import React from 'react' import ReactDOM from 'react-dom/client' import './index.css' // Global styles for your application diff --git a/src/front/pages/Home.jsx b/src/front/pages/Home.jsx index 341ed21768..b2f118d5d1 100644 --- a/src/front/pages/Home.jsx +++ b/src/front/pages/Home.jsx @@ -1,52 +1,173 @@ -import React, { useEffect } from "react" -import rigoImageUrl from "../assets/img/rigo-baby.jpg"; -import useGlobalReducer from "../hooks/useGlobalReducer.jsx"; +import React, { useEffect, useState } from "react"; +import { Link } from "react-router-dom"; +import useGlobalReducer from '../hooks/useGlobalReducer'; export const Home = () => { + const { store } = useGlobalReducer(); + const [offers, setOffers] = useState([]); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); - const { store, dispatch } = useGlobalReducer() - - const loadMessage = async () => { - try { - const backendUrl = import.meta.env.VITE_BACKEND_URL - - if (!backendUrl) throw new Error("VITE_BACKEND_URL is not defined in .env file") - - const response = await fetch(backendUrl + "/api/hello") - const data = await response.json() - - if (response.ok) dispatch({ type: "set_hello", payload: data.message }) - - return data - - } catch (error) { - if (error.message) throw new Error( - `Could not fetch the message from the backend. - Please check if the backend is running and the backend port is public.` - ); - } - - } - - useEffect(() => { - loadMessage() - }, []) - - return ( -
-

Hello Rigo!!

-

- Rigo Baby -

-
- {store.message ? ( - {store.message} - ) : ( - - Loading message from the backend (make sure your python 🐍 backend is running)... - - )} -
-
- ); -}; \ No newline at end of file + // Form state + const [form, setForm] = useState({ name: "", seller: "", price: "", unit: "", img: "" }); + const [submitting, setSubmitting] = useState(false); + const [submitError, setSubmitError] = useState(null); + + useEffect(() => { + const fetchOffers = async () => { + try { + const backendUrl = import.meta.env.VITE_BACKEND_URL; + if (!backendUrl) throw new Error("VITE_BACKEND_URL is not defined"); + + const res = await fetch(`${backendUrl}/api/offers`); + if (!res.ok) throw new Error(`Error: ${res.statusText}`); + const data = await res.json(); + setOffers(data); + } catch (err) { + setError(err.message); + } finally { + setLoading(false); + } + }; + fetchOffers(); + }, []); + + // Handle input change + const handleChange = e => { + const { name, value } = e.target; + setForm(prev => ({ ...prev, [name]: value })); + }; + + // Submit new offer + const handleSubmit = async e => { + e.preventDefault(); + setSubmitting(true); + setSubmitError(null); + try { + const backendUrl = import.meta.env.VITE_BACKEND_URL; + const res = await fetch(`${backendUrl}/api/offers`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(form) + }); + if (!res.ok) throw new Error(await res.text()); + const newOffer = await res.json(); + setOffers(prev => [newOffer, ...prev]); + setForm({ name: "", seller: "", price: "", unit: "", img: "" }); + } catch (err) { + setSubmitError(err.message); + } finally { + setSubmitting(false); + } + }; + + return ( +
+
+
+
+ {/* Conditionally show form if user is logged in */} + {store.user ? ( + <> +

Crear Nueva Oferta

+ {submitError &&
{submitError}
} +
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+ + ) : ( +
+ Inicia sesión para crear nuevas ofertas. +
+ )} + + {/* Listing */} +

Ofertas

+ {loading &&
Cargando...
} + {error &&
{error}
} + {!loading && !error && ( +
+
+ {offers.map(o => ( +
+ {o.name} +
+
{o.name}
+

Agricultor: {o.seller}

+

€{o.price} / {o.unit}

+
+
+ ))} +
+
+ )} +
+ Mostrar más +
+
+
+
+ Comprar + Vender +
+
+
+ ); +};