diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 07b6cb5..d5ee536 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -11,11 +11,12 @@ "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.5", "@mui/material": "^5.15.18", - "axios": "^1.6.8", + "axios": "^1.7.2", "react": "^18.2.0", "react-dom": "^18.2.0", "react-icons": "^5.1.0", "react-router-dom": "^6.23.0", + "react-star-ratings": "^2.3.0", "sweetalert": "^2.1.2", "sweetalert2": "^11.11.0" }, @@ -1889,9 +1890,9 @@ } }, "node_modules/axios": { - "version": "1.6.8", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz", - "integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==", + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz", + "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -2028,6 +2029,11 @@ "node": ">=0.8.0" } }, + "node_modules/classnames": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==" + }, "node_modules/clsx": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", @@ -4230,6 +4236,29 @@ "react-dom": ">=16.8" } }, + "node_modules/react-star-ratings": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/react-star-ratings/-/react-star-ratings-2.3.0.tgz", + "integrity": "sha512-34Z/oFNDRRn4ZcX7F3t9ccnpo7SQ32gD/vsusQOBc6B6vlqaGR6tke1/Yx3jTDjemKRSmXqhKgpPTR7/JAXq6A==", + "dependencies": { + "classnames": "^2.2.1", + "prop-types": "^15.6.0", + "react": "^16.1.0" + } + }, + "node_modules/react-star-ratings/node_modules/react": { + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", + "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/react-transition-group": { "version": "4.4.5", "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", diff --git a/frontend/package.json b/frontend/package.json index 7b9a80a..aa8c5c7 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -13,11 +13,12 @@ "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.5", "@mui/material": "^5.15.18", - "axios": "^1.6.8", + "axios": "^1.7.2", "react": "^18.2.0", "react-dom": "^18.2.0", "react-icons": "^5.1.0", "react-router-dom": "^6.23.0", + "react-star-ratings": "^2.3.0", "sweetalert": "^2.1.2", "sweetalert2": "^11.11.0" }, diff --git a/frontend/src/AdminPackages/AdminVista.css b/frontend/src/AdminPackages/AdminVista.css index e441343..72cf5bd 100644 --- a/frontend/src/AdminPackages/AdminVista.css +++ b/frontend/src/AdminPackages/AdminVista.css @@ -211,13 +211,7 @@ html { /* ********************************** */ /* BANNER */ /* ********************************** */ -.banner { - background-image: linear-gradient(100deg, #000000, #00000020), - url('assets/pastel-fondo.jpg'); - height: 60rem; - background-size: cover; - background-position: center; -} + .content-banner { max-width: 90rem; @@ -327,29 +321,6 @@ html { gap: 2rem; } -.category-moca { - background-image: linear-gradient(#00000080, #00000080), - url('assets/pastel-4-leches.jpg'); - background-size: cover; - background-position: bottom; - background-repeat: no-repeat; -} - -.category-capuchino { - background-image: linear-gradient(#00000080, #00000080), - url('assets/pastel-zarza.jpg'); - background-size: cover; - background-position: center; - background-repeat: no-repeat; -} - -.category-expreso { - background-image: linear-gradient(#00000080, #00000080), - url('assets/pastel-moka.jpg'); - background-size: cover; - background-position: center; - background-repeat: no-repeat; -} .card-category p { font-size: 2.5rem; @@ -1319,6 +1290,25 @@ html { background-color: #4b1e29; /* Cambia el color al pasar el cursor sobre el botón */ } + .modificar-btn { + margin-left: 2rem; + background-color: #8B374A; + color: #fff; + border: none; + padding: 8px 16px; + border-radius: 5px; + cursor: pointer; +} + +.modificar-btn:hover { + background-color: #ff4646; +} + + +.modificar-btn:hover { + background-color: #4b1e29; /* Cambia el color al pasar el cursor sobre el botón */ + } + .IniSesReserva{ padding-top: 2rem; diff --git a/frontend/src/AdminPackages/AdminVista.jsx b/frontend/src/AdminPackages/AdminVista.jsx index 9db4ed0..88521f5 100644 --- a/frontend/src/AdminPackages/AdminVista.jsx +++ b/frontend/src/AdminPackages/AdminVista.jsx @@ -25,7 +25,9 @@ import pastel_fresa_arcoiris from "/src/assets/Pastel-fresas-arcoiris.png"; import pastel_fresa_oreo from "/src/assets/Pastel-fresas-oreo.png"; import pastel_fresa_vainilla from "/src/assets/Pastel-fresas-vainilla.png"; -import pastelZarza from "/src/assets/pastel-zarza.jpg" +import pastelZarza from "/src/assets/pastel-zarza.jpg"; + +import Swal from 'sweetalert2'; function AdminVista() { @@ -121,6 +123,85 @@ const mostrarAlertaLogOut = () => { } }; + const mostrarAlertaEliminarPedido = (idPedido, nombPastel) => { + Swal.fire({ + title: "Eliminar Pedido", + text: `¿Seguro que quieres eliminar tu pedido del ${nombPastel}?`, + icon: "warning", + showCancelButton: true, // Mostrar el botón de cancelar + confirmButtonColor: "#3085d6", // Color del botón de confirmar + cancelButtonColor: "#d33", // Color del botón de cancelar + confirmButtonText: "Sí", // Texto del botón de confirmar + cancelButtonText: "No", // Texto del botón de cancelar + }).then((result) => { + if (result.isConfirmed) { + Swal.fire({ + text: "Pedido eliminado correctamente.", + icon: "success", + }); + eliminarPedido(idPedido); + } + }); + }; + + + const eliminarPedido = async (idPedido) => { + console.log(idPedido); + try { + if (idPedido) { + const response = await axios.post('http://localhost:4567/frontend/eliminarPedido', { datosId: { idPedido } }); + console.log(response.data); + // Lógica adicional si es necesario + obtenerPedidosDePasteles(); // Asumiendo que tienes una función para obtener pedidos, similar a obtenerReservaciones + } else { + console.log("El ID del pedido es obligatorio para eliminar."); + // Lógica adicional si es necesario + } + } catch (error) { + throw error; + } + }; + + const mostrarAlertaActualizarEstatusPedido = (idPedido, nombPastel) => { + Swal.fire({ + title: "Actualizar Estado del Pedido", + text: `¿Seguro que quieres marcar el pedido del ${nombPastel} como listo para entregar?`, + icon: "warning", + showCancelButton: true, // Mostrar el botón de cancelar + confirmButtonColor: "#3085d6", // Color del botón de confirmar + cancelButtonColor: "#d33", // Color del botón de cancelar + confirmButtonText: "Sí", // Texto del botón de confirmar + cancelButtonText: "No", // Texto del botón de cancelar + }).then((result) => { + if (result.isConfirmed) { + Swal.fire({ + text: "Estado del pedido actualizado a listo para entregar.", + icon: "success", + }); + actualizarEstatusPedido(idPedido, "listo para entregar"); + } + }); + }; + + + const actualizarEstatusPedido = async (idPedido, nuevoEstatus) => { + console.log(idPedido, nuevoEstatus); + try { + if (idPedido) { + const response = await axios.post('http://localhost:4567/frontend/actualizarEstatusPedido', { datosId: { idPedido, nuevoEstatus } }); + console.log(response.data); + // Lógica adicional si es necesario + obtenerPedidosDePasteles(); // Asumiendo que tienes una función para obtener pedidos + } else { + console.log("El ID del pedido es obligatorio para actualizar."); + // Lógica adicional si es necesario + } + } catch (error) { + throw error; + } + }; + + @@ -193,8 +274,11 @@ const mostrarAlertaLogOut = () => {

Estatus: {pedido.estatus}

Inscripción: {pedido.inscripcion}

Relleno: {pedido.relleno}

- + diff --git a/frontend/src/Pasteles/ChocolateBlanco.jsx b/frontend/src/Pasteles/ChocolateBlanco.jsx index a90d963..71dae24 100644 --- a/frontend/src/Pasteles/ChocolateBlanco.jsx +++ b/frontend/src/Pasteles/ChocolateBlanco.jsx @@ -13,6 +13,10 @@ import Swal from 'sweetalert2' import axios from 'axios'; +import StarRatings from 'react-star-ratings'; + + + function ChocolateBlanco() { const navigate = useNavigate(); @@ -86,6 +90,8 @@ function ChocolateBlanco() { useEffect(() => { // Llamar a la función al cargar la página obtenerNombreUsuario(); + obtenerReseñasPorPastel(); + mostrarReseñas(); }, []); const cerrarSesion = async () => { @@ -156,6 +162,120 @@ function ChocolateBlanco() { }; + + + + const [reseñas, setReseñas] = useState([]); + const [datosFormularioReseña, setDatosFormularioReseña] = useState( + {contenido: '', + estrellas: 5 + }); + + + const handleInputChange = (e) => { + const { name, value } = e.target; + setDatosFormularioReseña({ + ...datosFormularioReseña, + [name]: value, + }); + }; + + const enviarReseña = async (e) => { + e.preventDefault(); + await agregarReseña(); + await obtenerReseñasPorPastel("2"); // Obtener las reseñas nuevamente para actualizar la lista + }; + + + const agregarReseña = async () => { + console.log("Agregando reseña"); + console.log(datosFormularioReseña.contenido); + console.log(datosFormularioReseña.estrellas); + console.log(nombreUsuario) + + try{ + if(nombreUsuario==null){ + mostrarAlertaReseñaFallidaLogin(); + }else{ + const response = await axios.post('http://localhost:4567/frontend/agregarResenia', { + nombreUsuario: nombreUsuario, + idPastel: "2", // Asegúrate de tener el id del pastel + contenido: datosFormularioReseña.contenido, + estrellas: datosFormularioReseña.estrellas, + }); + + console.log(response.data); + //mostrarAlertaReseñaExitosa(); + console.log("reseña exitosa"); + console.log("") + // Limpiar los estados después de agregar la reseña + setDatosFormularioReseña({ contenido: "", estrellas: 0 }); + } + }catch(error){ + console.error("Error al agregar la reseña"); + throw error; + } + + + }; + + + const obtenerReseñasPorPastel = async (idPastel) => { + try { + const response = await axios.post('http://localhost:4567/frontend/obtenerReseniasPorPastel', { + idPastel: "2", + }); + console.log("Reseñas obtenidas:", response.data.reseñas); + const reseñasTransformadas = response.data.reseñas.map(reseña => ({ + idReseña: reseña.id_reseña, + nombreUsuario: reseña.nombre_usuario, + idPastel: reseña.id_pastel, + contenido: reseña.contenido, + estrellas: reseña.estrellas, + })); + + setReseñas(reseñasTransformadas); + } catch (error) { + console.error("Error al obtener reseñas:", error); + } + }; + + const mostrarReseñas = () => { + if (!nombreUsuario) { + return ( +

Inicia Sesión para poder ver las reseñas.

+ ); + } else { + if (reseñas.length === 0) { + return ( +

No hay reseñas para este pastel en este momento.

+ ); + } else { + return ( +
+ {reseñas.map(reseña => ( +
+
+ +
+
{reseña.nombreUsuario}
+
+
+
+ {"★".repeat(reseña.estrellas)}{"☆".repeat(5 - reseña.estrellas)} +
+

+ {reseña.contenido} +

+
+ ))} +
+ ); + } + } + }; + + return ( <> @@ -302,6 +422,49 @@ function ChocolateBlanco() { + + +
+ +

Reseñas

+ +
+

Calificación:

+ setDatosFormularioReseña({...datosFormularioReseña, estrellas: newRating})} + numberOfStars={5} + name='rating' + starDimension="30px" + /> +
+
+
+ + + + + + +
+ {mostrarReseñas()} + +
+ +
+ + + + + +