This commit is contained in:
NataliaCancinoV 2024-05-25 16:18:39 -06:00
commit 1fb9286822
67 changed files with 16374 additions and 0 deletions

21
.eslintrc.cjs Normal file
View File

@ -0,0 +1,21 @@
module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: [
'eslint:recommended',
'plugin:react/recommended',
'plugin:react/jsx-runtime',
'plugin:react-hooks/recommended',
],
ignorePatterns: ['dist', '.eslintrc.cjs'],
parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
settings: { react: { version: '18.2' } },
plugins: ['react-refresh'],
rules: {
'react/jsx-no-target-blank': 'off',
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
},
}

24
.gitignore vendored Normal file
View File

@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

8
README.md Normal file
View File

@ -0,0 +1,8 @@
# React + Vite
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
Currently, two official plugins are available:
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh

13
index.html Normal file
View File

@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Rapi cakeFactory</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>

5069
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

36
package.json Normal file
View File

@ -0,0 +1,36 @@
{
"name": "frontend",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview"
},
"dependencies": {
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.5",
"@mui/material": "^5.15.18",
"axios": "^1.7.2",
"emailjs-com": "^3.2.0",
"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.6.13"
},
"devDependencies": {
"@types/react": "^18.2.66",
"@types/react-dom": "^18.2.22",
"@vitejs/plugin-react": "^4.2.1",
"eslint": "^8.57.0",
"eslint-plugin-react": "^7.34.1",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.6",
"vite": "^5.2.0"
}
}

1
public/vite.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" className="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,426 @@
import { useState, useEffect } from 'react';
import './AdminVista.css';
import viteLogo from '/vite.svg'
import Edicion1 from '/src/assets/Edicion21.jpg';
import Edicion12 from '/src/assets/Edicion12.jpg';
import Edicion13 from '/src/assets/Edicion13.jpg';
import Edicion14 from '/src/assets/Edicion14.jpg';
import Edicion15 from '/src/assets/Edicion15.jpg';
import Edicion16 from '/src/assets/Edicion16.jpg';
import otra_imagen from '/src/assets/Edicion2.jpg';
import { RiCustomerService2Fill } from "react-icons/ri";
import { FaUser } from "react-icons/fa";
import { LuShoppingBasket } from "react-icons/lu";
import { FaMagnifyingGlass } from "react-icons/fa6";
import { CiHeart } from "react-icons/ci";
import { FaRegEye } from "react-icons/fa";
import { CiShare2 } from "react-icons/ci";
import { useNavigate } from "react-router-dom";
import axios from "axios";
//imagenes de pastel de fresas
import pastel_fresa_original from "/src/assets/Pastel-fresa-original.png";
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 Swal from 'sweetalert2';
function AdminVista() {
const [count, setCount] = useState(0);
const navigate = useNavigate();
const [pedidosDePasteles, setPedidosDePasteles] = useState([]);
const [datosFormulario, setDatosFormulario] = useState(
{correo: '',
password: '',
nombre: ''
});
const mostrarAlertaLogOut = () => {
Swal.fire({
title: "Cerrar Sesión",
text: "¿Seguro que quieres cerrar sesión?",
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: "Sesión cerrada correctamente. Adiós " + nombreUsuario + "",
icon: "success",
});
cerrarSesion();
}
});
};
const [nombreUsuario, setNombreUsuario]=useState("");
const obtenerNombreUsuario = async () => {
try {
// Realizar la llamada al backend para obtener el nombre del usuario
const response = await axios.post('http://localhost:4567/frontend/obtenerUsuario', { datosFormulario });
setNombreUsuario(response.data.nombre);
console.log(nombreUsuario);
console.log("hola"+ datosFormulario.nombre);
} catch (error) {
// Manejar el error según tus necesidades
console.error("Error al obtener el nombre del usuario", error);
}
};
useEffect(() => {
// Llamar a la función al cargar la página
obtenerNombreUsuario();
obtenerPedidosDePasteles();
console.log("obtuvo los pedidos");
}, []);
const cerrarSesion = async () => {
try {
// Realizar la llamada al backend para obtener el nombre del usuario
const response = await axios.post('http://localhost:4567/frontend/cerrarSesion', { datosFormulario });
setNombreUsuario(response.data.nombre);
console.log(nombreUsuario);
obtenerNombreUsuario();
//mostrarAlertaLogOut();
} catch (error) {
// Manejar el error según tus necesidades
console.error("Error al obtener el nombre del usuario", error);
}
};
const mostrarAlertaPedidoFallidaLogin=()=>{
Swal.fire({
title: "Pedido Fallida",
text: "Inicia Sesion para poder hacer un pedido.",
icon: "error",
button: "Aceptar"
});
};
const obtenerPedidosDePasteles = async () => {
try {
const response = await axios.post('http://localhost:4567/frontend/obtenerPedidosDePastelesAdmin');
console.log("Pedidos de pasteles obtenidos:", response.data.pedidos_de_pasteles);
// Almacena los pedidos de pasteles en el estado
setPedidosDePasteles(response.data.pedidos_de_pasteles);
} catch (error) {
console.error("Error al obtener pedidos de pasteles:", error);
}
};
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;
}
};
const redirectToLogin = () => {
navigate("/Login");
};
const redirectToPedidos = () => {
navigate("/Pedidos");
};
const [pedidos, setPedidos] = useState([]);
const generarPedidos = () => {
if (nombreUsuario == null) {
return (
<h1 className="IniSesReserva">Inicia Sesión para poder ver tus pedidos de pasteles.</h1>
);
} else {
if (pedidosDePasteles.length === 0) {
return (
<h1 className="ReservaNull">No tienes pedidos de pasteles en este momento.</h1>
);
} else {
return (
<div>
{pedidosDePasteles.map(pedido => (
<div key={pedido.id_pedido} className="reservacion">
<div className='container-img-pedido'>
{pedido.nombre_pastel === 'Pastel de Fresas' ? (
pedido.relleno === 'Original' ? <img src={pastel_fresa_original} alt="" className="imagenPastel" /> :
pedido.relleno === 'Arcoiris' ? <img src={pastel_fresa_arcoiris} alt="" className="imagenPastel" /> :
pedido.relleno === 'Oreo' ? <img src={pastel_fresa_oreo} alt="" className="imagenPastel" /> :
pedido.relleno === 'Vainilla' ? <img src={pastel_fresa_vainilla} alt="" className="imagenPastel" /> :
<img src={otra_imagen} alt="" className="imagenPastel" /> // Si el relleno no coincide con ninguno de los anteriores
) : pedido.nombre_pastel === 'Pastel Chocolate Blanco' ? (
<img src={Edicion1} alt="" className="imagenPastel" />
) : pedido.nombre_pastel === 'Pastel Cajeta' ? (
<img src={Edicion16} alt="" className="imagenPastel" />
): pedido.nombre_pastel === 'Pastel de Chocolate' ? (
<img src={Edicion13} alt="" className="imagenPastel" />
): pedido.nombre_pastel === 'Pastel Frambuesa' ? (
<img src={Edicion15} alt="" className="imagenPastel" />
) : pedido.nombre_pastel === 'Pastel de Moka' ? (
<img src={Edicion12} alt="" className="imagenPastel" />
) : pedido.nombre_pastel === 'Pastel de Zanahoria' ? (
<img src={Edicion14} alt="" className="imagenPastel" />
):(
<img src={otra_imagen} alt="" className="imagenPastel" /> // Si el pastel no es de fresas ni de chocolate blanco
)}
</div>
<div className="reservaData">
<h3>{pedido.nombre_pastel}</h3>
<p>Precio del pastel: ${pedido.precio}</p>
<p>Tamaño: {pedido.tamaño}</p>
<p>Estatus: {pedido.estatus}</p>
<p>Inscripción: {pedido.inscripcion}</p>
<p>Relleno: {pedido.relleno}</p>
<button className="eliminar-btn" onClick={() => mostrarAlertaEliminarPedido(pedido.id_pedido, pedido.nombre_pastel)}>
Eliminar Pedido
</button>
<button className="modificar-btn" onClick={() => mostrarAlertaActualizarEstatusPedido(pedido.id_pedido, pedido.nombre_pastel)}>
Modificar Pedido
</button>
</div>
</div>
))}
</div>
);
}
}
};
return (
<>
<body>
<header>
<div className="container-hero">
<div className="container hero">
<div className="customer-support">
<RiCustomerService2Fill className="icono-cliente" />
<div className="content-customer-support">
<span className="text">Soporte al cliente</span>
<span className="number">123-456-7890</span>
</div>
</div>
<div className="container-logo">
<i className="fa-solid fa-mug-hot"></i>
<h1 className="logo"><a href="/">Pasteleria RAPI</a></h1>
</div>
<div className="container-user">
<FaUser className="icono-User"/>
<div className="content-shopping-cart">
</div>
</div>
</div>
</div>
<div className="container-navbar">
<nav className="navbar container">
<i className="fa-solid fa-bars"></i>
<ul className="menu">
<li><a href="/Pedidos" onClick={redirectToPedidos}>Pedidos</a></li>
{nombreUsuario ? (
<>
<li className="enlaceNombre"><a href="#">{nombreUsuario}</a></li>
<li className="enlaceNombre2"><a href="#" onClick={mostrarAlertaLogOut}>Cerrar Sesión</a></li>
</>
) : (
<li className="enlaceNombre2"><a href="#" onClick={redirectToLogin}>Iniciar Sesión</a></li>
)
}
</ul>
<form className="search-form">
<input type="search" placeholder="Buscar..." />
<button className="btn-search">
<FaMagnifyingGlass className="icono-lupa" />
</button>
</form>
</nav>
</div>
</header>
<main className="main-pedidos">
<div id="contenedor_reservaciones">
{generarPedidos()}
</div>
</main>
<footer className="footer">
<div className="container container-footer">
<div className="menu-footer">
<div className="contact-info">
<p className="title-footer">Información de Contacto</p>
<ul>
<li>
Avenida Xalapa
</li>
<li>Teléfono: 2288520821</li>
<li>EmaiL: cdgn_17@hotmail.com</li>
</ul>
<div className="social-icons">
<span className="facebook">
<i className="fa-brands fa-facebook-f"></i>
</span>
<span className="twitter">
<i className="fa-brands fa-twitter"></i>
</span>
<span className="youtube">
<i className="fa-brands fa-youtube"></i>
</span>
<span className="pinterest">
<i className="fa-brands fa-pinterest-p"></i>
</span>
<span className="instagram">
<i className="fa-brands fa-instagram"></i>
</span>
</div>
</div>
<div className="information">
<p className="title-footer">Información</p>
<ul>
<li><a href="#">Acerca de Nosotros</a></li>
<li><a href="#">Información de Entrega</a></li>
<li><a href="#">Politicas de Privacidad</a></li>
<li><a href="#">Términos y condiciones</a></li>
<li><a href="#">Contactános</a></li>
</ul>
</div>
<div className="my-account">
<p className="title-footer">Mi cuenta</p>
<ul>
<li><a href="#">Mi cuenta</a></li>
<li><a href="#">Pedidos</a></li>
<li><a href="#">Boletín</a></li>
</ul>
</div>
</div>
<div className="copyright">
</div>
</div>
</footer>
</body>
</>
)
}
export default AdminVista

1170
src/AppInicio.css Normal file

File diff suppressed because it is too large Load Diff

498
src/AppInicio.jsx Normal file
View File

@ -0,0 +1,498 @@
import React, {useEffect, useState} from "react";
import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
import './AppInicio.css'
import { RiCustomerService2Fill } from "react-icons/ri";
import { FaUser } from "react-icons/fa";
import { LuShoppingBasket } from "react-icons/lu";
import { FaMagnifyingGlass } from "react-icons/fa6";
import { CiHeart } from "react-icons/ci";
import { FaRegEye } from "react-icons/fa";
import { CiShare2 } from "react-icons/ci";
import { useNavigate } from "react-router-dom";
import axios from 'axios';
import PastelEditado1 from "./assets/Edicion1.jpg";
import PastelEditado2 from "./assets/Edicion2.jpg";
import PastelEditado3 from "./assets/Edicion3.jpg";
import PastelEditado4 from "./assets/Edicion4.jpg";
import PastelEditado5 from "./assets/Edicion5.jpg";
import PastelEditado6 from "./assets/Edicion6.jpg";
import PastelZanahoria from "./assets/Pastel-Zanahoria.jpg";
import MejoresPasteles from "./assets/MejoresPasteles.jpg";
import PastelTematico from "./assets/pastel-tematico.jpg";
import Swal from 'sweetalert2';
//import PopupV from "/src/Popups/PopupLoginValido.jsx";
//import PopupIv from "/src/Popups/PopupLoginInvalido.jsx";
function App() {
const [count, setCount] = useState(0);
const navigate = useNavigate();
const [datosFormulario, setDatosFormulario] = useState(
{correo: '',
password: '',
nombre: ''
});
const redirectPersonalizarPastelArcoiris = () => {
navigate("/PersonalizarPastel/PastelArcoiris");
};
const redirectToLogin = () => {
navigate("/Login");
};
const redirectToPedidos = () => {
navigate("/Pedidos");
};
const redirectToPasteles = () => {
navigate("/Pasteles");
};
const redirectInicio = () => {
navigate("/");
};
const redirectToChocolate = ()=>{
navigate("/Pasteles/ChocolateBlanco")
};
const redirectToMoka = ()=>{
navigate("/Pasteles/PastelMoka")
};
const redirectToChocolate2 = ()=>{
navigate("/Pasteles/PastelChocolate")
};
const mostrarAlertaLogOut = () => {
Swal.fire({
title: "Cerrar Sesión",
text: "¿Seguro que quieres cerrar sesión?",
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: "Sesión cerrada correctamente. Adiós " + nombreUsuario + "",
icon: "success",
});
cerrarSesion();
}
});
};
const [nombreUsuario, setNombreUsuario]=useState("");
const obtenerNombreUsuario = async () => {
try {
// Realizar la llamada al backend para obtener el nombre del usuario
const response = await axios.post('http://localhost:4567/frontend/obtenerUsuario', { datosFormulario });
setNombreUsuario(response.data.nombre);
console.log(nombreUsuario);
console.log("hola"+ datosFormulario.nombre);
} catch (error) {
// Manejar el error según tus necesidades
console.error("Error al obtener el nombre del usuario", error);
}
};
useEffect(() => {
// Llamar a la función al cargar la página
obtenerNombreUsuario();
}, []);
const cerrarSesion = async () => {
try {
// Realizar la llamada al backend para obtener el nombre del usuario
const response = await axios.post('http://localhost:4567/frontend/cerrarSesion', { datosFormulario });
setNombreUsuario(response.data.nombre);
console.log(nombreUsuario);
obtenerNombreUsuario();
//mostrarAlertaLogOut();
} catch (error) {
// Manejar el error según tus necesidades
console.error("Error al obtener el nombre del usuario", error);
}
};
return (
<>
<body>
<header>
<div className="container-hero">
<div className="container hero">
<div className="customer-support">
<RiCustomerService2Fill className="icono-cliente" />
<div className="content-customer-support">
<span className="text">Soporte al cliente</span>
<span className="number">123-456-7890</span>
</div>
</div>
<div className="container-logo">
<i className="fa-solid fa-mug-hot"></i>
<h1 className="logo"><a href="/">Pasteleria RAPI</a></h1>
</div>
<div className="container-user">
<FaUser className="icono-User"/>
<div className="content-shopping-cart">
</div>
</div>
</div>
</div>
<div className="container-navbar">
<nav className="navbar container">
<i className="fa-solid fa-bars"></i>
<ul className="menu">
<li><a href="#" onClick={redirectInicio}>Inicio</a></li>
<li><a href="#" onClick={redirectToPasteles} >Pasteles</a></li>
<li><a href="#" onClick={redirectPersonalizarPastelArcoiris}>Personalizar Pastel</a></li>
<li><a href="/Pedidos" onClick={redirectToPedidos}>Pedidos</a></li>
<li><a href="#">Blog</a></li>
{nombreUsuario ? (
<>
<li className="enlaceNombre"><a href="#">{nombreUsuario}</a></li>
<li className="enlaceNombre2"><a href="#" onClick={mostrarAlertaLogOut}>Cerrar Sesión</a></li>
</>
) : (
<li className="enlaceNombre2"><a href="#" onClick={redirectToLogin}>Iniciar Sesión</a></li>
)
}
</ul>
<form className="search-form">
</form>
</nav>
</div>
</header>
<section className="banner">
<div className="content-banner">
<p>Pastel Delicioso</p>
<h2>100% Hecho <br />Por Nosotros</h2>
<a href="#">Comprar ahora</a>
</div>
</section>
<main className="main-content">
<section className="container container-features">
</section>
<section className="container top-categories">
<h1 className="heading-1">Mejores Categorías</h1>
<div className="container-categories">
<div className="card-category category-moca">
<p>Pasteles Personalizados</p>
<span onClick={redirectPersonalizarPastelArcoiris}>Ver más</span>
</div>
<div className="card-category category-expreso">
<p>Pasteles en linea </p>
<span onClick={redirectToPasteles}>Ver más</span>
</div>
</div>
</section>
<section className="container top-products">
<h1 className="heading-1">Mejores Productos</h1>
<div className="container-options">
<span className="active">Destacados</span>
</div>
<div className="container-products">
<div className="card-product">
<div className="container-img">
<img src={PastelEditado1} alt="Cafe Irish" />
<span className="discount">-10%</span>
<div className="button-group">
</div>
</div>
<div className="content-card-product">
<div className="stars">
<i className="fa-solid fa-star"></i>
<i className="fa-solid fa-star"></i>
<i className="fa-solid fa-star"></i>
<i className="fa-solid fa-star"></i>
<i className="fa-regular fa-star"></i>
</div>
<h3>Pastel Chocolate Blanco</h3>
<span className="add-cart" onClick={redirectToChocolate}>
<FaRegEye className="icono-eye"/>
</span>
<p className="price">$603<span>$670</span></p>
</div>
</div>
<div className="card-product">
<div className="container-img">
<img
src={PastelEditado2}
alt="Cafe incafe-ingles.jpg"
/>
<span className="discount">-30%</span>
<div className="button-group">
</div>
</div>
<div className="content-card-product">
<div className="stars">
<i className="fa-solid fa-star"></i>
<i className="fa-solid fa-star"></i>
<i className="fa-solid fa-star"></i>
<i className="fa-regular fa-star"></i>
<i className="fa-regular fa-star"></i>
</div>
<h3>Pastel de Moka</h3>
<span className="add-cart" onClick={redirectToMoka}>
<FaRegEye className="icono-eye"/>
</span>
<p className="price">$560 <span>$800</span></p>
</div>
</div>
<div className="card-product">
<div className="container-img">
<img
src={PastelEditado3}
alt="Cafe Australiano"
/>
<div className="button-group">
</div>
</div>
<div className="content-card-product">
<div className="stars">
<i className="fa-solid fa-star"></i>
<i className="fa-solid fa-star"></i>
<i className="fa-solid fa-star"></i>
<i className="fa-solid fa-star"></i>
<i className="fa-solid fa-star"></i>
</div>
<h3>Pastel de Chocolate</h3>
<span className="add-cart" onClick={redirectToChocolate2}>
<FaRegEye className="icono-eye"/>
</span>
<p className="price">$350</p>
</div>
</div>
<div className="card-product">
<div className="container-img">
<img src={PastelEditado4} alt="Moka" />
<div className="button-group">
</div>
</div>
<div className="content-card-product">
<div className="stars">
<i className="fa-solid fa-star"></i>
<i className="fa-solid fa-star"></i>
<i className="fa-solid fa-star"></i>
<i className="fa-solid fa-star"></i>
<i className="fa-regular fa-star"></i>
</div>
<h3>Pastel de Zanahoria</h3>
<span className="add-cart" >
<FaRegEye className="icono-eye"/>
</span>
<p className="price">$450</p>
</div>
</div>
</div>
</section>
<section className="container specials">
<h1 className="heading-1"></h1>
<div className="container-products">
</div>
</section>
<section className="container blogs">
<h1 className="heading-1">Últimos Blogs</h1>
<div className="container-blogs">
<div className="card-blog">
<div className="container-img">
<img src= {MejoresPasteles} alt="Imagen Blog 1" />
<div className="button-group-blog">
<span>
<i className="fa-solid fa-magnifying-glass"></i>
</span>
<span>
<i className="fa-solid fa-link"></i>
</span>
</div>
</div>
<div className="content-blog">
<h3>Los 5 Mejores Pasteles que Debes Probar</h3>
<span>27 de abril de 2024</span>
<p>
En este blog, quiero compartir contigo los cinco pasteles que considero absolutamente deliciosos y que definitivamente deberías probar al menos una vez en la vida. Estos pasteles son mis favoritos por diferentes razones, desde su sabor hasta su textura y presentación. ¡Espero que te animes a probarlos y que también se conviertan en tus favoritos!
</p>
<div className="btn-read-more">Leer más</div>
</div>
</div>
<div className="card-blog">
<div className="container-img">
<img src={PastelZanahoria} alt="Imagen Blog 2" />
<div className="button-group-blog">
<span>
<i className="fa-solid fa-magnifying-glass"></i>
</span>
<span>
<i className="fa-solid fa-link"></i>
</span>
</div>
</div>
<div className="content-blog">
<h3>Receta: Pastel de Zanahoria</h3>
<span>23 de abril de 2024</span>
<p>
El pastel de zanahoria es una verdadera joya en el mundo de la repostería. Su combinación de sabores dulces y especiados, junto con la textura húmeda y esponjosa, lo convierten en un postre irresistible para cualquier ocasión. En este artículo, te compartiré mi receta favorita de pastel
de zanahoria para que puedas disfrutar de esta delicia en cada bocado.
</p>
<div className="btn-read-more">Leer más</div>
</div>
</div>
<div className="card-blog">
<div className="container-img">
<img src={PastelTematico} alt="Imagen Blog 3" />
<div className="button-group-blog">
<span>
<i className="fa-solid fa-magnifying-glass"></i>
</span>
<span>
<i className="fa-solid fa-link"></i>
</span>
</div>
</div>
<div className="content-blog">
<h3>5 Caracteristicas de un patel tematico</h3>
<span>20 de abril de 2024</span>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing
elit. Iste, molestiae! Ratione et, dolore ipsum
quaerat iure illum reprehenderit non maxime amet dolor
voluptas facilis corporis, consequatur eius est sunt
suscipit?
</p>
<div className="btn-read-more">Leer más</div>
</div>
</div>
</div>
</section>
</main>
<footer className="footer">
<div className="container container-footer">
<div className="menu-footer">
<div className="contact-info">
<p className="title-footer">Información de Contacto</p>
<ul>
<li>
Avenida Xalapa
</li>
<li>Teléfono: 2288520821</li>
<li>EmaiL: cdgn_17@hotmail.com</li>
</ul>
<div className="social-icons">
<span className="facebook">
<i className="fa-brands fa-facebook-f"></i>
</span>
<span className="twitter">
<i className="fa-brands fa-twitter"></i>
</span>
<span className="youtube">
<i className="fa-brands fa-youtube"></i>
</span>
<span className="pinterest">
<i className="fa-brands fa-pinterest-p"></i>
</span>
<span className="instagram">
<i className="fa-brands fa-instagram"></i>
</span>
</div>
</div>
<div className="information">
<p className="title-footer">Información</p>
<ul>
<li><a href="#">Acerca de Nosotros</a></li>
<li><a href="#">Información de Entrega</a></li>
<li><a href="#">Politicas de Privacidad</a></li>
<li><a href="#">Términos y condiciones</a></li>
<li><a href="#">Contactános</a></li>
</ul>
</div>
<div className="my-account">
<p className="title-footer">Mi cuenta</p>
<ul>
<li><a href="#">Mi cuenta</a></li>
<li><a href="#">Pedidos</a></li>
<li><a href="#">Boletín</a></li>
</ul>
</div>
</div>
<div className="copyright">
</div>
</div>
</footer>
<script
src="https://kit.fontawesome.com/81581fb069.js"
crossOrigin="anonymous"
></script>
</body>
</>
)
}
export default App

0
src/Pasteles.css Normal file
View File

477
src/Pasteles.jsx Normal file
View File

@ -0,0 +1,477 @@
import React, {useEffect, useState} from "react";
import viteLogo from '/vite.svg'
import './Pasteles.css'
import { RiCustomerService2Fill } from "react-icons/ri";
import { FaUser } from "react-icons/fa";
import { LuShoppingBasket } from "react-icons/lu";
import { FaMagnifyingGlass } from "react-icons/fa6";
import { CiHeart } from "react-icons/ci";
import { FaRegEye } from "react-icons/fa";
import { CiShare2 } from "react-icons/ci";
import { useNavigate } from "react-router-dom";
import PastelEditado1 from "./assets/Edicion1.jpg";
import PastelEditado2 from "./assets/Edicion2.jpg";
import PastelEditado3 from "./assets/Edicion3.jpg";
import PastelEditado4 from "./assets/Edicion4.jpg";
import PastelEditado5 from "./assets/Edicion5.jpg";
import PastelEditado6 from "./assets/Edicion6.jpg";
import PastelZanahoria from "./assets/Pastel-Zanahoria.jpg";
import MejoresPasteles from "./assets/MejoresPasteles.jpg";
import PastelTematico from "./assets/pastel-tematico.jpg";
import Swal from 'sweetalert2'
import axios from 'axios';
function AppPasteles() {
const [count, setCount] = useState(0);
const navigate = useNavigate();
const [datosFormulario, setDatosFormulario] = useState(
{correo: '',
password: '',
nombre: ''
});
const redirectPersonalizarPastelArcoiris = () => {
// Redirige a la página del hotel cuando se hace clic en el botón
navigate("/PersonalizarPastel/PastelArcoiris");
};
const redirectToLogin = () => {
navigate("/Login");
};
const redirectToPedidos = () => {
navigate("/Pedidos");
};
const redirectToPasteles = () => {
navigate("/Pasteles");
};
const redirectInicio = () => {
navigate("/");
};
const redirectToChocolate = ()=>{
navigate("/Pasteles/ChocolateBlanco")
};
const redirectToMoka = ()=>{
navigate("/Pasteles/PastelMoka")
};
const redirectToChocolate2 = ()=>{
navigate("/Pasteles/PastelChocolate")
};
const redirectToPastelZanahoria = ()=>{
navigate("/Pasteles/PastelZanahoria")
};
const redirectToPastelFrambuesa = ()=>{
navigate("/Pasteles/PastelFrambuesa")
};
const redirectToPastelCajeta = ()=>{
navigate("/Pasteles/PastelCajeta")
};
const mostrarAlertaLogOut = () => {
Swal.fire({
title: "Cerrar Sesión",
text: "¿Seguro que quieres cerrar sesión?",
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: "Sesión cerrada correctamente. Adiós " + nombreUsuario + "",
icon: "success",
});
cerrarSesion();
}
});
};
const [nombreUsuario, setNombreUsuario]=useState("");
const obtenerNombreUsuario = async () => {
try {
// Realizar la llamada al backend para obtener el nombre del usuario
const response = await axios.post('http://localhost:4567/frontend/obtenerUsuario', { datosFormulario });
setNombreUsuario(response.data.nombre);
console.log(nombreUsuario);
} catch (error) {
// Manejar el error según tus necesidades
console.error("Error al obtener el nombre del usuario", error);
}
};
useEffect(() => {
// Llamar a la función al cargar la página
obtenerNombreUsuario();
}, []);
const cerrarSesion = async () => {
try {
// Realizar la llamada al backend para obtener el nombre del usuario
const response = await axios.post('http://localhost:4567/frontend/cerrarSesion', { datosFormulario });
setNombreUsuario(response.data.nombre);
console.log(nombreUsuario);
obtenerNombreUsuario();
//mostrarAlertaLogOut();
} catch (error) {
// Manejar el error según tus necesidades
console.error("Error al obtener el nombre del usuario", error);
}
};
return (
<>
<body>
<header>
<div className="container-hero">
<div className="container hero">
<div className="customer-support">
<RiCustomerService2Fill className="icono-cliente" />
<div className="content-customer-support">
<span className="text">Soporte al cliente</span>
<span className="number">123-456-7890</span>
</div>
</div>
<div className="container-logo">
<i className="fa-solid fa-mug-hot"></i>
<h1 className="logo"><a href="/">Pasteleria RAPI</a></h1>
</div>
<div className="container-user">
<FaUser className="icono-User"/>
<div className="content-shopping-cart">
</div>
</div>
</div>
</div>
<div className="container-navbar">
<nav className="navbar container">
<i className="fa-solid fa-bars"></i>
<ul className="menu">
<li><a href="#" onClick={redirectInicio}>Inicio</a></li>
<li><a href="#" onClick={redirectToPasteles} >Pasteles</a></li>
<li><a href="#" onClick={redirectPersonalizarPastelArcoiris}>Personalizar Pastel</a></li>
<li><a href="/Pedidos" onClick={redirectToPedidos}>Pedidos</a></li>
<li><a href="#">Blog</a></li>
{nombreUsuario ? (
<>
<li className="enlaceNombre"><a href="#">{nombreUsuario}</a></li>
<li className="enlaceNombre2"><a href="#" onClick={mostrarAlertaLogOut}>Cerrar Sesión</a></li>
</>
) : (
<li className="enlaceNombre2"><a href="#" onClick={redirectToLogin}>Iniciar Sesión</a></li>
)
}
</ul>
<form className="search-form">
<input type="search" placeholder="Buscar..." />
<button className="btn-search">
<FaMagnifyingGlass className="icono-lupa" />
</button>
</form>
</nav>
</div>
</header>
<main className="main-content">
<section className="container container-features">
</section>
<section className="container top-categories">
</section>
<section className="container top-products">
<section className="container top-products">
<h1 className="heading-2"><strong>Productos en linea:</strong> </h1>
<div className="container-options">
</div>
<div className="container-products">
<div className="card-product">
<div className="container-img">
<img src={PastelEditado1} alt="Pastel Chocolate Blanco" />
<span className="discount">-10%</span>
<div className="button-group">
</div>
</div>
<div className="content-card-product">
<div className="stars">
<i className="fa-solid fa-star"></i>
<i className="fa-solid fa-star"></i>
<i className="fa-solid fa-star"></i>
<i className="fa-solid fa-star"></i>
<i className="fa-regular fa-star"></i>
</div>
<h3 className='heading-3'>Pastel Chocolate Blanco</h3>
<span className= "add-cart" onClick={redirectToChocolate}>
<FaRegEye className="icono-eye" />
</span>
<p className="price">$603<span>$670</span></p>
</div>
</div>
<div className="card-product">
<div className="container-img">
<img
src={PastelEditado2} alt="Cafe incafe-ingles.jpg"
/>
<span className="discount">-30%</span>
<div className="button-group">
</div>
</div>
<div className="content-card-product">
<div className="stars">
<i className="fa-solid fa-star"></i>
<i className="fa-solid fa-star"></i>
<i className="fa-solid fa-star"></i>
<i className="fa-regular fa-star"></i>
<i className="fa-regular fa-star"></i>
</div>
<h3>Pastel de Moka</h3>
<span className="add-cart" onClick={redirectToMoka}>
<FaRegEye className="icono-eye" />
</span>
<p className="price">$560 <span>$800</span></p>
</div>
</div>
<div className="card-product">
<div className="container-img">
<img
src={PastelEditado3}
alt="Cafe Australiano"
/>
<div className="button-group">
</div>
</div>
<div className="content-card-product">
<div className="stars">
<i className="fa-solid fa-star"></i>
<i className="fa-solid fa-star"></i>
<i className="fa-solid fa-star"></i>
<i className="fa-solid fa-star"></i>
<i className="fa-solid fa-star"></i>
</div>
<h3>Pastel de Chocolate</h3>
<span className="add-cart" onClick={redirectToChocolate2}>
<FaRegEye className="icono-eye" />
</span>
<p className="price">$350</p>
</div>
</div>
<div className="card-product">
<div className="container-img">
<img src={PastelEditado4} alt="Moka" />
<div className="button-group">
</div>
</div>
<div className="content-card-product">
<div className="stars">
<i className="fa-solid fa-star"></i>
<i className="fa-solid fa-star"></i>
<i className="fa-solid fa-star"></i>
<i className="fa-solid fa-star"></i>
<i className="fa-regular fa-star"></i>
</div>
<h3>Pastel de Zanahoria</h3>
<span className="add-cart" onClick={redirectToPastelZanahoria}>
<FaRegEye className="icono-eye" />
</span>
<p className="price">$450</p>
</div>
</div>
<div className="card-product">
<div className="container-img">
<img src={PastelEditado5} alt="Cafe Irish" />
<span className="discount">-13%</span>
<div className="button-group">
</div>
</div>
<div className="content-card-product">
<div className="stars">
<i className="fa-solid fa-star"></i>
<i className="fa-solid fa-star"></i>
<i className="fa-solid fa-star"></i>
<i className="fa-solid fa-star"></i>
<i className="fa-regular fa-star"></i>
</div>
<h3>Pastel Frambuesa</h3>
<span className="add-cart" onClick={redirectToPastelFrambuesa}>
<FaRegEye className="icono-eye" />
</span>
<p className="price">$300 </p>
</div>
</div>
<div className="card-product">
<div className="container-img">
<img
src={PastelEditado6}
alt="Cafe incafe-ingles.jpg"
/>
<span className="discount">-22%</span>
<div className="button-group">
</div>
</div>
<div className="content-card-product">
<div className="stars">
<i className="fa-solid fa-star"></i>
<i className="fa-solid fa-star"></i>
<i className="fa-solid fa-star"></i>
<i className="fa-regular fa-star"></i>
<i className="fa-regular fa-star"></i>
</div>
<h3>Pastel de Cajeta</h3>
<span className="add-cart" onClick={redirectToPastelCajeta}>
<FaRegEye className="icono-eye" />
</span>
<p className="price">$390 <span>$500</span></p>
</div>
</div>
</div>
<div className="container-products">
</div>
</section>
</section>
<section className="container specials">
<h1 className="heading-1"></h1>
<div className="container-products">
</div>
</section>
<section className="container blogs">
</section>
</main>
<footer className="footer">
<div className="container container-footer">
<div className="menu-footer">
<div className="contact-info">
<p className="title-footer">Información de Contacto</p>
<ul>
<li>
Avenida Xalapa
</li>
<li>Teléfono: 2288520821</li>
<li>EmaiL: cdgn_17@hotmail.com</li>
</ul>
<div className="social-icons">
<span className="facebook">
<i className="fa-brands fa-facebook-f"></i>
</span>
<span className="twitter">
<i className="fa-brands fa-twitter"></i>
</span>
<span className="youtube">
<i className="fa-brands fa-youtube"></i>
</span>
<span className="pinterest">
<i className="fa-brands fa-pinterest-p"></i>
</span>
<span className="instagram">
<i className="fa-brands fa-instagram"></i>
</span>
</div>
</div>
<div className="information">
<p className="title-footer">Información</p>
<ul>
<li><a href="#">Acerca de Nosotros</a></li>
<li><a href="#">Información de Entrega</a></li>
<li><a href="#">Politicas de Privacidad</a></li>
<li><a href="#">Términos y condiciones</a></li>
<li><a href="#">Contactános</a></li>
</ul>
</div>
<div className="my-account">
<p className="title-footer">Mi cuenta</p>
<ul>
<li><a href="#">Mi cuenta</a></li>
<li><a href="#">Pedidos</a></li>
<li><a href="#">Boletín</a></li>
</ul>
</div>
</div>
<div className="copyright">
</div>
</div>
</footer>
</body>
</>
)
}
export default AppPasteles

View File

@ -0,0 +1,584 @@
@import url('https://fonts.googleapis.com/css2?family=Ubuntu:wght@300;500;700&display=swap');
.main-pers-pastel {
display: flex;
gap: 30px;
margin-bottom: 80px;
font-family: 'Ubuntu';
max-width: 1200px;
margin: 0 auto;
margin-top: 20px;
}
.titulo-Pastel{
font-size: 25px;
}
/* ********************************** */
/* HEADER */
/* ********************************** */
.container-hero {
background-color: var(--background-color);
}
.hero {
display: flex;
justify-content: space-between;
align-items: center;
padding: 2rem 0;
}
.customer-support {
display: flex;
align-items: center;
gap: 2rem;
}
.customer-support i {
font-size: 3.3rem;
}
.content-customer-support {
display: flex;
flex-direction: column;
}
.container-logo {
display: flex;
align-items: center;
gap: 0.5rem;
}
.container-logo i {
font-size: 3rem;
}
.container-logo h1 a {
text-decoration: none;
color: #000;
font-size: 3rem;
text-transform: uppercase;
letter-spacing: -1px;
}
.container-user {
display: flex;
gap: 1rem;
cursor: pointer;
}
.container-user .fa-user {
font-size: 3rem;
color: var(--primary-color);
padding-right: 2.5rem;
border-right: 1px solid #e2e2e2;
}
.container-user .fa-basket-shopping {
font-size: 3rem;
color: var(--primary-color);
padding-left: 1rem;
}
.content-shopping-cart {
display: flex;
flex-direction: column;
}
/* ************* NAVBAR ************* */
.container-navbar {
background-color: var(--primary-color);
}
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 0;
color: white;
}
.navbar .fa-bars {
display: none;
}
.menu {
display: flex;
gap: 2rem;
}
.menu li {
list-style: none;
}
.menu a {
text-decoration: none;
font-size: 1.3rem;
color: var(--dark-color);
font-weight: 600;
text-transform: uppercase;
position: relative;
color: white;
}
.menu a::after {
content: '';
width: 1.5rem;
height: 1px;
background-color: #fff;
position: absolute;
bottom: -3px;
left: 50%;
transform: translate(-50%, 50%);
opacity: 0;
transition: all 0.3s ease;
}
.menu a:hover::after {
opacity: 1;
}
.menu a:hover {
color: #fff;
}
.search-form {
position: relative;
display: flex;
align-items: center;
border: 2px solid #fff;
border-radius: 2rem;
background-color: #fff;
height: 4.4rem;
overflow: hidden;
}
.search-form input {
outline: none;
font-family: inherit;
border: none;
width: 25rem;
font-size: 1.4rem;
padding: 0 2rem;
color: #777;
cursor: pointer;
display: none;
}
.search-form input::-webkit-search-cancel-button {
appearance: none;
}
.search-form .btn-search {
border: none;
background-color: var(--primary-color);
display: flex;
align-items: center;
justify-content: center;
height: 100%;
padding: 1rem;
display: none;
}
.btn-search i {
font-size: 2rem;
color: #fff;
}
.container-title {
padding: 30px;
background-color: #eee;
margin-bottom: 50px;
color: #222;
}
.chocolate-blanco {
background-color: #f7f7f9;
background-image: url('/assets/pastel-zarza.jpg');
flex: 1;
width: 55%;
height: 100%;
padding-top: 60.4%;
background-size: 100% auto;
}
.container-info-product {
flex: 1;
display: flex;
flex-direction: column;
}
.container-price {
padding-bottom: 20px;
border-bottom: 1px solid #e4e4e4;
display: flex;
align-items: center;
justify-content: space-between;
}
.container-price span {
font-size: 24px;
font-weight: 300;
}
.container-details-product {
padding: 30px 0;
padding-bottom: 0px;
}
.opcionesPers{
}
.textPersPastel{
font-size: 18px;
font-weight: 900;
margin-bottom: 10px;
}
.pastel-Type{
font-size: 18px;
font-weight: 900;
font-weight: lighter;
margin-bottom: 10px;
}
.pastel-Type1{
font-size: 18px;
font-weight: lighter;
margin-bottom: 10px;
color: #8B374A;
}
.botones-pastel{
display: flex;
gap: 4;
margin-bottom: 20px;
}
.boton-1{
margin-right: 10px;
border: none;
color: white;
padding: 14px 28px;
cursor: pointer;
border-radius: 5px;
background-color: #8B374A
}
.boton-1:hover {
background-color: #4b1e29; /* Cambia el color al pasar el cursor sobre el botón */
}
.boton-1:active {
transform: scale(0.90); /* Reduce ligeramente el tamaño del botón cuando se hace clic */
}
.boton-2{
margin-right: 10px;
border: none;
color: white;
padding: 14px 28px;
cursor: pointer;
border-radius: 5px;
background-color: #8B374A
}
.boton-2:hover {
background-color: #4b1e29; /* Cambia el color al pasar el cursor sobre el botón */
}
.boton-2:active {
transform: scale(0.90); /* Reduce ligeramente el tamaño del botón cuando se hace clic */
}
.boton-3{
margin-right: 10px;
border: none;
color: white;
padding: 14px 28px;
cursor: pointer;
border-radius: 5px;
background-color: #8B374A
}
.boton-3:hover {
background-color: #4b1e29; /* Cambia el color al pasar el cursor sobre el botón */
}
.boton-3:active {
transform: scale(0.90); /* Reduce ligeramente el tamaño del botón cuando se hace clic */
}
.boton-4{
border: none;
color: white;
padding: 14px 28px;
cursor: pointer;
border-radius: 5px;
background-color: #8B374A
}
.boton-4:hover {
background-color: #4b1e29; /* Cambia el color al pasar el cursor sobre el botón */
}
.boton-4:active {
transform: scale(0.90); /* Reduce ligeramente el tamaño del botón cuando se hace clic */
}
.label-text-pers{
margin-top: 10px;
font-size: 16px;
font-weight: lighter;
margin-bottom: 10px;
}
.input-text-pers{
margin-top: 10px;
font-size: 16px;
margin-bottom: 10px;
text-indent: 5px;
width: 100%;
height: 50px;
}
.form-group {
display: flex;
align-items: center;
gap: 20px;
margin-bottom: 15px;
}
.form-group label {
width: 100px;
color: #222;
font-weight: 700;
}
.form-group select {
width: 300px;
border: none;
padding: 12px 15px;
background-color: #f7f7f7;
outline: none;
color: #666;
}
.btn-clean {
border: none;
background: none;
color: #666;
margin-left: 120px;
cursor: pointer;
}
.btn-clean:hover {
color: #1bbeb4;
}
.container-add-cart {
display: flex;
gap: 20px;
padding-bottom: 30px;
border-bottom: 1px solid #e4e4e4;
}
.container-quantity {
position: relative;
}
.input-quantity {
background-color: #f7f7f7;
border: none;
padding: 10px;
width: 60px;
height: 100%;
color: #666;
font-weight: 500;
line-height: 0;
}
.input-quantity:focus {
outline: none;
}
.input-quantity::-webkit-inner-spin-button,
.input-quantity::-webkit-outer-spin-button {
-webkit-appearance: none;
appearance: none;
}
.fa-chevron-down:hover {
color: #1bbeb4;
}
.fa-chevron-up:hover {
color: #1bbeb4;
}
.btn-add-to-cart{
border: none;
color: white;
padding: 14px 28px;
cursor: pointer;
border-radius: 5px;
background-color: #8B374A
}
.btn-add-to-cart:hover {
background-color: #4b1e29; /* Cambia el color al pasar el cursor sobre el botón */
}
.btn-add-to-cart:active {
transform: scale(0.90); /* Reduce ligeramente el tamaño del botón cuando se hace clic */
}
.hidden {
display: none;
}
.container-description,
.container-additional-information,
.container-reviews {
display: flex;
flex-direction: column;
border-bottom: 1px solid #e4e4e4;
padding: 10px 0;
}
.title-description,
.title-additional-information,
.title-reviews {
display: flex;
align-items: center;
justify-content: space-between;
cursor: pointer;
}
.title-description h4,
.title-additional-information h4,
.title-reviews h4 {
font-weight: 300;
color: #666;
font-size: 14px;
}
.text-description,
.text-additional-information,
.text-reviews {
font-size: 13px;
color: #252525;
line-height: 22px;
margin-top: 25px;
}
.container-social {
display: flex;
justify-content: space-between;
padding: 10px 0;
align-items: center;
border-bottom: 1px solid #e4e4e4;
}
.container-social span {
font-weight: 300;
color: #252525;
}
.container-buttons-social {
display: flex;
gap: 15px;
align-items: center;
}
.container-buttons-social a:link,
.container-buttons-social a:visited {
color: #666;
font-size: 15px;
}
.container-buttons-social a:hover {
color: #1bbeb4;
}
.container-related-products h2 {
text-align: center;
margin-bottom: 30px;
}
.card-list-products {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 25px;
}
.card {
cursor: pointer;
}
.card-img {
background: transparent;
margin-bottom: 15px;
}
.card-img img {
height: 400px;
object-fit: cover;
box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.2);
}
.info-card {
display: flex;
justify-content: space-between;
}
.text-product {
color: #252525;
font-weight: 300;
line-height: 1.4;
}
.text-product h3{
color: inherit;
font-weight: inherit;
font-size: 15px;
}
.text-product h3:hover{
color: #1bbeb4;
}
.text-product p{
color: #666;
font-size: 13px;
}
.text-product p:hover{
color: #1bbeb4;
}
footer {
padding: 30px;
background-color: #eee;
margin-top: 50px;
color: #222;
}

View File

@ -0,0 +1,533 @@
import React, {useEffect, useState} from "react";
import { RiCustomerService2Fill } from "react-icons/ri";
import { FaUser } from "react-icons/fa";
import { LuShoppingBasket } from "react-icons/lu";
import { FaMagnifyingGlass } from "react-icons/fa6";
import { CiHeart } from "react-icons/ci";
import { FaRegEye } from "react-icons/fa";
import { CiShare2 } from "react-icons/ci";
import { useNavigate } from "react-router-dom";
import './ChocolateBlanco.css';
import Swal from 'sweetalert2'
import axios from 'axios';
import StarRatings from 'react-star-ratings';
function ChocolateBlanco() {
const navigate = useNavigate();
const [datosFormulario, setDatosFormulario] = useState(
{correo: '',
password: '',
nombre: ''
});
const redirectPersonalizarPastelArcoiris = () => {
// Redirige a la página del hotel cuando se hace clic en el botón
navigate("/PersonalizarPastel/PastelArcoiris");
};
const redirectToPedidos = () => {
navigate("/Pedidos");
};
const redirectToPasteles = () => {
navigate("/Pasteles");
};
const redirectInicio = () => {
// Redirige a la página del hotel cuando se hace clic en el botón
navigate("/");
};
const redirectToLogin = () => {
navigate("/Login");
};
const mostrarAlertaLogOut = () => {
Swal.fire({
title: "Cerrar Sesión",
text: "¿Seguro que quieres cerrar sesión?",
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: "Sesión cerrada correctamente. Adiós " + nombreUsuario + "",
icon: "success",
});
cerrarSesion();
}
});
};
const [nombreUsuario, setNombreUsuario]=useState("");
const obtenerNombreUsuario = async () => {
try {
// Realizar la llamada al backend para obtener el nombre del usuario
const response = await axios.post('http://localhost:4567/frontend/obtenerUsuario', { datosFormulario });
setNombreUsuario(response.data.nombre);
console.log(nombreUsuario);
} catch (error) {
// Manejar el error según tus necesidades
console.error("Error al obtener el nombre del usuario", error);
}
};
useEffect(() => {
// Llamar a la función al cargar la página
obtenerNombreUsuario();
obtenerReseñasPorPastel();
mostrarReseñas();
}, []);
const cerrarSesion = async () => {
try {
// Realizar la llamada al backend para obtener el nombre del usuario
const response = await axios.post('http://localhost:4567/frontend/cerrarSesion', { datosFormulario });
setNombreUsuario(response.data.nombre);
console.log(nombreUsuario);
obtenerNombreUsuario();
//mostrarAlertaLogOut();
} catch (error) {
// Manejar el error según tus necesidades
console.error("Error al obtener el nombre del usuario", error);
}
};
const mostrarAlertaReservaFallidaPers=()=>{
Swal.fire({
title: "Pedidos Info",
text: "No se encuentra disponible.",
icon: "info",
button: "Aceptar"
});
};
const mostrarAlertaReservaExitosa=()=>{
Swal.fire({
title: "Pedido Exitosa",
text: "Tu Pedido se ha realizado correctamente.",
icon: "success",
button: "Aceptar"
});
};
const hacerPedidoPastel1 = async () => {
try{
if(nombreUsuario==null){
mostrarAlertaPedidoFallidaLogin();
}else{
const response = await axios.post('http://localhost:4567/frontend/hacerPedidoPastel1', {
textoEncima: "",
textoCantidad: "8",
textoRelleno: "Confetti cake",
textoTipo: "Pastel Chocolate Blanco",
textoPrecio:"603",
idPastel: "2"
});
mostrarAlertaReservaExitosa();
}
}catch(error){
console.error("Error al hace el pedido");
throw error;
}
};
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 (
<h1 className="IniSesReserva">Inicia Sesión para poder ver las reseñas.</h1>
);
} else {
if (reseñas.length === 0) {
return (
<h1 className="ReseñaNull">No hay reseñas para este pastel en este momento.</h1>
);
} else {
return (
<div className="flex justify-center space-x-4">
{reseñas.map(reseña => (
<div key={reseña.idReseña} className="customer-review-card">
<div className="customer-review-info">
<img className="customer-review-avatar" src="https://placehold.co/100x100" />
<div>
<div className="customer-review-name">{reseña.nombreUsuario}</div>
</div>
</div>
<div className="customer-review-rating">
{"★".repeat(reseña.estrellas)}{"☆".repeat(5 - reseña.estrellas)}
</div>
<p className="customer-review-content">
{reseña.contenido}
</p>
</div>
))}
</div>
);
}
}
};
return (
<>
<header>
<div className="container-hero">
<div className="container hero">
<div className="customer-support">
<RiCustomerService2Fill className="icono-cliente" />
<div className="content-customer-support">
<span className="text">Soporte al cliente</span>
<span className="number">123-456-7890</span>
</div>
</div>
<div className="container-logo">
<i className="fa-solid fa-mug-hot"></i>
<h1 className="logo"><a href="/">Pasteleria RAPI</a></h1>
</div>
<div className="container-user">
<FaUser className="icono-User"/>
<div className="content-shopping-cart">
</div>
</div>
</div>
</div>
<div className="container-navbar">
<nav className="navbar container">
<i className="fa-solid fa-bars"></i>
<ul className="menu">
<li><a href="#" onClick={redirectInicio}>Inicio</a></li>
<li><a href="#" onClick={redirectToPasteles} >Pasteles</a></li>
<li><a href="#" onClick={redirectPersonalizarPastelArcoiris}>Personalizar Pastel</a></li>
<li><a href="/Pedidos" onClick={redirectToPedidos}>Pedidos</a></li>
<li><a href="#">Blog</a></li>
{nombreUsuario ? (
<>
<li className="enlaceNombre"><a href="#">{nombreUsuario}</a></li>
<li className="enlaceNombre2"><a href="#" onClick={mostrarAlertaLogOut}>Cerrar Sesión</a></li>
</>
) : (
<li className="enlaceNombre2"><a href="#" onClick={redirectToLogin}>Iniciar Sesión</a></li>
)
}
</ul>
<form className="search-form">
<input type="search" placeholder="Buscar..." />
<button className="btn-search">
<FaMagnifyingGlass className="icono-lupa" />
</button>
</form>
</nav>
</div>
</header>
<main className = "main-pers-pastel">
<div className="container-img-2" >
{}
</div>
<div className="container-info-product">
<div className="container-price">
<h1 className="titulo-Pastel">Pastel De Chocolate</h1>
<i className="fa-solid fa-angle-right"></i>
</div>
<div className="container-details-product">
<div className="form-group">
<div className="OpcionesPers">
<h2 className="textPersPastel">Precio:</h2><p className="pastel-Type1"><strong>$603</strong></p>
<h2 className="textPersPastel">Tamaño:</h2><p className="pastel-Type1"><strong>Grande</strong></p>
<h2 className="textPersPastel">Relleno:</h2><p className="pastel-Type1"><strong>Confetti cake</strong></p>
<div className="mb-4">
</div>
<div className="mb-6">
</div>
</div>
</div>
</div>
<div className="container-add-cart">
<button className="btn-add-to-cart" onClick={hacerPedidoPastel1}>
<i className="fa-solid fa-plus"></i>
Comprar
</button>
</div>
<div className="container-description">
<div className="title-description">
<h4>Descripción</h4>
<i className="fa-solid fa-chevron-down"></i>
</div>
<div className="text-description">
<p>
Este es un delicioso pastel de globo terráqueo de chocolate con glaseado de vainilla. El pastel es de un color marrón intenso y tiene una textura húmeda y densa. El glaseado de vainilla es cremoso y dulce, y la decoración del globo terráqueo con glaseado azul y verde añade un toque de creatividad y diversión.
</p>
</div>
</div>
<div className="container-additional-information">
<div className="title-additional-information">
<h4>Información adicional</h4>
<i className="fa-solid fa-chevron-down"></i>
</div>
<div className="text-additional-information hidden">
<p>-----------</p>
</div>
</div>
<div className="container-reviews">
<div className="title-reviews">
<h4>Reseñas</h4>
<i className="fa-solid fa-chevron-down"></i>
</div>
<div className="text-reviews hidden">
<p>-----------</p>
</div>
</div>
<div className="container-social">
<span>Compartir</span>
<div className="container-buttons-social">
<a href="#"><i className="fa-solid fa-envelope"></i></a>
<a href="#"><i className="fa-brands fa-facebook"></i></a>
<a href="#"><i className="fa-brands fa-twitter"></i></a>
<a href="#"><i className="fa-brands fa-instagram"></i></a>
<a href="#"><i className="fa-brands fa-pinterest"></i></a>
</div>
</div>
</div>
</main>
<div className="Reseñas">
<h2 className="customer-reviews-title">Reseñas</h2>
<div className="estrellas-reviews-container">
<h1>Calificación:</h1>
<StarRatings
rating={datosFormularioReseña.estrellas}
starRatedColor="#4b1e29"
starHoverColor="#8B374A"
changeRating={(newRating) => setDatosFormularioReseña({...datosFormularioReseña, estrellas: newRating})}
numberOfStars={5}
name='rating'
starDimension="30px"
/>
</div>
<div className="customer-reviews-container">
<div className="reseñas-conteiner">
<input className="input-reseñas"
type="text"
name="contenido"
value={datosFormularioReseña.contenido}
onChange={handleInputChange}
placeholder="Escribe tu reseña aquí"></input>
<button className="boton-reseñas" onClick={enviarReseña}>Enviar</button>
</div>
{mostrarReseñas()}
</div>
</div>
<footer className="footer">
<div className="container container-footer">
<div className="menu-footer">
<div className="contact-info">
<p className="title-footer">Información de Contacto</p>
<ul>
<li>
Avenida Xalapa
</li>
<li>Teléfono: 2288520821</li>
<li>EmaiL: cdgn_17@hotmail.com</li>
</ul>
<div className="social-icons">
<span className="facebook">
<i className="fa-brands fa-facebook-f"></i>
</span>
<span className="twitter">
<i className="fa-brands fa-twitter"></i>
</span>
<span className="youtube">
<i className="fa-brands fa-youtube"></i>
</span>
<span className="pinterest">
<i className="fa-brands fa-pinterest-p"></i>
</span>
<span className="instagram">
<i className="fa-brands fa-instagram"></i>
</span>
</div>
</div>
<div className="information">
<p className="title-footer">Información</p>
<ul>
<li><a href="#">Acerca de Nosotros</a></li>
<li><a href="#">Información de Entrega</a></li>
<li><a href="#">Politicas de Privacidad</a></li>
<li><a href="#">Términos y condiciones</a></li>
<li><a href="#">Contactános</a></li>
</ul>
</div>
<div className="my-account">
<p className="title-footer">Mi cuenta</p>
<ul>
<li><a href="#">Mi cuenta</a></li>
<li><a href="#">Pedidos</a></li>
<li><a href="#">Boletín</a></li>
</ul>
</div>
</div>
<div className="copyright">
</div>
</div>
</footer>
</>
);
}
export default ChocolateBlanco;

View File

@ -0,0 +1,514 @@
import React, {useEffect, useState} from "react";
import { RiCustomerService2Fill } from "react-icons/ri";
import { FaUser } from "react-icons/fa";
import { LuShoppingBasket } from "react-icons/lu";
import { FaMagnifyingGlass } from "react-icons/fa6";
import { CiHeart } from "react-icons/ci";
import { FaRegEye } from "react-icons/fa";
import { CiShare2 } from "react-icons/ci";
import { useNavigate } from "react-router-dom";
import './ChocolateBlanco.css';
import Swal from 'sweetalert2'
import axios from 'axios';
import StarRatings from 'react-star-ratings';
function PastelCajeta() {
const navigate = useNavigate();
const [datosFormulario, setDatosFormulario] = useState(
{correo: '',
password: '',
nombre: ''
});
const redirectPersonalizarPastelArcoiris = () => {
// Redirige a la página del hotel cuando se hace clic en el botón
navigate("/PersonalizarPastel/PastelArcoiris");
};
const redirectToPedidos = () => {
navigate("/Pedidos");
};
const redirectToPasteles = () => {
navigate("/Pasteles");
};
const redirectInicio = () => {
// Redirige a la página del hotel cuando se hace clic en el botón
navigate("/");
};
const redirectToLogin = () => {
navigate("/Login");
};
const mostrarAlertaLogOut = () => {
Swal.fire({
title: "Cerrar Sesión",
text: "¿Seguro que quieres cerrar sesión?",
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: "Sesión cerrada correctamente. Adiós " + nombreUsuario + "",
icon: "success",
});
cerrarSesion();
}
});
};
const [nombreUsuario, setNombreUsuario]=useState("");
const obtenerNombreUsuario = async () => {
try {
// Realizar la llamada al backend para obtener el nombre del usuario
const response = await axios.post('http://localhost:4567/frontend/obtenerUsuario', { datosFormulario });
setNombreUsuario(response.data.nombre);
console.log(nombreUsuario);
} catch (error) {
// Manejar el error según tus necesidades
console.error("Error al obtener el nombre del usuario", error);
}
};
useEffect(() => {
// Llamar a la función al cargar la página
obtenerNombreUsuario();
obtenerReseñasPorPastel();
mostrarReseñas();
}, []);
const cerrarSesion = async () => {
try {
// Realizar la llamada al backend para obtener el nombre del usuario
const response = await axios.post('http://localhost:4567/frontend/cerrarSesion', { datosFormulario });
setNombreUsuario(response.data.nombre);
console.log(nombreUsuario);
obtenerNombreUsuario();
//mostrarAlertaLogOut();
} catch (error) {
// Manejar el error según tus necesidades
console.error("Error al obtener el nombre del usuario", error);
}
};
const mostrarAlertaReservaFallidaPers=()=>{
Swal.fire({
title: "Pedidos Info",
text: "No se encuentra disponible.",
icon: "info",
button: "Aceptar"
});
};
const mostrarAlertaReservaExitosa=()=>{
Swal.fire({
title: "Pedido Exitosa",
text: "Tu Pedido se ha realizado correctamente.",
icon: "success",
button: "Aceptar"
});
};
const hacerPedidoPastel1 = async () => {
try{
if(nombreUsuario==null){
mostrarAlertaPedidoFallidaLogin();
}else{
const response = await axios.post('http://localhost:4567/frontend/hacerPedidoPastel1', {
textoEncima: "",
textoCantidad: "8",
textoRelleno: "Chocolate Fudge Cake",
textoTipo: "Pastel Cajeta",
textoPrecio:"390",
idPastel: "3"
});
mostrarAlertaReservaExitosa();
}
}catch(error){
console.error("Error al hace el pedido");
throw error;
}
};
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("3"); // 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: "3", // 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: "3",
});
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 (
<h1 className="IniSesReserva">Inicia Sesión para poder ver las reseñas.</h1>
);
} else {
if (reseñas.length === 0) {
return (
<h1 className="ReseñaNull">No hay reseñas para este pastel en este momento.</h1>
);
} else {
return (
<div className="flex justify-center space-x-4">
{reseñas.map(reseña => (
<div key={reseña.idReseña} className="customer-review-card">
<div className="customer-review-info">
<img className="customer-review-avatar" src="https://placehold.co/100x100" />
<div>
<div className="customer-review-name">{reseña.nombreUsuario}</div>
</div>
</div>
<div className="customer-review-rating">
{"★".repeat(reseña.estrellas)}{"☆".repeat(5 - reseña.estrellas)}
</div>
<p className="customer-review-content">
{reseña.contenido}
</p>
</div>
))}
</div>
);
}
}
};
return (
<>
<header>
<div className="container-hero">
<div className="container hero">
<div className="customer-support">
<RiCustomerService2Fill className="icono-cliente" />
<div className="content-customer-support">
<span className="text">Soporte al cliente</span>
<span className="number">123-456-7890</span>
</div>
</div>
<div className="container-logo">
<i className="fa-solid fa-mug-hot"></i>
<h1 className="logo"><a href="/">Pasteleria RAPI</a></h1>
</div>
<div className="container-user">
<FaUser className="icono-User"/>
<div className="content-shopping-cart">
</div>
</div>
</div>
</div>
<div className="container-navbar">
<nav className="navbar container">
<i className="fa-solid fa-bars"></i>
<ul className="menu">
<li><a href="#" onClick={redirectInicio}>Inicio</a></li>
<li><a href="#" onClick={redirectToPasteles} >Pasteles</a></li>
<li><a href="#" onClick={redirectPersonalizarPastelArcoiris}>Personalizar Pastel</a></li>
<li><a href="/Pedidos" onClick={redirectToPedidos}>Pedidos</a></li>
<li><a href="#">Blog</a></li>
{nombreUsuario ? (
<>
<li className="enlaceNombre"><a href="#">{nombreUsuario}</a></li>
<li className="enlaceNombre2"><a href="#" onClick={mostrarAlertaLogOut}>Cerrar Sesión</a></li>
</>
) : (
<li className="enlaceNombre2"><a href="#" onClick={redirectToLogin}>Iniciar Sesión</a></li>
)
}
</ul>
<form className="search-form">
<input type="search" placeholder="Buscar..." />
<button className="btn-search">
<FaMagnifyingGlass className="icono-lupa" />
</button>
</form>
</nav>
</div>
</header>
<main className = "main-pers-pastel">
<div className="container-img-7" >
{}
</div>
<div className="container-info-product">
<div className="container-price">
<h1 className="titulo-Pastel">Pastel De Cajeta</h1>
<i className="fa-solid fa-angle-right"></i>
</div>
<div className="container-details-product">
<div className="form-group">
<div className="OpcionesPers">
<h2 className="textPersPastel">Precio:</h2><p className="pastel-Type1"><strong>$390</strong></p>
<h2 className="textPersPastel">Tamaño:</h2><p className="pastel-Type1"><strong>Mediano</strong></p>
<h2 className="textPersPastel">Relleno:</h2><p className="pastel-Type1"><strong>Chocolate Fudge Cake</strong></p>
<div className="mb-4">
</div>
<div className="mb-6">
</div>
</div>
</div>
</div>
<div className="container-add-cart">
<button className="btn-add-to-cart" onClick={hacerPedidoPastel1}>
<i className="fa-solid fa-plus"></i>
Comprar
</button>
</div>
<div className="container-description">
<div className="title-description">
<h4>Descripción</h4>
<i className="fa-solid fa-chevron-down"></i>
</div>
<div className="text-description">
<p>
Este es un delicioso pastel de chocolate con ganache de chocolate y frambuesas. El pastel es de un color marrón intenso y tiene una textura húmeda y densa. El ganache de chocolate es cremoso y dulce, y las frambuesas frescas añaden un toque de acidez y color.
</p>
</div>
</div>
<div className="container-additional-information">
<div className="title-additional-information">
<h4>Información adicional</h4>
<i className="fa-solid fa-chevron-down"></i>
</div>
<div className="text-additional-information hidden">
<p>-----------</p>
</div>
</div>
<div className="container-reviews">
<div className="title-reviews">
<h4>Reseñas</h4>
<i className="fa-solid fa-chevron-down"></i>
</div>
<div className="text-reviews hidden">
<p>-----------</p>
</div>
</div>
</div>
</main>
<div className="Reseñas">
<h2 className="customer-reviews-title">Reseñas</h2>
<div className="estrellas-reviews-container">
<h1>Calificación:</h1>
<StarRatings
rating={datosFormularioReseña.estrellas}
starRatedColor="#4b1e29"
starHoverColor="#8B374A"
changeRating={(newRating) => setDatosFormularioReseña({...datosFormularioReseña, estrellas: newRating})}
numberOfStars={5}
name='rating'
starDimension="30px"
/>
</div>
<div className="customer-reviews-container">
<div className="reseñas-conteiner">
<input className="input-reseñas"
type="text"
name="contenido"
value={datosFormularioReseña.contenido}
onChange={handleInputChange}
placeholder="Escribe tu reseña aquí"></input>
<button className="boton-reseñas" onClick={enviarReseña}>Enviar</button>
</div>
{mostrarReseñas()}
</div>
</div>
<footer className="footer">
<div className="container container-footer">
<div className="menu-footer">
<div className="contact-info">
<p className="title-footer">Información de Contacto</p>
<ul>
<li>
Avenida Xalapa
</li>
<li>Teléfono: 2288520821</li>
<li>EmaiL: cdgn_17@hotmail.com</li>
</ul>
<div className="social-icons">
<span className="facebook">
<i className="fa-brands fa-facebook-f"></i>
</span>
<span className="twitter">
<i className="fa-brands fa-twitter"></i>
</span>
<span className="youtube">
<i className="fa-brands fa-youtube"></i>
</span>
<span className="pinterest">
<i className="fa-brands fa-pinterest-p"></i>
</span>
<span className="instagram">
<i className="fa-brands fa-instagram"></i>
</span>
</div>
</div>
<div className="information">
<p className="title-footer">Información</p>
<ul>
<li><a href="#">Acerca de Nosotros</a></li>
<li><a href="#">Información de Entrega</a></li>
<li><a href="#">Politicas de Privacidad</a></li>
<li><a href="#">Términos y condiciones</a></li>
<li><a href="#">Contactános</a></li>
</ul>
</div>
<div className="my-account">
<p className="title-footer">Mi cuenta</p>
<ul>
<li><a href="#">Mi cuenta</a></li>
<li><a href="#">Pedidos</a></li>
<li><a href="#">Boletín</a></li>
</ul>
</div>
</div>
<div className="copyright">
</div>
</div>
</footer>
</>
);
}
export default PastelCajeta;

View File

@ -0,0 +1,520 @@
import React, {useEffect, useState} from "react";
import { RiCustomerService2Fill } from "react-icons/ri";
import { FaUser } from "react-icons/fa";
import { LuShoppingBasket } from "react-icons/lu";
import { FaMagnifyingGlass } from "react-icons/fa6";
import { CiHeart } from "react-icons/ci";
import { FaRegEye } from "react-icons/fa";
import { CiShare2 } from "react-icons/ci";
import { useNavigate } from "react-router-dom";
import './ChocolateBlanco.css';
import Swal from 'sweetalert2'
import axios from 'axios';
import StarRatings from 'react-star-ratings';
function PastelChocolate() {
const navigate = useNavigate();
const [datosFormulario, setDatosFormulario] = useState(
{correo: '',
password: '',
nombre: ''
});
const redirectPersonalizarPastelArcoiris = () => {
// Redirige a la página del hotel cuando se hace clic en el botón
navigate("/PersonalizarPastel/PastelArcoiris");
};
const redirectToPedidos = () => {
navigate("/Pedidos");
};
const redirectToPasteles = () => {
navigate("/Pasteles");
};
const redirectInicio = () => {
// Redirige a la página del hotel cuando se hace clic en el botón
navigate("/");
};
const redirectToLogin = () => {
navigate("/Login");
};
const mostrarAlertaLogOut = () => {
Swal.fire({
title: "Cerrar Sesión",
text: "¿Seguro que quieres cerrar sesión?",
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: "Sesión cerrada correctamente. Adiós " + nombreUsuario + "",
icon: "success",
});
cerrarSesion();
}
});
};
const [nombreUsuario, setNombreUsuario]=useState("");
const obtenerNombreUsuario = async () => {
try {
// Realizar la llamada al backend para obtener el nombre del usuario
const response = await axios.post('http://localhost:4567/frontend/obtenerUsuario', { datosFormulario });
setNombreUsuario(response.data.nombre);
console.log(nombreUsuario);
} catch (error) {
// Manejar el error según tus necesidades
console.error("Error al obtener el nombre del usuario", error);
}
};
useEffect(() => {
// Llamar a la función al cargar la página
obtenerNombreUsuario();
obtenerReseñasPorPastel();
mostrarReseñas();
}, []);
const cerrarSesion = async () => {
try {
// Realizar la llamada al backend para obtener el nombre del usuario
const response = await axios.post('http://localhost:4567/frontend/cerrarSesion', { datosFormulario });
setNombreUsuario(response.data.nombre);
console.log(nombreUsuario);
obtenerNombreUsuario();
//mostrarAlertaLogOut();
} catch (error) {
// Manejar el error según tus necesidades
console.error("Error al obtener el nombre del usuario", error);
}
};
const mostrarAlertaReservaFallidaPers=()=>{
Swal.fire({
title: "Pedidos Info",
text: "No se encuentra disponible.",
icon: "info",
button: "Aceptar"
});
};
const mostrarAlertaReservaExitosa=()=>{
Swal.fire({
title: "Pedido Exitosa",
text: "Tu Pedido se ha realizado correctamente.",
icon: "success",
button: "Aceptar"
});
};
const hacerPedidoPastel1 = async () => {
try{
if(nombreUsuario==null){
mostrarAlertaPedidoFallidaLogin();
}else{
const response = await axios.post('http://localhost:4567/frontend/hacerPedidoPastel1', {
textoEncima: "",
textoCantidad: "8",
textoRelleno: "Chocolate Fudge Cake",
textoTipo: "Pastel de Chocolate",
textoPrecio:"350",
idPastel: "5"
});
mostrarAlertaReservaExitosa();
}
}catch(error){
console.error("Error al hace el pedido");
throw error;
}
};
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("5"); // 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: "5", // 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: "5",
});
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 (
<h1 className="IniSesReserva">Inicia Sesión para poder ver las reseñas.</h1>
);
} else {
if (reseñas.length === 0) {
return (
<h1 className="ReseñaNull">No hay reseñas para este pastel en este momento.</h1>
);
} else {
return (
<div className="flex justify-center space-x-4">
{reseñas.map(reseña => (
<div key={reseña.idReseña} className="customer-review-card">
<div className="customer-review-info">
<img className="customer-review-avatar" src="https://placehold.co/100x100" />
<div>
<div className="customer-review-name">{reseña.nombreUsuario}</div>
</div>
</div>
<div className="customer-review-rating">
{"★".repeat(reseña.estrellas)}{"☆".repeat(5 - reseña.estrellas)}
</div>
<p className="customer-review-content">
{reseña.contenido}
</p>
</div>
))}
</div>
);
}
}
};
return (
<>
<header>
<div className="container-hero">
<div className="container hero">
<div className="customer-support">
<RiCustomerService2Fill className="icono-cliente" />
<div className="content-customer-support">
<span className="text">Soporte al cliente</span>
<span className="number">123-456-7890</span>
</div>
</div>
<div className="container-logo">
<i className="fa-solid fa-mug-hot"></i>
<h1 className="logo"><a href="/">Pasteleria RAPI</a></h1>
</div>
<div className="container-user">
<FaUser className="icono-User"/>
<div className="content-shopping-cart">
</div>
</div>
</div>
</div>
<div className="container-navbar">
<nav className="navbar container">
<i className="fa-solid fa-bars"></i>
<ul className="menu">
<li><a href="#" onClick={redirectInicio}>Inicio</a></li>
<li><a href="#" onClick={redirectToPasteles} >Pasteles</a></li>
<li><a href="#" onClick={redirectPersonalizarPastelArcoiris}>Personalizar Pastel</a></li>
<li><a href="/Pedidos" onClick={redirectToPedidos}>Pedidos</a></li>
<li><a href="#">Blog</a></li>
{nombreUsuario ? (
<>
<li className="enlaceNombre"><a href="#">{nombreUsuario}</a></li>
<li className="enlaceNombre2"><a href="#" onClick={mostrarAlertaLogOut}>Cerrar Sesión</a></li>
</>
) : (
<li className="enlaceNombre2"><a href="#" onClick={redirectToLogin}>Iniciar Sesión</a></li>
)
}
</ul>
<form className="search-form">
<input type="search" placeholder="Buscar..." />
<button className="btn-search">
<FaMagnifyingGlass className="icono-lupa" />
</button>
</form>
</nav>
</div>
</header>
<main className = "main-pers-pastel">
<div className="container-img-4" >
</div>
<div className="container-info-product">
<div className="container-price">
<h1 className="titulo-Pastel">Pastel De Chocolate</h1>
<i className="fa-solid fa-angle-right"></i>
</div>
<div className="container-details-product">
<div className="form-group">
<div className="OpcionesPers">
<h2 className="textPersPastel">Precio:</h2><p className="pastel-Type1"><strong>$350</strong></p>
<h2 className="textPersPastel">Tamaño:</h2><p className="pastel-Type1"><strong>Mediano</strong></p>
<h2 className="textPersPastel">Relleno:</h2><p className="pastel-Type1"><strong>Chocolate Fudge Cake</strong></p>
<div className="mb-4">
</div>
<div className="mb-6">
</div>
</div>
</div>
</div>
<div className="container-add-cart">
<button className="btn-add-to-cart" onClick={hacerPedidoPastel1}>
<i className="fa-solid fa-plus"></i>
Comprar
</button>
</div>
<div className="container-description">
<div className="title-description">
<h4>Descripción</h4>
<i className="fa-solid fa-chevron-down"></i>
</div>
<div className="text-description">
<p>
Este es un delicioso pastel de chocolate con frosting de chocolate y bolitas de chocolate. El pastel es de un color marrón intenso y tiene una textura húmeda y densa. El frosting de chocolate es cremoso y dulce, y las bolitas de chocolate añaden un toque de textura y sabor.
</p>
</div>
</div>
<div className="container-additional-information">
<div className="title-additional-information">
<h4>Información adicional</h4>
<i className="fa-solid fa-chevron-down"></i>
</div>
<div className="text-additional-information hidden">
<p>-----------</p>
</div>
</div>
<div className="container-reviews">
<div className="title-reviews">
<h4>Reseñas</h4>
<i className="fa-solid fa-chevron-down"></i>
</div>
<div className="text-reviews hidden">
<p>-----------</p>
</div>
</div>
</div>
</main>
<div className="Reseñas">
<h2 className="customer-reviews-title">Reseñas</h2>
<div className="estrellas-reviews-container">
<h1>Calificación:</h1>
<StarRatings
rating={datosFormularioReseña.estrellas}
starRatedColor="#4b1e29"
starHoverColor="#8B374A"
changeRating={(newRating) => setDatosFormularioReseña({...datosFormularioReseña, estrellas: newRating})}
numberOfStars={5}
name='rating'
starDimension="30px"
/>
</div>
<div className="customer-reviews-container">
<div className="reseñas-conteiner">
<input className="input-reseñas"
type="text"
name="contenido"
value={datosFormularioReseña.contenido}
onChange={handleInputChange}
placeholder="Escribe tu reseña aquí"></input>
<button className="boton-reseñas" onClick={enviarReseña}>Enviar</button>
</div>
{mostrarReseñas()}
</div>
</div>
<footer className="footer">
<div className="container container-footer">
<div className="menu-footer">
<div className="contact-info">
<p className="title-footer">Información de Contacto</p>
<ul>
<li>
Avenida Xalapa
</li>
<li>Teléfono: 2288520821</li>
<li>EmaiL: cdgn_17@hotmail.com</li>
</ul>
<div className="social-icons">
<span className="facebook">
<i className="fa-brands fa-facebook-f"></i>
</span>
<span className="twitter">
<i className="fa-brands fa-twitter"></i>
</span>
<span className="youtube">
<i className="fa-brands fa-youtube"></i>
</span>
<span className="pinterest">
<i className="fa-brands fa-pinterest-p"></i>
</span>
<span className="instagram">
<i className="fa-brands fa-instagram"></i>
</span>
</div>
</div>
<div className="information">
<p className="title-footer">Información</p>
<ul>
<li><a href="#">Acerca de Nosotros</a></li>
<li><a href="#">Información de Entrega</a></li>
<li><a href="#">Politicas de Privacidad</a></li>
<li><a href="#">Términos y condiciones</a></li>
<li><a href="#">Contactános</a></li>
</ul>
</div>
<div className="my-account">
<p className="title-footer">Mi cuenta</p>
<ul>
<li><a href="#">Mi cuenta</a></li>
<li><a href="#">Pedidos</a></li>
<li><a href="#">Boletín</a></li>
</ul>
</div>
</div>
<div className="copyright">
</div>
</div>
</footer>
</>
);
}
export default PastelChocolate;

View File

@ -0,0 +1,520 @@
import React, {useEffect, useState} from "react";
import { RiCustomerService2Fill } from "react-icons/ri";
import { FaUser } from "react-icons/fa";
import { LuShoppingBasket } from "react-icons/lu";
import { FaMagnifyingGlass } from "react-icons/fa6";
import { CiHeart } from "react-icons/ci";
import { FaRegEye } from "react-icons/fa";
import { CiShare2 } from "react-icons/ci";
import { useNavigate } from "react-router-dom";
import './ChocolateBlanco.css';
import Swal from 'sweetalert2'
import axios from 'axios';
import StarRatings from 'react-star-ratings';
function PastelFrambuesa() {
const navigate = useNavigate();
const [datosFormulario, setDatosFormulario] = useState(
{correo: '',
password: '',
nombre: ''
});
const redirectPersonalizarPastelArcoiris = () => {
// Redirige a la página del hotel cuando se hace clic en el botón
navigate("/PersonalizarPastel/PastelArcoiris");
};
const redirectToPedidos = () => {
navigate("/Pedidos");
};
const redirectToPasteles = () => {
navigate("/Pasteles");
};
const redirectInicio = () => {
// Redirige a la página del hotel cuando se hace clic en el botón
navigate("/");
};
const redirectToLogin = () => {
navigate("/Login");
};
const mostrarAlertaLogOut = () => {
Swal.fire({
title: "Cerrar Sesión",
text: "¿Seguro que quieres cerrar sesión?",
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: "Sesión cerrada correctamente. Adiós " + nombreUsuario + "",
icon: "success",
});
cerrarSesion();
}
});
};
const [nombreUsuario, setNombreUsuario]=useState("");
const obtenerNombreUsuario = async () => {
try {
// Realizar la llamada al backend para obtener el nombre del usuario
const response = await axios.post('http://localhost:4567/frontend/obtenerUsuario', { datosFormulario });
setNombreUsuario(response.data.nombre);
console.log(nombreUsuario);
} catch (error) {
// Manejar el error según tus necesidades
console.error("Error al obtener el nombre del usuario", error);
}
};
useEffect(() => {
// Llamar a la función al cargar la página
obtenerNombreUsuario();
obtenerReseñasPorPastel();
mostrarReseñas();
}, []);
const cerrarSesion = async () => {
try {
// Realizar la llamada al backend para obtener el nombre del usuario
const response = await axios.post('http://localhost:4567/frontend/cerrarSesion', { datosFormulario });
setNombreUsuario(response.data.nombre);
console.log(nombreUsuario);
obtenerNombreUsuario();
//mostrarAlertaLogOut();
} catch (error) {
// Manejar el error según tus necesidades
console.error("Error al obtener el nombre del usuario", error);
}
};
const mostrarAlertaReservaFallidaPers=()=>{
Swal.fire({
title: "Pedidos Info",
text: "No se encuentra disponible.",
icon: "info",
button: "Aceptar"
});
};
const mostrarAlertaReservaExitosa=()=>{
Swal.fire({
title: "Pedido Exitosa",
text: "Tu Pedido se ha realizado correctamente.",
icon: "success",
button: "Aceptar"
});
};
const hacerPedidoPastel1 = async () => {
try{
if(nombreUsuario==null){
mostrarAlertaPedidoFallidaLogin();
}else{
const response = await axios.post('http://localhost:4567/frontend/hacerPedidoPastel1', {
textoEncima: "",
textoCantidad: "12",
textoRelleno: "Vanilla Rainbow Cake",
textoTipo: "Pastel Frambuesa",
textoPrecio:"500",
idPastel: "7"
});
mostrarAlertaReservaExitosa();
}
}catch(error){
console.error("Error al hace el pedido");
throw error;
}
};
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("7"); // 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: "7", // 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: "7",
});
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 (
<h1 className="IniSesReserva">Inicia Sesión para poder ver las reseñas.</h1>
);
} else {
if (reseñas.length === 0) {
return (
<h1 className="ReseñaNull">No hay reseñas para este pastel en este momento.</h1>
);
} else {
return (
<div className="flex justify-center space-x-4">
{reseñas.map(reseña => (
<div key={reseña.idReseña} className="customer-review-card">
<div className="customer-review-info">
<img className="customer-review-avatar" src="https://placehold.co/100x100" />
<div>
<div className="customer-review-name">{reseña.nombreUsuario}</div>
</div>
</div>
<div className="customer-review-rating">
{"★".repeat(reseña.estrellas)}{"☆".repeat(5 - reseña.estrellas)}
</div>
<p className="customer-review-content">
{reseña.contenido}
</p>
</div>
))}
</div>
);
}
}
};
return (
<>
<header>
<div className="container-hero">
<div className="container hero">
<div className="customer-support">
<RiCustomerService2Fill className="icono-cliente" />
<div className="content-customer-support">
<span className="text">Soporte al cliente</span>
<span className="number">123-456-7890</span>
</div>
</div>
<div className="container-logo">
<i className="fa-solid fa-mug-hot"></i>
<h1 className="logo"><a href="/">Pasteleria RAPI</a></h1>
</div>
<div className="container-user">
<FaUser className="icono-User"/>
<div className="content-shopping-cart">
</div>
</div>
</div>
</div>
<div className="container-navbar">
<nav className="navbar container">
<i className="fa-solid fa-bars"></i>
<ul className="menu">
<li><a href="#" onClick={redirectInicio}>Inicio</a></li>
<li><a href="#" onClick={redirectToPasteles} >Pasteles</a></li>
<li><a href="#" onClick={redirectPersonalizarPastelArcoiris}>Personalizar Pastel</a></li>
<li><a href="/Pedidos" onClick={redirectToPedidos}>Pedidos</a></li>
<li><a href="#">Blog</a></li>
{nombreUsuario ? (
<>
<li className="enlaceNombre"><a href="#">{nombreUsuario}</a></li>
<li className="enlaceNombre2"><a href="#" onClick={mostrarAlertaLogOut}>Cerrar Sesión</a></li>
</>
) : (
<li className="enlaceNombre2"><a href="#" onClick={redirectToLogin}>Iniciar Sesión</a></li>
)
}
</ul>
<form className="search-form">
<input type="search" placeholder="Buscar..." />
<button className="btn-search">
<FaMagnifyingGlass className="icono-lupa" />
</button>
</form>
</nav>
</div>
</header>
<main className = "main-pers-pastel">
<div className="container-img-6" >
{}
</div>
<div className="container-info-product">
<div className="container-price">
<h1 className="titulo-Pastel">Pastel De Frambuesa</h1>
<i className="fa-solid fa-angle-right"></i>
</div>
<div className="container-details-product">
<div className="form-group">
<div className="OpcionesPers">
<h2 className="textPersPastel">Precio:</h2><p className="pastel-Type1"><strong>$500</strong></p>
<h2 className="textPersPastel">Tamaño:</h2><p className="pastel-Type1"><strong>Grande</strong></p>
<h2 className="textPersPastel">Relleno:</h2><p className="pastel-Type1"><strong>Vanilla Rainbow Cake</strong></p>
<div className="mb-4">
</div>
<div className="mb-6">
</div>
</div>
</div>
</div>
<div className="container-add-cart">
<button className="btn-add-to-cart" onClick={hacerPedidoPastel1}>
<i className="fa-solid fa-plus"></i>
Comprar
</button>
</div>
<div className="container-description">
<div className="title-description">
<h4>Descripción</h4>
<i className="fa-solid fa-chevron-down"></i>
</div>
<div className="text-description">
<p>
Este es un delicioso pastel de terciopelo rojo con glaseado blanco y chispas. El pastel es de un color rojo intenso y tiene una textura suave y húmeda. El glaseado blanco es cremoso y dulce, y las chispas añaden un toque de color y diversión.
</p>
</div>
</div>
<div className="container-additional-information">
<div className="title-additional-information">
<h4>Información adicional</h4>
<i className="fa-solid fa-chevron-down"></i>
</div>
<div className="text-additional-information hidden">
<p>-----------</p>
</div>
</div>
<div className="container-reviews">
<div className="title-reviews">
<h4>Reseñas</h4>
<i className="fa-solid fa-chevron-down"></i>
</div>
<div className="text-reviews hidden">
<p>-----------</p>
</div>
</div>
</div>
</main>
<div className="Reseñas">
<h2 className="customer-reviews-title">Reseñas</h2>
<div className="estrellas-reviews-container">
<h1>Calificación:</h1>
<StarRatings
rating={datosFormularioReseña.estrellas}
starRatedColor="#4b1e29"
starHoverColor="#8B374A"
changeRating={(newRating) => setDatosFormularioReseña({...datosFormularioReseña, estrellas: newRating})}
numberOfStars={5}
name='rating'
starDimension="30px"
/>
</div>
<div className="customer-reviews-container">
<div className="reseñas-conteiner">
<input className="input-reseñas"
type="text"
name="contenido"
value={datosFormularioReseña.contenido}
onChange={handleInputChange}
placeholder="Escribe tu reseña aquí"></input>
<button className="boton-reseñas" onClick={enviarReseña}>Enviar</button>
</div>
{mostrarReseñas()}
</div>
</div>
<footer className="footer">
<div className="container container-footer">
<div className="menu-footer">
<div className="contact-info">
<p className="title-footer">Información de Contacto</p>
<ul>
<li>
Avenida Xalapa
</li>
<li>Teléfono: 2288520821</li>
<li>EmaiL: cdgn_17@hotmail.com</li>
</ul>
<div className="social-icons">
<span className="facebook">
<i className="fa-brands fa-facebook-f"></i>
</span>
<span className="twitter">
<i className="fa-brands fa-twitter"></i>
</span>
<span className="youtube">
<i className="fa-brands fa-youtube"></i>
</span>
<span className="pinterest">
<i className="fa-brands fa-pinterest-p"></i>
</span>
<span className="instagram">
<i className="fa-brands fa-instagram"></i>
</span>
</div>
</div>
<div className="information">
<p className="title-footer">Información</p>
<ul>
<li><a href="#">Acerca de Nosotros</a></li>
<li><a href="#">Información de Entrega</a></li>
<li><a href="#">Politicas de Privacidad</a></li>
<li><a href="#">Términos y condiciones</a></li>
<li><a href="#">Contactános</a></li>
</ul>
</div>
<div className="my-account">
<p className="title-footer">Mi cuenta</p>
<ul>
<li><a href="#">Mi cuenta</a></li>
<li><a href="#">Pedidos</a></li>
<li><a href="#">Boletín</a></li>
</ul>
</div>
</div>
<div className="copyright">
</div>
</div>
</footer>
</>
);
}
export default PastelFrambuesa;

514
src/Pasteles/PastelMoka.jsx Normal file
View File

@ -0,0 +1,514 @@
import React, {useEffect, useState} from "react";
import { RiCustomerService2Fill } from "react-icons/ri";
import { FaUser } from "react-icons/fa";
import { LuShoppingBasket } from "react-icons/lu";
import { FaMagnifyingGlass } from "react-icons/fa6";
import { CiHeart } from "react-icons/ci";
import { FaRegEye } from "react-icons/fa";
import { CiShare2 } from "react-icons/ci";
import { useNavigate } from "react-router-dom";
import Swal from 'sweetalert2'
import axios from 'axios';
import StarRatings from 'react-star-ratings';
function PastelMoka() {
const navigate = useNavigate();
const [datosFormulario, setDatosFormulario] = useState(
{correo: '',
password: '',
nombre: ''
});
const redirectPersonalizarPastelArcoiris = () => {
// Redirige a la página del hotel cuando se hace clic en el botón
navigate("/PersonalizarPastel/PastelArcoiris");
};
const redirectToPedidos = () => {
navigate("/Pedidos");
};
const redirectToPasteles = () => {
navigate("/Pasteles");
};
const redirectInicio = () => {
// Redirige a la página del hotel cuando se hace clic en el botón
navigate("/");
};
const redirectToLogin = () => {
navigate("/Login");
};
const mostrarAlertaLogOut = () => {
Swal.fire({
title: "Cerrar Sesión",
text: "¿Seguro que quieres cerrar sesión?",
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: "Sesión cerrada correctamente. Adiós " + nombreUsuario + "",
icon: "success",
});
cerrarSesion();
}
});
};
const [nombreUsuario, setNombreUsuario]=useState("");
const obtenerNombreUsuario = async () => {
try {
// Realizar la llamada al backend para obtener el nombre del usuario
const response = await axios.post('http://localhost:4567/frontend/obtenerUsuario', { datosFormulario });
setNombreUsuario(response.data.nombre);
console.log(nombreUsuario);
} catch (error) {
// Manejar el error según tus necesidades
console.error("Error al obtener el nombre del usuario", error);
}
};
useEffect(() => {
// Llamar a la función al cargar la página
obtenerNombreUsuario();
obtenerReseñasPorPastel();
mostrarReseñas();
}, []);
const cerrarSesion = async () => {
try {
// Realizar la llamada al backend para obtener el nombre del usuario
const response = await axios.post('http://localhost:4567/frontend/cerrarSesion', { datosFormulario });
setNombreUsuario(response.data.nombre);
console.log(nombreUsuario);
obtenerNombreUsuario();
//mostrarAlertaLogOut();
} catch (error) {
// Manejar el error según tus necesidades
console.error("Error al obtener el nombre del usuario", error);
}
};
const mostrarAlertaReservaFallidaPers=()=>{
Swal.fire({
title: "Pedidos Info",
text: "No se encuentra disponible.",
icon: "info",
button: "Aceptar"
});
};
const mostrarAlertaReservaExitosa=()=>{
Swal.fire({
title: "Pedido Exitosa",
text: "Tu Pedido se ha realizado correctamente.",
icon: "success",
button: "Aceptar"
});
};
const hacerPedidoPastel1 = async () => {
try{
if(nombreUsuario==null){
mostrarAlertaPedidoFallidaLogin();
}else{
const response = await axios.post('http://localhost:4567/frontend/hacerPedidoPastel1', {
textoEncima: "",
textoCantidad: "8",
textoRelleno: "Vanilla Rainbow Cake",
textoTipo: "Pastel de Moka",
textoPrecio:"560",
idPastel: "4"
});
mostrarAlertaReservaExitosa();
}
}catch(error){
console.error("Error al hace el pedido");
throw error;
}
};
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("4"); // 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: "4", // 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: "4",
});
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 (
<h1 className="IniSesReserva">Inicia Sesión para poder ver las reseñas.</h1>
);
} else {
if (reseñas.length === 0) {
return (
<h1 className="ReseñaNull">No hay reseñas para este pastel en este momento.</h1>
);
} else {
return (
<div className="flex justify-center space-x-4">
{reseñas.map(reseña => (
<div key={reseña.idReseña} className="customer-review-card">
<div className="customer-review-info">
<img className="customer-review-avatar" src="https://placehold.co/100x100" />
<div>
<div className="customer-review-name">{reseña.nombreUsuario}</div>
</div>
</div>
<div className="customer-review-rating">
{"★".repeat(reseña.estrellas)}{"☆".repeat(5 - reseña.estrellas)}
</div>
<p className="customer-review-content">
{reseña.contenido}
</p>
</div>
))}
</div>
);
}
}
};
return (
<>
<header>
<div className="container-hero">
<div className="container hero">
<div className="customer-support">
<RiCustomerService2Fill className="icono-cliente" />
<div className="content-customer-support">
<span className="text">Soporte al cliente</span>
<span className="number">123-456-7890</span>
</div>
</div>
<div className="container-logo">
<i className="fa-solid fa-mug-hot"></i>
<h1 className="logo"><a href="/">Pasteleria RAPI</a></h1>
</div>
<div className="container-user">
<FaUser className="icono-User"/>
<div className="content-shopping-cart">
</div>
</div>
</div>
</div>
<div className="container-navbar">
<nav className="navbar container">
<i className="fa-solid fa-bars"></i>
<ul className="menu">
<li><a href="#" onClick={redirectInicio}>Inicio</a></li>
<li><a href="#" onClick={redirectToPasteles} >Pasteles</a></li>
<li><a href="#" onClick={redirectPersonalizarPastelArcoiris}>Personalizar Pastel</a></li>
<li><a href="/Pedidos" onClick={redirectToPedidos}>Pedidos</a></li>
<li><a href="#">Blog</a></li>
{nombreUsuario ? (
<>
<li className="enlaceNombre"><a href="#">{nombreUsuario}</a></li>
<li className="enlaceNombre2"><a href="#" onClick={mostrarAlertaLogOut}>Cerrar Sesión</a></li>
</>
) : (
<li className="enlaceNombre2"><a href="#" onClick={redirectToLogin}>Iniciar Sesión</a></li>
)
}
</ul>
<form className="search-form">
<input type="search" placeholder="Buscar..." />
<button className="btn-search">
<FaMagnifyingGlass className="icono-lupa" />
</button>
</form>
</nav>
</div>
</header>
<main className = "main-pers-pastel">
<div className="container-img-3" >
</div>
<div className="container-info-product">
<div className="container-price">
<h1 className="titulo-Pastel">Pastel De Moka</h1>
<i className="fa-solid fa-angle-right"></i>
</div>
<div className="container-details-product">
<div className="form-group">
<div className="OpcionesPers">
<h2 className="textPersPastel">Precio:</h2><p className="pastel-Type1"><strong>$560</strong></p>
<h2 className="textPersPastel">Tamaño:</h2><p className="pastel-Type1"><strong>Mediano</strong></p>
<h2 className="textPersPastel">Relleno:</h2><p className="pastel-Type1"><strong>Vanilla Rainbow Cake</strong></p>
<div className="mb-4">
</div>
<div className="mb-6">
</div>
</div>
</div>
</div>
<div className="container-add-cart">
<button className="btn-add-to-cart" onClick={hacerPedidoPastel1}>
<i className="fa-solid fa-plus"></i>
Comprar
</button>
</div>
<div className="container-description">
<div className="title-description">
<h4>Descripción</h4>
<i className="fa-solid fa-chevron-down"></i>
</div>
<div className="text-description">
<p>
Este es un delicioso pastel de chocolate con ganache de chocolate. El pastel es de un color marrón intenso y tiene una textura húmeda y densa. El ganache de chocolate es cremoso y dulce, y la decoración con frutas frescas añade un toque de frescura y color.
</p>
</div>
</div>
<div className="container-additional-information">
<div className="title-additional-information">
<h4>Información adicional</h4>
<i className="fa-solid fa-chevron-down"></i>
</div>
<div className="text-additional-information hidden">
<p>-----------</p>
</div>
</div>
<div className="container-reviews">
<div className="title-reviews">
<h4>Reseñas</h4>
<i className="fa-solid fa-chevron-down"></i>
</div>
<div className="text-reviews hidden">
<p>-----------</p>
</div>
</div>
</div>
</main>
<div className="Reseñas">
<h2 className="customer-reviews-title">Reseñas</h2>
<div className="estrellas-reviews-container">
<h1>Calificación:</h1>
<StarRatings
rating={datosFormularioReseña.estrellas}
starRatedColor="#4b1e29"
starHoverColor="#8B374A"
changeRating={(newRating) => setDatosFormularioReseña({...datosFormularioReseña, estrellas: newRating})}
numberOfStars={5}
name='rating'
starDimension="30px"
/>
</div>
<div className="customer-reviews-container">
<div className="reseñas-conteiner">
<input className="input-reseñas"
type="text"
name="contenido"
value={datosFormularioReseña.contenido}
onChange={handleInputChange}
placeholder="Escribe tu reseña aquí"></input>
<button className="boton-reseñas" onClick={enviarReseña}>Enviar</button>
</div>
{mostrarReseñas()}
</div>
</div>
<footer className="footer">
<div className="container container-footer">
<div className="menu-footer">
<div className="contact-info">
<p className="title-footer">Información de Contacto</p>
<ul>
<li>
Avenida Xalapa
</li>
<li>Teléfono: 2288520821</li>
<li>EmaiL: cdgn_17@hotmail.com</li>
</ul>
<div className="social-icons">
<span className="facebook">
<i className="fa-brands fa-facebook-f"></i>
</span>
<span className="twitter">
<i className="fa-brands fa-twitter"></i>
</span>
<span className="youtube">
<i className="fa-brands fa-youtube"></i>
</span>
<span className="pinterest">
<i className="fa-brands fa-pinterest-p"></i>
</span>
<span className="instagram">
<i className="fa-brands fa-instagram"></i>
</span>
</div>
</div>
<div className="information">
<p className="title-footer">Información</p>
<ul>
<li><a href="#">Acerca de Nosotros</a></li>
<li><a href="#">Información de Entrega</a></li>
<li><a href="#">Politicas de Privacidad</a></li>
<li><a href="#">Términos y condiciones</a></li>
<li><a href="#">Contactános</a></li>
</ul>
</div>
<div className="my-account">
<p className="title-footer">Mi cuenta</p>
<ul>
<li><a href="#">Mi cuenta</a></li>
<li><a href="#">Pedidos</a></li>
<li><a href="#">Boletín</a></li>
</ul>
</div>
</div>
<div className="copyright">
</div>
</div>
</footer>
</>
);
}
export default PastelMoka;

View File

@ -0,0 +1,519 @@
import React, {useEffect, useState} from "react";
import { RiCustomerService2Fill } from "react-icons/ri";
import { FaUser } from "react-icons/fa";
import { LuShoppingBasket } from "react-icons/lu";
import { FaMagnifyingGlass } from "react-icons/fa6";
import { CiHeart } from "react-icons/ci";
import { FaRegEye } from "react-icons/fa";
import { CiShare2 } from "react-icons/ci";
import { useNavigate } from "react-router-dom";
import './ChocolateBlanco.css';
import Swal from 'sweetalert2'
import axios from 'axios';
import StarRatings from 'react-star-ratings';
function PastelZanahoria() {
const navigate = useNavigate();
const [datosFormulario, setDatosFormulario] = useState(
{correo: '',
password: '',
nombre: ''
});
const redirectPersonalizarPastelArcoiris = () => {
// Redirige a la página del hotel cuando se hace clic en el botón
navigate("/PersonalizarPastel/PastelArcoiris");
};
const redirectToPedidos = () => {
navigate("/Pedidos");
};
const redirectToPasteles = () => {
navigate("/Pasteles");
};
const redirectInicio = () => {
// Redirige a la página del hotel cuando se hace clic en el botón
navigate("/");
};
const redirectToLogin = () => {
navigate("/Login");
};
const mostrarAlertaLogOut = () => {
Swal.fire({
title: "Cerrar Sesión",
text: "¿Seguro que quieres cerrar sesión?",
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: "Sesión cerrada correctamente. Adiós " + nombreUsuario + "",
icon: "success",
});
cerrarSesion();
}
});
};
const [nombreUsuario, setNombreUsuario]=useState("");
const obtenerNombreUsuario = async () => {
try {
// Realizar la llamada al backend para obtener el nombre del usuario
const response = await axios.post('http://localhost:4567/frontend/obtenerUsuario', { datosFormulario });
setNombreUsuario(response.data.nombre);
console.log(nombreUsuario);
} catch (error) {
// Manejar el error según tus necesidades
console.error("Error al obtener el nombre del usuario", error);
}
};
useEffect(() => {
// Llamar a la función al cargar la página
obtenerNombreUsuario();
obtenerReseñasPorPastel();
mostrarReseñas();
}, []);
const cerrarSesion = async () => {
try {
// Realizar la llamada al backend para obtener el nombre del usuario
const response = await axios.post('http://localhost:4567/frontend/cerrarSesion', { datosFormulario });
setNombreUsuario(response.data.nombre);
console.log(nombreUsuario);
obtenerNombreUsuario();
//mostrarAlertaLogOut();
} catch (error) {
// Manejar el error según tus necesidades
console.error("Error al obtener el nombre del usuario", error);
}
};
const mostrarAlertaReservaFallidaPers=()=>{
Swal.fire({
title: "Pedidos Info",
text: "No se encuentra disponible.",
icon: "info",
button: "Aceptar"
});
};
const mostrarAlertaReservaExitosa=()=>{
Swal.fire({
title: "Pedido Exitosa",
text: "Tu Pedido se ha realizado correctamente.",
icon: "success",
button: "Aceptar"
});
};
const hacerPedidoPastel1 = async () => {
try{
if(nombreUsuario==null){
mostrarAlertaPedidoFallidaLogin();
}else{
const response = await axios.post('http://localhost:4567/frontend/hacerPedidoPastel1', {
textoEncima: "",
textoCantidad: "8",
textoRelleno: "Vanilla Rainbow Cake",
textoTipo: "Pastel de Zanahoria",
textoPrecio:"450",
idPastel: "6"
});
mostrarAlertaReservaExitosa();
}
}catch(error){
console.error("Error al hace el pedido");
throw error;
}
};
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("6"); // 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: "6", // 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: "6",
});
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 (
<h1 className="IniSesReserva">Inicia Sesión para poder ver las reseñas.</h1>
);
} else {
if (reseñas.length === 0) {
return (
<h1 className="ReseñaNull">No hay reseñas para este pastel en este momento.</h1>
);
} else {
return (
<div className="flex justify-center space-x-4">
{reseñas.map(reseña => (
<div key={reseña.idReseña} className="customer-review-card">
<div className="customer-review-info">
<img className="customer-review-avatar" src="https://placehold.co/100x100" />
<div>
<div className="customer-review-name">{reseña.nombreUsuario}</div>
</div>
</div>
<div className="customer-review-rating">
{"★".repeat(reseña.estrellas)}{"☆".repeat(5 - reseña.estrellas)}
</div>
<p className="customer-review-content">
{reseña.contenido}
</p>
</div>
))}
</div>
);
}
}
};
return (
<>
<header>
<div className="container-hero">
<div className="container hero">
<div className="customer-support">
<RiCustomerService2Fill className="icono-cliente" />
<div className="content-customer-support">
<span className="text">Soporte al cliente</span>
<span className="number">123-456-7890</span>
</div>
</div>
<div className="container-logo">
<i className="fa-solid fa-mug-hot"></i>
<h1 className="logo"><a href="/">Pasteleria RAPI</a></h1>
</div>
<div className="container-user">
<FaUser className="icono-User"/>
<div className="content-shopping-cart">
</div>
</div>
</div>
</div>
<div className="container-navbar">
<nav className="navbar container">
<i className="fa-solid fa-bars"></i>
<ul className="menu">
<li><a href="#" onClick={redirectInicio}>Inicio</a></li>
<li><a href="#" onClick={redirectToPasteles} >Pasteles</a></li>
<li><a href="#" onClick={redirectPersonalizarPastelArcoiris}>Personalizar Pastel</a></li>
<li><a href="/Pedidos" onClick={redirectToPedidos}>Pedidos</a></li>
<li><a href="#">Blog</a></li>
{nombreUsuario ? (
<>
<li className="enlaceNombre"><a href="#">{nombreUsuario}</a></li>
<li className="enlaceNombre2"><a href="#" onClick={mostrarAlertaLogOut}>Cerrar Sesión</a></li>
</>
) : (
<li className="enlaceNombre2"><a href="#" onClick={redirectToLogin}>Iniciar Sesión</a></li>
)
}
</ul>
<form className="search-form">
<input type="search" placeholder="Buscar..." />
<button className="btn-search">
<FaMagnifyingGlass className="icono-lupa" />
</button>
</form>
</nav>
</div>
</header>
<main className = "main-pers-pastel">
<div className="container-img-5" >
{}
</div>
<div className="container-info-product">
<div className="container-price">
<h1 className="titulo-Pastel">Pastel De Zanahoria</h1>
<i className="fa-solid fa-angle-right"></i>
</div>
<div className="container-details-product">
<div className="form-group">
<div className="OpcionesPers">
<h2 className="textPersPastel">Precio:</h2><p className="pastel-Type1"><strong>$450</strong></p>
<h2 className="textPersPastel">Tamaño:</h2><p className="pastel-Type1"><strong>Chico</strong></p>
<h2 className="textPersPastel">Relleno:</h2><p className="pastel-Type1"><strong>Vanilla Rainbow Cake</strong></p>
<div className="mb-4">
</div>
<div className="mb-6">
</div>
</div>
</div>
</div>
<div className="container-add-cart">
<button className="btn-add-to-cart" onClick={hacerPedidoPastel1}>
<i className="fa-solid fa-plus"></i>
Comprar
</button>
</div>
<div className="container-description">
<div className="title-description">
<h4>Descripción</h4>
<i className="fa-solid fa-chevron-down"></i>
</div>
<div className="text-description">
<p>
Este es un delicioso pastel de zanahoria con queso crema y nueces picadas. El pastel es de un color naranja intenso y tiene una textura húmeda y densa. El queso crema es cremoso y dulce, y las nueces picadas añaden un toque de textura y sabor.
</p>
</div>
</div>
<div className="container-additional-information">
<div className="title-additional-information">
<h4>Información adicional</h4>
<i className="fa-solid fa-chevron-down"></i>
</div>
<div className="text-additional-information hidden">
<p>-----------</p>
</div>
</div>
<div className="container-reviews">
<div className="title-reviews">
<h4>Reseñas</h4>
<i className="fa-solid fa-chevron-down"></i>
</div>
<div className="text-reviews hidden">
<p>-----------</p>
</div>
</div>
</div>
</main>
<div className="Reseñas">
<h2 className="customer-reviews-title">Reseñas</h2>
<div className="estrellas-reviews-container">
<h1>Calificación:</h1>
<StarRatings
rating={datosFormularioReseña.estrellas}
starRatedColor="#4b1e29"
starHoverColor="#8B374A"
changeRating={(newRating) => setDatosFormularioReseña({...datosFormularioReseña, estrellas: newRating})}
numberOfStars={5}
name='rating'
starDimension="30px"
/>
</div>
<div className="customer-reviews-container">
<div className="reseñas-conteiner">
<input className="input-reseñas"
type="text"
name="contenido"
value={datosFormularioReseña.contenido}
onChange={handleInputChange}
placeholder="Escribe tu reseña aquí"></input>
<button className="boton-reseñas" onClick={enviarReseña}>Enviar</button>
</div>
{mostrarReseñas()}
</div>
</div>
<footer className="footer">
<div className="container container-footer">
<div className="menu-footer">
<div className="contact-info">
<p className="title-footer">Información de Contacto</p>
<ul>
<li>
Avenida Xalapa
</li>
<li>Teléfono: 2288520821</li>
<li>EmaiL: cdgn_17@hotmail.com</li>
</ul>
<div className="social-icons">
<span className="facebook">
<i className="fa-brands fa-facebook-f"></i>
</span>
<span className="twitter">
<i className="fa-brands fa-twitter"></i>
</span>
<span className="youtube">
<i className="fa-brands fa-youtube"></i>
</span>
<span className="pinterest">
<i className="fa-brands fa-pinterest-p"></i>
</span>
<span className="instagram">
<i className="fa-brands fa-instagram"></i>
</span>
</div>
</div>
<div className="information">
<p className="title-footer">Información</p>
<ul>
<li><a href="#">Acerca de Nosotros</a></li>
<li><a href="#">Información de Entrega</a></li>
<li><a href="#">Politicas de Privacidad</a></li>
<li><a href="#">Términos y condiciones</a></li>
<li><a href="#">Contactános</a></li>
</ul>
</div>
<div className="my-account">
<p className="title-footer">Mi cuenta</p>
<ul>
<li><a href="#">Mi cuenta</a></li>
<li><a href="#">Pedidos</a></li>
<li><a href="#">Boletín</a></li>
</ul>
</div>
</div>
<div className="copyright">
</div>
</div>
</footer>
</>
);
}
export default PastelZanahoria;

174
src/Pedidos.css Normal file
View File

@ -0,0 +1,174 @@
.content-card-product h3:hover {
color: var(--primary-color);
}
.add-cart {
justify-self: start;
border: 2px solid var(--primary-color);
padding: 1rem;
border-radius: 50%;
cursor: pointer;
transition: all 0.4s ease;
display: flex;
align-items: center;
justify-content: center;
}
.add-cart:hover {
background-color: var(--primary-color);
}
.add-cart i {
font-size: 1.5rem;
color: var(--primary-color);
}
.add-cart:hover i {
color: #fff;
}
.content-card-product .price {
justify-self: end;
align-self: center;
font-size: 1.7rem;
font-weight: 600;
}
.content-card-product .price span {
font-size: 1.5rem;
font-weight: 400;
text-decoration: line-through;
color: #777;
margin-left: 0.5rem;
}
/* ************* ICONOS ************* */
.icono-cliente {
font-size: 4rem; /* Cambia el tamaño del icono ajustando el valor de '2rem' según sea necesario */
align-items: center;
text-align: left;
color:var(--primary-color)
}
.icono-User {
font-size: 4rem; /* Cambia el tamaño del icono ajustando el valor de '2rem' según sea necesario */
align-items: center;
text-align: left;
color:var(--primary-color)
}
.icono-basket {
font-size: 4.5rem; /* Cambia el tamaño del icono ajustando el valor de '2rem' según sea necesario */
align-items: center;
text-align: left;
color:var(--primary-color)
}
.icono-lupa{
font-size: 2rem; /* Cambia el tamaño del icono ajustando el valor de '2rem' según sea necesario */
align-items: center;
text-align: left;
color: white;
}
.icono-basket-card{
font-size: 2.5rem; /* Cambia el tamaño del icono ajustando el valor de '2rem' según sea necesario */
align-items: center;
text-align: left;
color:var(--primary-color)
}
/* Estilos del contenedor principal de reservaciones */
#contenedor_reservaciones {
display: flex;
flex-wrap: wrap;
justify-content: space-around;
padding-top: 10px;
}
/* Estilos de cada tarjeta de reservación */
.reservacion {
display: flex; /* Añadir esta propiedad para usar flexbox */
width: 700px;
gap: 1.5rem;
height: 230px;
margin: 20px;
padding: 15px;
border: 1px solid #ccc;
border-radius: 10px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
background-color: #fff;
}
/* Estilos para la imagen */
.imagenPastel {
width: 300px;
height: 100%; /* Ajustar al 100% del contenedor padre */
object-fit: cover;
background-repeat: no-repeat;
background-size: 100% auto;
border-radius: 8px; /* Añadir bordes redondeados solo a la izquierda */
}
/* Estilos para el texto */
.reservaData {
width: 50%;
padding: 0 15px; /* Agregar relleno solo a los lados */
}
.reservacion h3 {
margin-top: 10px;
font-size: 18px;
}
.reservacion p {
margin: 8px 0;
}
/* Estilos del botón Eliminar Reservación */
.eliminar-btn {
background-color: #8B374A;
color: #fff;
border: none;
padding: 8px 16px;
border-radius: 5px;
cursor: pointer;
}
.eliminar-btn:hover {
background-color: #ff4646;
}
.eliminar-btn:hover {
background-color: #4b1e29; /* Cambia el color al pasar el cursor sobre el botón */
}
.IniSesReserva{
padding-top: 2rem;
padding-bottom: 10px;
border-bottom: 1px solid #e4e4e4;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 24px;
font-weight: 300;
}
.ReservaNull{
padding-top: 2rem;
padding-bottom: 10px;
border-bottom: 1px solid #e4e4e4;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 24px;
font-weight: 300;
}

404
src/Pedidos.jsx Normal file
View File

@ -0,0 +1,404 @@
import { useState, useEffect } from 'react';
import './Pedidos.css';
import viteLogo from '/vite.svg'
import Edicion1 from './assets/Edicion21.jpg';
import Edicion12 from './assets/Edicion12.jpg';
import Edicion13 from './assets/Edicion13.jpg';
import Edicion14 from './assets/Edicion14.jpg';
import Edicion15 from './assets/Edicion15.jpg';
import Edicion16 from './assets/Edicion16.jpg';
import otra_imagen from './assets/Edicion2.jpg';
import { RiCustomerService2Fill } from "react-icons/ri";
import { FaUser } from "react-icons/fa";
import { LuShoppingBasket } from "react-icons/lu";
import { FaMagnifyingGlass } from "react-icons/fa6";
import { CiHeart } from "react-icons/ci";
import { FaRegEye } from "react-icons/fa";
import { CiShare2 } from "react-icons/ci";
import { useNavigate } from "react-router-dom";
import axios from "axios";
//imagenes de pastel de fresas
import pastel_fresa_original from "./assets/Pastel-fresa-original.png";
import pastel_fresa_arcoiris from "./assets/Pastel-fresas-arcoiris.png";
import pastel_fresa_oreo from "./assets/Pastel-fresas-oreo.png";
import pastel_fresa_vainilla from "./assets/Pastel-fresas-vainilla.png";
import Swal from 'sweetalert2';
import pastelZarza from "./assets/pastel-zarza.jpg"
function Pedidos() {
const [count, setCount] = useState(0);
const navigate = useNavigate();
const [pedidosDePasteles, setPedidosDePasteles] = useState([]);
const [datosFormulario, setDatosFormulario] = useState(
{correo: '',
password: '',
nombre: ''
});
const mostrarAlertaLogOut = () => {
Swal.fire({
title: "Cerrar Sesión",
text: "¿Seguro que quieres cerrar sesión?",
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: "Sesión cerrada correctamente. Adiós " + nombreUsuario + "",
icon: "success",
});
cerrarSesion();
}
});
};
const [nombreUsuario, setNombreUsuario]=useState("");
const obtenerNombreUsuario = async () => {
try {
// Realizar la llamada al backend para obtener el nombre del usuario
const response = await axios.post('http://localhost:4567/frontend/obtenerUsuario', { datosFormulario });
setNombreUsuario(response.data.nombre);
console.log(nombreUsuario);
console.log("hola"+ datosFormulario.nombre);
} catch (error) {
// Manejar el error según tus necesidades
console.error("Error al obtener el nombre del usuario", error);
}
};
useEffect(() => {
// Llamar a la función al cargar la página
obtenerNombreUsuario();
obtenerPedidosDePasteles();
console.log("obtuvo los pedidos");
}, []);
const cerrarSesion = async () => {
try {
// Realizar la llamada al backend para obtener el nombre del usuario
const response = await axios.post('http://localhost:4567/frontend/cerrarSesion', { datosFormulario });
setNombreUsuario(response.data.nombre);
console.log(nombreUsuario);
obtenerNombreUsuario();
//mostrarAlertaLogOut();
} catch (error) {
// Manejar el error según tus necesidades
console.error("Error al obtener el nombre del usuario", error);
}
};
const mostrarAlertaPedidoFallidaLogin=()=>{
Swal.fire({
title: "Pedido Fallida",
text: "Inicia Sesion para poder hacer un pedido.",
icon: "error",
button: "Aceptar"
});
};
const obtenerPedidosDePasteles = async () => {
try {
const response = await axios.post('http://localhost:4567/frontend/obtenerPedidosDePasteles');
console.log("Pedidos de pasteles obtenidos:", response.data.pedidos_de_pasteles);
// Almacena los pedidos de pasteles en el estado
setPedidosDePasteles(response.data.pedidos_de_pasteles);
} catch (error) {
console.error("Error al obtener pedidos de pasteles:", error);
}
};
const redirectPersonalizarPastelArcoiris = () => {
// Redirige a la página del hotel cuando se hace clic en el botón
navigate("/PersonalizarPastel/PastelArcoiris");
};
const redirectInicio = () => {
// Redirige a la página del hotel cuando se hace clic en el botón
navigate("/");
};
const redirectToLogin = () => {
navigate("/Login");
};
const redirectToPedidos = () => {
navigate("/Pedidos");
};
const redirectToPasteles = () => {
navigate("/Pasteles");
};
const mostrarAlertaEliminarPedido = (idPedido, nombPastel, status) => {
if (status === "listo para entregar") {
Swal.fire({
title: "No se puede eliminar",
text: `El pedido del ${nombPastel} ya está listo para entregar y no se puede eliminar.`,
icon: "info",
confirmButtonText: "Entendido",
});
} else {
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 [pedidos, setPedidos] = useState([]);
const generarPedidos = () => {
if (nombreUsuario == null) {
return (
<h1 className="IniSesReserva">Inicia Sesión para poder ver tus pedidos de pasteles.</h1>
);
} else {
if (pedidosDePasteles.length === 0) {
return (
<h1 className="ReservaNull">No tienes pedidos de pasteles en este momento.</h1>
);
} else {
return (
<div>
{pedidosDePasteles.map(pedido => (
<div key={pedido.id_pedido} className="reservacion">
<div className='container-img-pedido'>
{pedido.nombre_pastel === 'Pastel de Fresas' ? (
pedido.relleno === 'Original' ? <img src={pastel_fresa_original} alt="" className="imagenPastel" /> :
pedido.relleno === 'Arcoiris' ? <img src={pastel_fresa_arcoiris} alt="" className="imagenPastel" /> :
pedido.relleno === 'Oreo' ? <img src={pastel_fresa_oreo} alt="" className="imagenPastel" /> :
pedido.relleno === 'Vainilla' ? <img src={pastel_fresa_vainilla} alt="" className="imagenPastel" /> :
<img src={otra_imagen} alt="" className="imagenPastel" /> // Si el relleno no coincide con ninguno de los anteriores
) : pedido.nombre_pastel === 'Pastel Chocolate Blanco' ? (
<img src={Edicion1} alt="" className="imagenPastel" />
) : pedido.nombre_pastel === 'Pastel Cajeta' ? (
<img src={Edicion16} alt="" className="imagenPastel" />
): pedido.nombre_pastel === 'Pastel de Chocolate' ? (
<img src={Edicion13} alt="" className="imagenPastel" />
): pedido.nombre_pastel === 'Pastel Frambuesa' ? (
<img src={Edicion15} alt="" className="imagenPastel" />
) : pedido.nombre_pastel === 'Pastel de Moka' ? (
<img src={Edicion12} alt="" className="imagenPastel" />
) : pedido.nombre_pastel === 'Pastel de Zanahoria' ? (
<img src={Edicion14} alt="" className="imagenPastel" />
):(
<img src={otra_imagen} alt="" className="imagenPastel" /> // Si el pastel no es de fresas ni de chocolate blanco
)}
</div>
<div className="reservaData">
<h3>{pedido.nombre_pastel}</h3>
<p>Precio del pastel: ${pedido.precio}</p>
<p>Tamaño: {pedido.tamaño}</p>
<p>Estatus: {pedido.estatus}</p>
<p>Inscripción: {pedido.inscripcion}</p>
<p>Relleno: {pedido.relleno}</p>
<button className="eliminar-btn" onClick={() => mostrarAlertaEliminarPedido(pedido.id_pedido, pedido.nombre_pastel,pedido.estatus)}>
Eliminar Pedido
</button>
</div>
</div>
))}
</div>
);
}
}
};
return (
<>
<body>
<header>
<div className="container-hero">
<div className="container hero">
<div className="customer-support">
<RiCustomerService2Fill className="icono-cliente" />
<div className="content-customer-support">
<span className="text">Soporte al cliente</span>
<span className="number">123-456-7890</span>
</div>
</div>
<div className="container-logo">
<i className="fa-solid fa-mug-hot"></i>
<h1 className="logo"><a href="/">Pasteleria RAPI</a></h1>
</div>
<div className="container-user">
<FaUser className="icono-User"/>
<div className="content-shopping-cart">
</div>
</div>
</div>
</div>
<div className="container-navbar">
<nav className="navbar container">
<i className="fa-solid fa-bars"></i>
<ul className="menu">
<li><a href="#" onClick={redirectInicio}>Inicio</a></li>
<li><a href="#" onClick={redirectToPasteles} >Pasteles</a></li>
<li><a href="#" onClick={redirectPersonalizarPastelArcoiris}>Personalizar Pastel</a></li>
<li><a href="/Pedidos" onClick={redirectToPedidos}>Pedidos</a></li>
<li><a href="#">Blog</a></li>
{nombreUsuario ? (
<>
<li className="enlaceNombre"><a href="#">{nombreUsuario}</a></li>
<li className="enlaceNombre2"><a href="#" onClick={mostrarAlertaLogOut}>Cerrar Sesión</a></li>
</>
) : (
<li className="enlaceNombre2"><a href="#" onClick={redirectToLogin}>Iniciar Sesión</a></li>
)
}
</ul>
<form className="search-form">
<input type="search" placeholder="Buscar..." />
<button className="btn-search">
<FaMagnifyingGlass className="icono-lupa" />
</button>
</form>
</nav>
</div>
</header>
<main className="main-pedidos">
<div id="contenedor_reservaciones">
{generarPedidos()}
</div>
</main>
<footer className="footer">
<div className="container container-footer">
<div className="menu-footer">
<div className="contact-info">
<p className="title-footer">Información de Contacto</p>
<ul>
<li>
Avenida Xalapa
</li>
<li>Teléfono: 2288520821</li>
<li>EmaiL: cdgn_17@hotmail.com</li>
</ul>
<div className="social-icons">
<span className="facebook">
<i className="fa-brands fa-facebook-f"></i>
</span>
<span className="twitter">
<i className="fa-brands fa-twitter"></i>
</span>
<span className="youtube">
<i className="fa-brands fa-youtube"></i>
</span>
<span className="pinterest">
<i className="fa-brands fa-pinterest-p"></i>
</span>
<span className="instagram">
<i className="fa-brands fa-instagram"></i>
</span>
</div>
</div>
<div className="information">
<p className="title-footer">Información</p>
<ul>
<li><a href="#">Acerca de Nosotros</a></li>
<li><a href="#">Información de Entrega</a></li>
<li><a href="#">Politicas de Privacidad</a></li>
<li><a href="#">Términos y condiciones</a></li>
<li><a href="#">Contactános</a></li>
</ul>
</div>
<div className="my-account">
<p className="title-footer">Mi cuenta</p>
<ul>
<li><a href="#">Mi cuenta</a></li>
<li><a href="#">Pedidos</a></li>
<li><a href="#">Boletín</a></li>
</ul>
</div>
</div>
<div className="copyright">
</div>
</div>
</footer>
</body>
</>
)
}
export default Pedidos

710
src/PersPastel1.jsx Normal file
View File

@ -0,0 +1,710 @@
import React, { useState, useEffect } from "react";
import './PersPastelStyle.css';
import { Button, Select, MenuItem, TextField, Box } from '@mui/material';
import StarRatings from 'react-star-ratings';
import { RiCustomerService2Fill } from "react-icons/ri";
import { FaUser } from "react-icons/fa";
import { LuShoppingBasket } from "react-icons/lu";
import { FaMagnifyingGlass } from "react-icons/fa6";
import { CiHeart } from "react-icons/ci";
import { FaRegEye } from "react-icons/fa";
import { CiShare2 } from "react-icons/ci";
import { useNavigate } from "react-router-dom";
import axios from 'axios';
import pastel_fresa_original from "./assets/Pastel-fresa-original.png";
import pastel_fresa_arcoiris from "./assets/Pastel-fresas-arcoiris.png";
import pastel_fresa_oreo from "./assets/Pastel-fresas-oreo.png";
import pastel_fresa_vainilla from "./assets/Pastel-fresas-vainilla.png";
import Swal from 'sweetalert2'
import pastelTexto from "./assets/pastel-texto.jpg"
function Pastel() {
const navigate = useNavigate();
const [quantity, setQuantity] = useState(1);
const [textoEncima, setTextoEncima] = useState("");
const [textoCantidad, setTextoCantidad] = useState("");
const [textoRelleno, setTextoRelleno] = useState("");
const [textoTipo, setTextoTipo] = useState("");
const [textoPrecio, setTextoPrecio] = useState("");
const [datosPastel, setDatosPastel] = useState(
{
texto: '',
quantity: 1
});
const [datosPastelEnviar, setDatosPastelEnviar] = useState(
{
texto: textoEncima,
quantity: datosPastel.quantity
});
const [datosFormulario, setDatosFormulario] = useState(
{correo: '',
password: '',
nombre: ''
});
const redirectPersonalizarPastelArcoiris = () => {
// Redirige a la página del hotel cuando se hace clic en el botón
navigate("/PersonalizarPastel/PastelArcoiris");
};
const redirectInicio = () => {
// Redirige a la página del hotel cuando se hace clic en el botón
navigate("/");
};
const redirectToLogin = () => {
navigate("/Login");
};
const redirectToPedidos = () => {
navigate("/Pedidos");
};
const redirectToPasteles = () => {
navigate("/Pasteles");
};
const [lastSelectedImage, setLastSelectedImage] = useState(pastel_fresa_original);
const [imagenVisible, setImagenVisible] = useState(pastel_fresa_original);
const [inputActivo, setInputActivo] = useState(false);
const cambiarImagenBoton = (nuevaImagen) => {
if (!inputActivo) {
setImagenVisible(nuevaImagen);
setLastSelectedImage(nuevaImagen);
}
};
const handleChange = (event) => {
setImagenVisible(pastelTexto);
setDatosPastel(prevState => ({
...prevState, // Clona el estado actual
texto: event.target.value, // Establece el campo 'correo' con el valor del evento
}));
};
const handleInputFocus = () => {
console.log(textoEncima);
setDatosPastel(prevState => ({
...prevState, // Clona el estado actual
texto: textoEncima, // Establece el campo 'correo' con el valor del evento
}));
//console.log("hola");
setImagenVisible(pastelTexto);
};
const handleInputBlur = () => {
setTextoEncima(datosPastel.texto);
console.log(textoEncima);
setDatosPastel(prevState => ({
...prevState, // Clona el estado actual
texto: "", // Establece el campo 'correo' con el valor del evento
}));
setImagenVisible(lastSelectedImage);
};
const handleDocumentClick = (event) => {
// Comprueba si el clic ocurrió fuera del input
if (!event.target.matches("#inscription")) {
}
};
const mostrarAlertaLogOut = () => {
Swal.fire({
title: "Cerrar Sesión",
text: "¿Seguro que quieres cerrar sesión?",
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: "Sesión cerrada correctamente. Adiós " + nombreUsuario + "",
icon: "success",
});
cerrarSesion();
}
});
};
const [nombreUsuario, setNombreUsuario]=useState("");
const obtenerNombreUsuario = async () => {
try {
// Realizar la llamada al backend para obtener el nombre del usuario
const response = await axios.post('http://localhost:4567/frontend/obtenerUsuario', { datosFormulario });
setNombreUsuario(response.data.nombre);
console.log(nombreUsuario);
console.log("hola"+ datosFormulario.nombre);
} catch (error) {
// Manejar el error según tus necesidades
console.error("Error al obtener el nombre del usuario", error);
}
};
useEffect(() => {
// Llamar a la función al cargar la página
obtenerNombreUsuario();
obtenerReseñasPorPastel();
mostrarReseñas();
setTextoRelleno("Original");
document.addEventListener("click", handleDocumentClick);
return () => {
document.removeEventListener("click", handleDocumentClick);
};
}, []);
const cerrarSesion = async () => {
try {
// Realizar la llamada al backend para obtener el nombre del usuario
const response = await axios.post('http://localhost:4567/frontend/cerrarSesion', { datosFormulario });
setNombreUsuario(response.data.nombre);
console.log(nombreUsuario);
obtenerNombreUsuario();
//mostrarAlertaLogOut();
} catch (error) {
// Manejar el error según tus necesidades
console.error("Error al obtener el nombre del usuario", error);
}
};
const mostrarAlertaPedidoFallidaLogin=()=>{
Swal.fire({
title: "Pedido Fallida",
text: "Inicia Sesion para poder hacer un pedido.",
icon: "error",
button: "Aceptar"
});
}
const handleIncrement = () => {
setQuantity((prevQuantity) => prevQuantity + 1);
};
const handleDecrement = () => {
setQuantity((prevQuantity) => (prevQuantity > 1 ? prevQuantity - 1 : 1));
};
const mostrarAlertaReservaFallidaPers=()=>{
Swal.fire({
title: "Pedidos Info",
text: "Solo hay pasteles de hasta 12 personas.",
icon: "info",
button: "Aceptar"
});
};
const mostrarAlertaReservaExitosa=()=>{
Swal.fire({
title: "Pedido Exitoso",
text: "Tu Pedido se ha realizado correctamente.",
icon: "success",
button: "Aceptar"
});
};
const handleQuantityChange = (value) => {
if (value >= 1 && value <= 12) {
setQuantity(value);
setDatosPastel((prevData) => ({ ...prevData, quantity: value }));
} else {
mostrarAlertaReservaFallidaPers();
}
};
const clickBotonOriginal = () => {
cambiarImagenBoton(pastel_fresa_original);
setTextoRelleno("Original");
};
const clickBotonArcoiris = () => {
cambiarImagenBoton(pastel_fresa_arcoiris);
setTextoRelleno("Arcoiris");
};
const clickBotonOreo = () => {
cambiarImagenBoton(pastel_fresa_oreo);
setTextoRelleno("Oreo");
};
const clickBotonVainilla = () => {
cambiarImagenBoton(pastel_fresa_vainilla);
setTextoRelleno("Vainilla");
};
const hacerPedidoPastel1 = async () => {
console.log("Fresas");
console.log(datosPastel.quantity);
console.log(textoEncima);
console.log(textoRelleno);
try{
if(nombreUsuario==null){
mostrarAlertaPedidoFallidaLogin();
}else{
const response = await axios.post('http://localhost:4567/frontend/hacerPedidoPastel1', {
textoEncima: textoEncima,
textoCantidad: datosPastel.quantity,
textoRelleno: textoRelleno,
textoTipo: "Pastel de Fresas",
textoPrecio:"1000",
idPastel: "1"
});
console.log(response.data);
mostrarAlertaReservaExitosa();
// Limpiar los estados después de hacer el pedido
setDatosPastel({ texto: "", quantity: 1 });
setTextoEncima("");
setTextoCantidad("");
setTextoRelleno("Original");
setTextoTipo("");
setDatosPastel({ texto: "", quantity: 1 });
setQuantity(1);
cambiarImagenBoton(pastel_fresa_original);
}
}catch(error){
console.error("Error al hace el pedido");
throw error;
}
};
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("1"); // 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: "1", // 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: "1",
});
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 (
<h1 className="IniSesReserva">Inicia Sesión para poder ver las reseñas.</h1>
);
} else {
if (reseñas.length === 0) {
return (
<h1 className="ReseñaNull">No hay reseñas para este pastel en este momento.</h1>
);
} else {
return (
<div className="flex justify-center space-x-4">
{reseñas.map(reseña => (
<div key={reseña.idReseña} className="customer-review-card">
<div className="customer-review-info">
<img className="customer-review-avatar" src="https://placehold.co/100x100" />
<div>
<div className="customer-review-name">{reseña.nombreUsuario}</div>
</div>
</div>
<div className="customer-review-rating">
{"★".repeat(reseña.estrellas)}{"☆".repeat(5 - reseña.estrellas)}
</div>
<p className="customer-review-content">
{reseña.contenido}
</p>
</div>
))}
</div>
);
}
}
};
return (
<>
<header>
<div className="container-hero">
<div className="container hero">
<div className="customer-support">
<RiCustomerService2Fill className="icono-cliente" />
<div className="content-customer-support">
<span className="text">Soporte al cliente</span>
<span className="number">123-456-7890</span>
</div>
</div>
<div className="container-logo">
<i className="fa-solid fa-mug-hot"></i>
<h1 className="logo"><a href="/">Pasteleria RAPI</a></h1>
</div>
<div className="container-user">
<FaUser className="icono-User"/>
<div className="content-shopping-cart">
</div>
</div>
</div>
</div>
<div className="container-navbar">
<nav className="navbar container">
<i className="fa-solid fa-bars"></i>
<ul className="menu">
<li><a href="#" onClick={redirectInicio}>Inicio</a></li>
<li><a href="#" onClick={redirectToPasteles} >Pasteles</a></li>
<li><a href="#" onClick={redirectPersonalizarPastelArcoiris}>Personalizar Pastel</a></li>
<li><a href="/Pedidos" onClick={redirectToPedidos}>Pedidos</a></li>
<li><a href="#">Blog</a></li>
{nombreUsuario ? (
<>
<li className="enlaceNombre"><a href="#">{nombreUsuario}</a></li>
<li className="enlaceNombre2"><a href="#" onClick={mostrarAlertaLogOut}>Cerrar Sesión</a></li>
</>
) : (
<li className="enlaceNombre2"><a href="#" onClick={redirectToLogin}>Iniciar Sesión</a></li>
)
}
</ul>
<form className="search-form">
<input type="search" placeholder="Buscar..." />
<button className="btn-search">
<FaMagnifyingGlass className="icono-lupa" />
</button>
</form>
</nav>
</div>
</header>
<main className = "main-pers-pastel">
<div className="container-img-1">
<img className="imgPastel" src={imagenVisible} alt="Pastel"></img>
<div className="texto-encima">{datosPastel.texto}</div>
</div>
<div className="container-info-product">
<div className="container-price">
<span>Pastel de Fresas</span>
<i className="fa-solid fa-angle-right"></i>
</div>
<div className="container-details-product">
<div className="form-group">
<div className="OpcionesPers">
<h2 className="textPersPastel">Personaliza tu pastel</h2>
<div className="mb-4">
<p className="pastel-Type">Tipo de Relleno</p>
<div className="botones-pastel">
<button className="boton-1" onClick={() => clickBotonOriginal()}>
Original
</button>
<button className="boton-2" onClick={() => clickBotonArcoiris()}>
Arcoiris
</button>
<button className="boton-3" onClick={() => clickBotonOreo()}>
Oreo
</button>
<button className="boton-4" onClick={() => clickBotonVainilla()}>
Vainilla
</button>
</div>
</div>
<div className="container-cantidad-personas">
<div className="titulo-pers">Personas </div>
<TextField
type="number"
placeholder="1"
value={quantity}
onChange={(e) => handleQuantityChange(e.target.value)}
InputProps={{ inputProps: { min: 1 } }}
className="input-cantidad"
/>
<div className="btn-increment-decrement">
<i
className="fa-solid fa-chevron-up"
id="increment"
onClick={handleIncrement}
></i>
<i
className="fa-solid fa-chevron-down"
id="decrement"
onClick={handleDecrement}
></i>
</div>
</div>
<div className="mb-6">
<p className="label-text-pers">Inscription (30 Character Limit)</p>
<input className="input-text-pers"
type="text"
id="inscription"
name="inscription"
placeholder="Enter your text"
maxLength="30"
value={datosPastel.texto}
onChange={handleChange}
onBlur={handleInputBlur}
onFocus={handleInputFocus}
/>
</div>
</div>
</div>
</div>
<div className="container-add-cart">
<button className="btn-add-to-cart" onClick={hacerPedidoPastel1}>
Comprar
</button>
</div>
<div className="container-description">
<div className="title-description">
<h4>Descripción</h4>
<i className="fa-solid fa-chevron-down"></i>
</div>
<div className="text-description">
<p>
Lorem ipsum dolor, sit amet consectetur adipisicing elit.
Laboriosam iure provident atque voluptatibus reiciendis quae
rerum, maxime placeat enim cupiditate voluptatum, temporibus
quis iusto. Enim eum qui delectus deleniti similique? Lorem,
ipsum dolor sit amet consectetur adipisicing elit. Sint autem
magni earum est dolorem saepe perferendis repellat ipsam
laudantium cum assumenda quidem quam, vero similique? Iusto
officiis quod blanditiis iste?, ipsum dolor sit amet consectetur
adipisicing elit. Sint autem magni earum est dolorem saepe
perferendis repellat ipsa laudantium cum assumenda quidem
quam, vero similique? Iustoofficiis
</p>
</div>
</div>
</div>
</main>
<div className="Reseñas">
<h2 className="customer-reviews-title">Reseñas</h2>
<div className="estrellas-reviews-container">
<h1>Calificación:</h1>
<StarRatings
rating={datosFormularioReseña.estrellas}
starRatedColor="#4b1e29"
starHoverColor="#8B374A"
changeRating={(newRating) => setDatosFormularioReseña({...datosFormularioReseña, estrellas: newRating})}
numberOfStars={5}
name='rating'
starDimension="30px"
/>
</div>
<div className="customer-reviews-container">
<div className="reseñas-conteiner">
<input className="input-reseñas"
type="text"
name="contenido"
value={datosFormularioReseña.contenido}
onChange={handleInputChange}
placeholder="Escribe tu reseña aquí"></input>
<button className="boton-reseñas" onClick={enviarReseña}>Enviar</button>
</div>
{mostrarReseñas()}
</div>
</div>
<footer className="footer">
<div className="container container-footer">
<div className="menu-footer">
<div className="contact-info">
<p className="title-footer">Información de Contacto</p>
<ul>
<li>
Avenida Xalapa
</li>
<li>Teléfono: 2288520821</li>
<li>EmaiL: cdgn_17@hotmail.com</li>
</ul>
<div className="social-icons">
<span className="facebook">
<i className="fa-brands fa-facebook-f"></i>
</span>
<span className="twitter">
<i className="fa-brands fa-twitter"></i>
</span>
<span className="youtube">
<i className="fa-brands fa-youtube"></i>
</span>
<span className="pinterest">
<i className="fa-brands fa-pinterest-p"></i>
</span>
<span className="instagram">
<i className="fa-brands fa-instagram"></i>
</span>
</div>
</div>
<div className="information">
<p className="title-footer">Información</p>
<ul>
<li><a href="#">Acerca de Nosotros</a></li>
<li><a href="#">Información de Entrega</a></li>
<li><a href="#">Politicas de Privacidad</a></li>
<li><a href="#">Términos y condiciones</a></li>
<li><a href="#">Contactános</a></li>
</ul>
</div>
<div className="my-account">
<p className="title-footer">Mi cuenta</p>
<ul>
<li><a href="#">Mi cuenta</a></li>
<li><a href="#">Pedidos</a></li>
<li><a href="#">Boletín</a></li>
</ul>
</div>
</div>
<div className="copyright">
</div>
</div>
</footer>
</>
);
}
export default Pastel;

853
src/PersPastelStyle.css Normal file
View File

@ -0,0 +1,853 @@
@import url('https://fonts.googleapis.com/css2?family=Ubuntu:wght@300;500;700&display=swap');
.main-pers-pastel {
display: flex;
gap: 30px;
margin-bottom: 80px;
font-family: 'Ubuntu';
max-width: 1200px;
margin: 0 auto;
margin-top: 20px;
}
/* ********************************** */
/* HEADER */
/* ********************************** */
.container-hero {
background-color: var(--background-color);
}
.hero {
display: flex;
justify-content: space-between;
align-items: center;
padding: 2rem 0;
}
.customer-support {
display: flex;
align-items: center;
gap: 2rem;
}
.customer-support i {
font-size: 3.3rem;
}
.content-customer-support {
display: flex;
flex-direction: column;
}
.container-logo {
display: flex;
align-items: center;
gap: 0.5rem;
}
.container-logo i {
font-size: 3rem;
}
.container-logo h1 a {
text-decoration: none;
color: #000;
font-size: 3rem;
text-transform: uppercase;
letter-spacing: -1px;
}
.container-user {
display: flex;
gap: 1rem;
cursor: pointer;
}
.container-user .fa-user {
font-size: 3rem;
color: var(--primary-color);
padding-right: 2.5rem;
border-right: 1px solid #e2e2e2;
}
.container-user .fa-basket-shopping {
font-size: 3rem;
color: var(--primary-color);
padding-left: 1rem;
}
.content-shopping-cart {
display: flex;
flex-direction: column;
}
/* ************* NAVBAR ************* */
.container-navbar {
background-color: var(--primary-color);
}
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 0;
color: white;
}
.navbar .fa-bars {
display: none;
}
.menu {
display: flex;
gap: 2rem;
}
.menu li {
list-style: none;
}
.menu a {
text-decoration: none;
font-size: 1.3rem;
color: var(--dark-color);
font-weight: 600;
text-transform: uppercase;
position: relative;
color: white;
}
.menu a::after {
content: '';
width: 1.5rem;
height: 1px;
background-color: #fff;
position: absolute;
bottom: -3px;
left: 50%;
transform: translate(-50%, 50%);
opacity: 0;
transition: all 0.3s ease;
}
.menu a:hover::after {
opacity: 1;
}
.menu a:hover {
color: #fff;
}
.search-form {
position: relative;
display: flex;
align-items: center;
border: 2px solid #fff;
border-radius: 2rem;
background-color: #fff;
height: 4.4rem;
overflow: hidden;
}
.search-form input {
outline: none;
font-family: inherit;
border: none;
width: 25rem;
font-size: 1.4rem;
padding: 0 2rem;
color: #777;
cursor: pointer;
}
.search-form input::-webkit-search-cancel-button {
appearance: none;
}
.search-form .btn-search {
border: none;
background-color: var(--primary-color);
display: flex;
align-items: center;
justify-content: center;
height: 100%;
padding: 1rem;
}
.btn-search i {
font-size: 2rem;
color: #fff;
}
.container-title {
padding: 30px;
background-color: #eee;
margin-bottom: 50px;
color: #222;
}
.imgPastel{
position: relative;
max-height: 670px;
}
.texto-encima {
position: absolute;
top: 54%;
left:34%;
max-width: 220px;
word-wrap: break-word; /* Esta propiedad permite que las palabras se rompan cuando no caben en el contenedor */
overflow-wrap: break-word;
transform: translate(-50%, -50%);
background-color: rgba(255, 255, 255, 0.4); /* Cambia el color de fondo según lo desees */
padding: 10px;
border-radius: 5px;
font-size: 32px;
text-align: center;
}
.container-img-1 {
background-color: #f7f7f9;
background-image: url('');
flex: 1;
width: 55%;
height: 100%;
background-size: 100% auto;
}
.container-img-2 {
background-color: #f7f7f9;
background-image: url('assets/Edicion21.jpg');
flex: 1;
width: 55%;
height: 100%;
padding-top: 60.4%;
background-size: 100% auto;
}
.container-img-3 {
background-color: #f7f7f9;
background-image: url('assets/Edicion12.jpg');
flex: 1;
width: 55%;
height: 100%;
padding-top: 60.4%;
background-size: 100% auto;
}
.container-img-4 {
background-color: #f7f7f9;
background-image: url('assets/Edicion13.jpg');
flex: 1;
width: 55%;
height: 100%;
padding-top: 60.4%;
background-size: 100% auto;
}
.container-img-5 {
background-color: #f7f7f9;
background-image: url('assets/Edicion14.jpg');
flex: 1;
width: 55%;
height: 100%;
padding-top: 60.4%;
background-size: 100% auto;
}
.container-img-6 {
background-color: #f7f7f9;
background-image: url('assets/Edicion15.jpg');
flex: 1;
width: 55%;
height: 100%;
padding-top: 60.4%;
background-size: 100% auto;
}
.container-img-7 {
background-color: #f7f7f9;
background-image: url('assets/Edicion16.jpg');
flex: 1;
width: 55%;
height: 100%;
padding-top: 60.4%;
background-size: 100% auto;
}
.imgPastel{
flex: 1;
width: 100%;
height: 100%;
background-size: 200% auto;
}
.container-info-product {
flex: 1;
display: flex;
flex-direction: column;
}
.container-price {
padding-bottom: 20px;
border-bottom: 1px solid #e4e4e4;
display: flex;
align-items: center;
justify-content: space-between;
}
.container-price span {
font-size: 24px;
font-weight: 300;
}
.container-details-product {
padding: 30px 0;
padding-bottom: 0px;
}
.textPersPastel{
font-size: 18px;
font-weight: bold;
margin-bottom: 10px;
}
.pastel-Type{
font-size: 18px;
font-weight: lighter;
margin-bottom: 10px;
}
.botones-pastel{
display: flex;
gap: 4;
margin-bottom: 20px;
}
.boton-1{
margin-right: 20px;
border: none;
color: white;
padding: 14px 28px;
cursor: pointer;
border-radius: 5px;
background-color: #8B374A
}
.boton-1:hover {
background-color: #4b1e29; /* Cambia el color al pasar el cursor sobre el botón */
}
.boton-1:active {
transform: scale(0.90); /* Reduce ligeramente el tamaño del botón cuando se hace clic */
}
.boton-2{
margin-right: 10px;
border: none;
color: white;
padding: 14px 28px;
cursor: pointer;
border-radius: 5px;
background-color: #8B374A
}
.boton-2:hover {
background-color: #4b1e29; /* Cambia el color al pasar el cursor sobre el botón */
}
.boton-2:active {
transform: scale(0.90); /* Reduce ligeramente el tamaño del botón cuando se hace clic */
}
.boton-3{
margin-right: 10px;
border: none;
color: white;
padding: 14px 28px;
cursor: pointer;
border-radius: 5px;
background-color: #8B374A
}
.boton-3:hover {
background-color: #4b1e29; /* Cambia el color al pasar el cursor sobre el botón */
}
.boton-3:active {
transform: scale(0.90); /* Reduce ligeramente el tamaño del botón cuando se hace clic */
}
.boton-4{
border: none;
color: white;
padding: 14px 28px;
cursor: pointer;
border-radius: 5px;
background-color: #8B374A
}
.boton-4:hover {
background-color: #4b1e29; /* Cambia el color al pasar el cursor sobre el botón */
}
.boton-4:active {
transform: scale(0.90); /* Reduce ligeramente el tamaño del botón cuando se hace clic */
}
.label-text-pers{
margin-top: 10px;
font-size: 16px;
font-weight: lighter;
margin-bottom: 10px;
}
.input-text-pers{
margin-top: 10px;
font-size: 16px;
margin-bottom: 10px;
text-indent: 5px;
width: 100%;
height: 50px;
}
.form-group {
display: flex;
align-items: center;
gap: 20px;
margin-bottom: 15px;
}
.form-group label {
width: 100px;
color: #222;
font-weight: lighter;
}
.form-group select {
width: 300px;
border: none;
padding: 12px 15px;
background-color: #f7f7f7;
outline: none;
color: #666;
}
.btn-clean {
border: none;
background: none;
color: #666;
margin-left: 120px;
cursor: pointer;
}
.btn-clean:hover {
color: #1bbeb4;
}
.container-add-cart {
display: flex;
gap: 20px;
padding-bottom: 30px;
border-bottom: 1px solid #e4e4e4;
}
.container-quantity {
position: relative;
}
.input-quantity {
background-color: #f7f7f7;
border: none;
padding: 10px;
width: 60px;
height: 100%;
color: #666;
font-weight: 500;
line-height: 0;
}
.input-quantity:focus {
outline: none;
}
.input-quantity::-webkit-inner-spin-button,
.input-quantity::-webkit-outer-spin-button {
-webkit-appearance: none;
appearance: none;
}
.fa-chevron-down:hover {
color: #1bbeb4;
}
.fa-chevron-up:hover {
color: #1bbeb4;
}
.btn-add-to-cart{
border: none;
color: white;
padding: 14px 28px;
cursor: pointer;
border-radius: 5px;
background-color: #8B374A
}
.btn-add-to-cart:hover {
background-color: #4b1e29; /* Cambia el color al pasar el cursor sobre el botón */
}
.btn-add-to-cart:active {
transform: scale(0.90); /* Reduce ligeramente el tamaño del botón cuando se hace clic */
}
.hidden {
display: none;
}
.container-description,
.container-additional-information,
.container-reviews {
display: flex;
flex-direction: column;
border-bottom: 1px solid #e4e4e4;
padding: 10px 0;
}
.title-description,
.title-additional-information,
.title-reviews {
display: flex;
align-items: center;
justify-content: space-between;
cursor: pointer;
}
.title-description h4,
.title-additional-information h4,
.title-reviews h4 {
font-weight: 300;
color: #666;
font-size: 14px;
}
.text-description,
.text-additional-information,
.text-reviews {
font-size: 13px;
color: #252525;
line-height: 22px;
margin-top: 25px;
}
.container-social {
display: flex;
justify-content: space-between;
padding: 10px 0;
align-items: center;
border-bottom: 1px solid #e4e4e4;
}
.container-social span {
font-weight: 300;
color: #252525;
}
.container-buttons-social {
display: flex;
gap: 15px;
align-items: center;
}
.container-buttons-social a:link,
.container-buttons-social a:visited {
color: #666;
font-size: 15px;
}
.container-buttons-social a:hover {
color: #1bbeb4;
}
.container-related-products h2 {
text-align: center;
margin-bottom: 30px;
}
.card-list-products {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 25px;
}
.card {
cursor: pointer;
}
.card-img {
background: transparent;
margin-bottom: 15px;
}
.card-img img {
height: 400px;
object-fit: cover;
box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.2);
}
.info-card {
display: flex;
justify-content: space-between;
}
.text-product {
color: #252525;
font-weight: 300;
line-height: 1.4;
}
.text-product h3{
color: inherit;
font-weight: inherit;
font-size: 15px;
}
.text-product h3:hover{
color: #1bbeb4;
}
.text-product p{
color: #666;
font-size: 13px;
}
.text-product p:hover{
color: #1bbeb4;
}
footer {
padding: 30px;
background-color: #eee;
margin-top: 50px;
color: #222;
}
.reseñas{
display: flex;
align-items: center;
}
.reseñas-conteiner{
display: flex;
align-items: center;
}
/* Estilos para el contenedor principal */
.customer-reviews-container {
background-color: #fff;
margin-left: 35.5rem;
margin-right: 35.5rem;
position: relative;
}
/* Estilos para el título */
.customer-reviews-title {
font-size: 2.875rem; /* text-3xl */
font-weight: bold;
padding-top: 3rem;
text-align: center;
color: #4b5563; /* text-zinc-800 */
margin-bottom: 2.5rem; /* mb-10 */
}
/* Estilos para el contenedor de cada reseña */
.customer-review-card {/* ajustar según sea necesario */
border-radius: 1rem;
max-width: 100%;
overflow: hidden;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
padding: 1.5rem;
background-color: #f9fafb; /* bg-zinc-50 */
margin-bottom: 3rem ;
}
/* Estilos para la sección de la imagen y la información del cliente */
.customer-review-info {
display: flex;
align-items: center;
gap: 0.25rem; /* space-x-2 */
margin-bottom: 1rem; /* mb-4 */
}
/* Estilos para la imagen del cliente */
.customer-review-avatar {
width: 4.5rem; /* w-10 */
height: 4.5rem; /* h-10 */
border-radius: 50%;
}
/* Estilos para el nombre del cliente */
.customer-review-name {
padding-left: 3rem;
font-size: 1.875rem; /* text-sm */
font-weight: bold;
}
/* Estilos para la descripción del cliente */
.customer-review-description {
font-size: 0.875rem; /* text-sm */
color: #4b5563; /* text-zinc-600 */
}
/* Estilos para la calificación */
.customer-review-rating {
margin-bottom: 0.5rem; /* mb-2 */
color: var(--primary-color); /* text-pink-500 */
font-size: 2.5rem;
}
/* Estilos para el contenido de la reseña */
.customer-review-content {
color: #4b5563; /* text-zinc-700 */
font-size: 1.5rem; /* text-base */
}
.btn-increment-decrement {
display: flex;
flex-direction: column;
position: absolute;
top: 17px;
right: 17px;
}
.btn-increment-decrement i {
font-size: 31px;
color: #666;
cursor: pointer;
padding-bottom: 3rem;
}
.input-cantidad {
background-color: #f7f7f7;
border: none;
padding: 15px;
width: 110px;
height: 100%;
color: #666;
font-weight: lighter;
line-height: 0;
}
.input-cantidad:focus {
outline: none;
}
.input-cantidad::-webkit-inner-spin-button,
.input-cantidad::-webkit-outer-spin-button {
-webkit-appearance: none;
appearance: none;
}
.container-cantidad-personas {
display: flex;
align-items: center;
gap: 20px;
}
.container-add-reservacion {
display: flex;
gap: 20px;
padding-bottom: 30px;
border-bottom: 1px solid #e4e4e4;
font-weight: lighter;
}
.titulo-pers{
font-weight: lighter;
font-size: 18px;
}
.fa-chevron-up,
.fa-chevron-down {
font-size: 20px; /* Aumentar el tamaño de la fuente de los iconos */
}
/* ********************************** */
/* Reseñas */
/* ********************************** */
.boton-reseñas{
border: none;
color: white;
padding: 14px 28px;
cursor: pointer;
width: 200px;
border-radius: 5px;
background-color: #8B374A;
}
.boton-reseñas:hover {
background-color: #4b1e29; /* Cambia el color al pasar el cursor sobre el botón */
}
.boton-reseñas:active {
transform: scale(0.90); /* Reduce ligeramente el tamaño del botón cuando se hace clic */
}
.input-reseñas{
margin-top: 10px;
font-size: 16px;
margin-bottom: 10px;
margin-right: 20px;
text-indent: 5px;
width: 100%;
height: 40px;
}
.reseñas-conteiner{
margin-bottom: 5rem;
}
.star-ratings {
margin-top: 1rem;
margin-bottom: 1rem;
width:335px;
}
.estrellas-reviews-container{
background-color: #fff;
margin-left: 35.5rem;
margin-right: 35.5rem;
position: relative;
}

View File

@ -0,0 +1,43 @@
import { Button } from "@mui/base"
import { Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle } from "@mui/material"
import { useState } from "react"
import { useNavigate } from "react-router-dom"
function PopupActualizar ({nombre}){
const navigate = useNavigate();
const[open,setOpen] = useState(true);
const redirectToLogin = () => {
// Redirige a la página del hotel cuando se hace clic en el botón
navigate("/Login");
};
const eventoAbrir = () => {
setOpen(true)
}
const eventoCerrar = () => {
setOpen(false)
redirectToLogin();
}
return(
<>
<div>
<Dialog open={open} onClose={eventoCerrar}>
<DialogTitle>Actualizacion</DialogTitle>
<DialogContent>
<DialogContentText>
Credenciales actualizadas correctamenete
</DialogContentText>
</DialogContent>
<DialogActions>
<Button className="cerrar" onClick={eventoCerrar}>Cerrar</Button>
</DialogActions>
</Dialog>
</div>
</>
)
}
export default PopupActualizar

View File

@ -0,0 +1,34 @@
import { Button } from "@mui/base"
import { Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle } from "@mui/material"
import { useState } from "react"
function PopupActualizarInv ({nombre}){
const[open,setOpen] = useState(true);
const eventoAbrir = () => {
setOpen(true)
}
const eventoCerrar = () => {
setOpen(false)
}
return(
<>
<div>
<Dialog open={open} onClose={eventoCerrar}>
<DialogTitle>Correo no encontrado</DialogTitle>
<DialogContent>
<DialogContentText>
El correo que introdujo no existe o no se encuentra.
</DialogContentText>
</DialogContent>
<DialogActions>
<Button className="cerrar" onClick={eventoCerrar}>Cerrar</Button>
</DialogActions>
</Dialog>
</div>
</>
)
}
export default PopupActualizarInv

View File

@ -0,0 +1,35 @@
import { Button } from "@mui/base"
import { Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle } from "@mui/material"
import { useState } from "react"
function PopupLoginInvalido ({nombre}){
const[open,setOpen] = useState(true);
const eventoAbrir = () => {
setOpen(true)
}
const eventoCerrar = () => {
setOpen(false)
}
return(
<>
<div>
<Dialog open={open} onClose={eventoCerrar}>
<DialogTitle>Error al Iniciar Sesion</DialogTitle>
<DialogContent>
<DialogContentText>
Correo o contraseña incorrecta.
</DialogContentText>
</DialogContent>
<DialogActions>
<Button className="cerrar" onClick={eventoCerrar}>Cerrar</Button>
</DialogActions>
</Dialog>
</div>
</>
)
}
export default PopupLoginInvalido

View File

@ -0,0 +1,43 @@
import { Button } from "@mui/base"
import { Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle } from "@mui/material"
import { useState } from "react"
import { useNavigate } from "react-router-dom"
function PopupLoginValido ({nombre}){
const navigate = useNavigate();
const[open,setOpen] = useState(true);
const redirectToHome = () => {
// Redirige a la página del hotel cuando se hace clic en el botón
navigate("/");
};
const eventoAbrir = () => {
setOpen(true)
}
const eventoCerrar = () => {
setOpen(false)
redirectToHome();
}
return(
<>
<div>
<Dialog open={open} onClose={eventoCerrar}>
<DialogTitle>Inicio de Sesion Exitoso</DialogTitle>
<DialogContent>
<DialogContentText>
Bienvenido: {nombre}
</DialogContentText>
</DialogContent>
<DialogActions>
<Button className="cerrar" onClick={eventoCerrar}>Cerrar</Button>
</DialogActions>
</Dialog>
</div>
</>
)
}
export default PopupLoginValido

View File

@ -0,0 +1,36 @@
import { Button } from "@mui/base"
import { Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle } from "@mui/material"
import { useState } from "react"
function PopupRegistro (){
const[open,setOpen] = useState(true);
const eventoAbrir = () => {
setOpen(true)
}
const eventoCerrar = () => {
setOpen(false)
}
return(
<>
<div>
<Dialog open={open} onClose={eventoCerrar}>
<DialogTitle>Registro Exitoso</DialogTitle>
<DialogContent>
<DialogContentText>
Cuenta Registrada con exito
</DialogContentText>
</DialogContent>
<DialogActions>
<Button className="cerrar" onClick={eventoCerrar}>Cerrar</Button>
</DialogActions>
</Dialog>
</div>
</>
)
}
export default PopupRegistro

View File

@ -0,0 +1,35 @@
import { Button } from "@mui/base"
import { Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle } from "@mui/material"
import { useState } from "react"
function Popup (){
const[open,setOpen] = useState(true);
const eventoAbrir = () => {
setOpen(true)
}
const eventoCerrar = () => {
setOpen(false)
}
return(
<>
<div>
<Dialog open={open} onClose={eventoCerrar}>
<DialogTitle>Registro Fallido</DialogTitle>
<DialogContent>
<DialogContentText>
Porfavor introduzca los datos correspondientes.
</DialogContentText>
</DialogContent>
<DialogActions>
<Button className="cerrar" onClick={eventoCerrar}>Cerrar</Button>
</DialogActions>
</Dialog>
</div>
</>
)
}
export default Popup

126
src/Sesion/LoginForm.css Normal file
View File

@ -0,0 +1,126 @@
.wrapper{
width: 450px;
background: transparent;
border: 2px solid rgba(255, 255, 255, .2);
backdrop-filter: blur(50px);
box-shadow: 0 0 10px rgba(0, 0, 0, .2);
color: #fff;
border-radius: 20px;
padding: 50px 30px;
}
.wrapper h1{
font-size: 36px;
text-align: center;
}
.wrapper .input-box{
position: relative;
margin: 30px 0;
}
.input-box input{
width: 100%;
height: 100%;
background: transparent;
border: 2px solid rgba(255, 255, 255, .2);
outline: none;
border-radius: 40px;
font-size: 16px;
color: #fff;
padding: 20px 45px 20px 20px;
}
.input-box input::placeholder{
color: #fff;
}
.input-box .icon{
position: absolute;
right: 20px;
top: 50%;
transform: translateY(-50%);
font-size: 16px;
}
.wrapper .remember-forgot{
display: flex;
justify-content: space-between;
font-size: 14.5px;
margin: -15px 0 15px;
}
.remember-forgot label input{
accent-color: #fff;
margin-right: 4px;
}
.remember-forgot a{
color: #fff;
text-decoration: none;
}
.remember-forgot a:hover{
text-decoration: underline;
}
.wrapper .boton1{
display: inline-block;
position: absolute;
background-color: none;
top: 20px;
left: 10px;
width: 45px;
height: 35px;
padding: 0px;
padding-left: 0px;
padding-right: 0px;
font-size: 14px;
}
.wrapper button{
width: 100%;
height: 45px;
background: #fff;
border: none;
outline: none;
border-radius: 40px;
box-shadow: 0 0 10px rgba(0, 0, 0, .1);
cursor: pointer;
font-size: 16px;
color: #333;
font-weight: 700;
}
.wrapper .register-link{
font-size: 14.5px;
text-align: center;
margin: 20px 0 15px;
}
.register-link p a{
color: #fff;
text-decoration: none;
font-weight: 600;
}
.register-link p a:hover {
text-decoration: underline;
}
.cuerpo {
width: 135.1%;
background-repeat: no-repeat;
height: 100%;
padding-left: 0%;
background-size: 100% auto;
margin:0;
font-family: 'Poppins', sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background: url("src/assets/fondo_pasteles.jpg");
background-position: center;
}
.cuerpo {
transform: translateX(-361px);
}

187
src/Sesion/LoginForm.jsx Normal file
View File

@ -0,0 +1,187 @@
import React, { useState } from "react";
import './LoginForm.css';
import { FaUser, FaLock, FaHome } from "react-icons/fa";
import { TextField, Button, Box } from "@mui/material";
import axios from "axios";
import { useNavigate } from "react-router-dom";
import PopupV from "/src/Popups/PopupLoginValido.jsx";
import PopupIv from "/src/Popups/PopupLoginInvalido.jsx";
import Swal from 'sweetalert2'
function LoginForm(props){
const navigate = useNavigate();
const [Cargando, setCargando] = useState(false)
const [datosFormulario, setDatosFormulario] = useState(
{correo: '',
password: ''
})
const redirectToRecuperarContraseña = () => {
navigate("/RecuperarContraseña");
};
const redirectToAdminVista = () => {
navigate("/AdminVista");
};
const mostrarAlertaLoginExitoso=(nomb)=>{
Swal.fire({
title: "Inicio de sesion Exitoso",
text: "Bienvenido "+nomb+".",
icon: "success",
button: "Aceptar"
}).then(respuesta=>{
if(respuesta){
if(datosFormulario.correo == "admin" && datosFormulario.password == "12345"){
console.log("asdasddsdasdasdadadsasddasdasdassa");
redirectToAdminVista();
}else{
redirectToHome();
}
}
})
}
const mostrarAlertaLoginFallido=()=>{
Swal.fire({
title: "Inicio de sesion fallido",
text: "Usuario o Contraseña Incorrecta.",
icon: "error",
button: "Aceptar"
});
}
const mostrarAlertaLoginSinDatos=()=>{
Swal.fire({
title: "Inicio de sesion fallido",
text: "Introduzca los datos que se le piden.",
icon: "error",
button: "Aceptar"
});
}
const loginUsuario = async (evento) => {
evento.preventDefault();
try{
console.log(datosFormulario)
const response = await axios.post('http://localhost:4567/frontend/login',{datosFormulario})
console.log(response.data)
console.log("c = " +datosFormulario.correo+" p = "+datosFormulario.password)
if(datosFormulario.correo && datosFormulario.password){
if (response.data === 'Invalido') {
// Si la respuesta es 'Invalido', limpiar los campos del formulario
mostrarAlertaLoginFallido();
setDatosFormulario({
correo: '',
password: ''
});
} else {
// Si la respuesta es 'Valido', puedes realizar las acciones deseadas
setNombre(response.data.nombre);
console.log(response.data.nombre);
mostrarAlertaLoginExitoso(response.data.nombre);
//abrirPopupV()
}
}else{
mostrarAlertaLoginSinDatos();
}
return response.data
} catch(error){
throw error
}
}
const [nombre,setNombre]=useState('')
const [mostrarPopupV, setMostrarPopupV] = useState(false);
const abrirPopupV = () => {
setMostrarPopupV(true);
};
const [mostrarPopupIv, setMostrarPopupIv] = useState(false);
const abrirPopupIv = () => {
setMostrarPopupIv(true);
};
const cambiosFormulario = (evento) => {
//console.log(evento.target)
const {name,value} = evento.target
setDatosFormulario ({...datosFormulario, [name]: value})
setMostrarPopupIv(false);
}
const redirectToHome = () => {
// Redirige a la página del hotel cuando se hace clic en el botón
navigate("/");
};
const redirectToRegistro = () => {
// Redirige a la página del hotel cuando se hace clic en el botón
navigate("/Registro");
};
return(
<>
<div className="cuerpo">
<div className="wrapper">
<form>
<div className="boton1">
<button type="button" className="button first-button" onClick={redirectToHome}>
<span className="button-text"></span>
<FaHome />
</button>
</div>
<h1>Inicio</h1>
<div className="input-box">
<input type="text" placeholder="Correo" onChange={cambiosFormulario} name="correo" value={datosFormulario.correo}/>
<FaUser className="icon"/>
</div>
<div className="input-box">
<input type="password" placeholder="Contraseña" onChange={cambiosFormulario} name="password" value={datosFormulario.password}/>
<FaLock className="icon"/>
</div>
<div className="remember-forgot">
<label><input type="checkbox" />Recuerdame</label>
<a href="#" onClick={redirectToRecuperarContraseña} >¿Contraseña olvidada?</a>
</div>
<button className="Entrar" onClick={loginUsuario} disabled={Cargando}>Entrar</button>
<div className="register-link">
<p>¿No tienes una cuenta? <a href="" onClick={redirectToRegistro}>Register </a></p>
</div>
<Box m={5}>
{mostrarPopupV && <PopupV nombre ={nombre} onClose={() => setMostrarPopupV(false)} />}
</Box>
<Box m={5}>
{mostrarPopupIv && <PopupIv nombre ={nombre} onClose={() => setMostrarPopupIv(false)} />}
</Box>
</form>
</div>
</div>
</>
)
}
export default LoginForm;

143
src/Sesion/Recuperar.css Normal file
View File

@ -0,0 +1,143 @@
.wrapper{
width: 450px;
background: transparent;
border: 2px solid rgba(255, 255, 255, .2);
backdrop-filter: blur(50px);
box-shadow: 0 0 10px rgba(0, 0, 0, .2);
color: #fff;
border-radius: 20px;
padding: 50px 30px;
}
.wrapper h1{
font-size: 36px;
text-align: center;
}
.wrapper .label-correo {
margin-top: 10px;
margin-left: 10px; /* Puedes ajustar este valor según sea necesario */
margin-bottom: -20px; /* Puedes ajustar este valor según sea necesario */
display: block; /* Asegura que el label se comporte como un bloque */
font-size: 16px;
}
.wrapper .input-box{
position: relative;
width: 100%;
height: 50px;
margin: 30px 0;
}
.input-box input{
width: 100%;
height: 100%;
background: transparent;
border: 2px solid rgba(255, 255, 255, .2);
outline: none;
border-radius: 40px;
font-size: 16px;
color: #fff;
padding: 20px 45px 20px 20px;
}
.input-box input::placeholder{
color: #fff;
}
.input-box .icon{
position: absolute;
right: 20px;
top: 50%;
transform: translateY(-50%);
font-size: 16px;
}
.wrapper .remember-forgot{
display: flex;
justify-content: space-between;
font-size: 14.5px;
margin: -15px 0 15px;
}
.remember-forgot label input{
accent-color: #fff;
margin-right: 4px;
}
.remember-forgot a{
color: #fff;
text-decoration: none;
}
.remember-forgot a:hover{
text-decoration: underline;
}
.wrapper .boton1{
display: inline-block;
position: absolute;
background-color: none;
top: 20px;
left: 10px;
width: 45px;
height: 35px;
padding: 0px;
padding-left: 0px;
padding-right: 0px;
font-size: 14px;
}
.wrapper button{
width: 100%;
height: 45px;
background: #fff;
border: none;
outline: none;
border-radius: 40px;
box-shadow: 0 0 10px rgba(0, 0, 0, .1);
cursor: pointer;
font-size: 16px;
color: #333;
font-weight: 700;
}
.wrapper .register-link{
font-size: 14.5px;
text-align: center;
margin: 20px 0 15px;
}
.register-link p a{
color: #fff;
text-decoration: none;
font-weight: 600;
}
.register-link p a:hover {
text-decoration: underline;
}
.cuerpo {
width: 135.1%;
background-repeat: no-repeat;
height: 100%;
padding-left: 0%;
background-size: 100% auto;
margin:0;
font-family: 'Poppins', sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background-position: center;
}
.cuerpo {
transform: translateX(-361px);
}
.label-correo.desactivado {
color: #999; /* Color de texto desactivado */
}
.input-box.desactivado {
background-color: gray; /* Color de fondo desactivado */
border: 2px solid #ccc; /* Borde desactivado */
border-radius: 30px;
}

View File

@ -0,0 +1,210 @@
/* POPPINS FONT */
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap');
.body-login{
background: url("/src/assets/fondo_pasteles.jpg");
background-size: 100%;
background-repeat: no-repeat;
overflow: hidden;
background-attachment: fixed;
display: flex;
height: 100%;
position: relative;
justify-content: center;
margin: 0;
padding: 0;
}
.wrapper{
display: flex;
width: 40%;
height: 100vh;
padding-left: 4px;
align-items: center;
justify-content: center;
}
.link:hover, .active{
border-bottom: 2px solid #fff;
}
.btn:hover{
background: rgba(255, 255, 255, 0.3);
}
#registerBtn{
margin-left: 15px;
}
.btn.white-btn{
background: rgba(255, 255, 255, 0.7);
}
.btn.btn.white-btn:hover{
background: rgba(255, 255, 255, 0.5);
}
.form-box{
position: relative;
display: flex;
align-items: center;
justify-content: center;
width: 512px;
height: 500px;
overflow: hidden;
z-index: 2;
border-radius: 4%;
background: rgba(39, 39, 39, 0.5);
}
.login-container{
position: absolute;
left: 4px;
width: 500px;
opacity: 1;
display: flex;
flex-direction: column;
transition: .5s ease-in-out;
}
.register-container{
position: absolute;
right: -520px;
width: 500px;
display: flex;
flex-direction: column;
transition: .5s ease-in-out;
gap: 7px;
}
.password-container{
position: absolute;
right: -520px;
width: 500px;
display: flex;
flex-direction: column;
transition: .5s ease-in-out;
gap: 7px;
}
.top span{
color: #fff;
font-size: small;
padding: 10px 0;
display: flex;
justify-content: center;
}
.top2 span{
color: #fff;
font-size: small;
padding: 10px 0;
display: flex;
justify-content: center;
}
.two span a{
font-weight: 500;
color: #fff;
margin-left: 5px;
}
.top span a{
font-weight: 500;
color: #fff;
margin-left: 5px;
}
.top2 span a{
font-weight: 500;
color: #fff;
margin-left: 5px;
}
.header-login{
color: #fff;
font-size: 30px;
text-align: center;
padding: 10px 0 30px 0;
}
.two-forms{
display: flex;
gap: 20px;
}
.input-field{
font-size: 15px;
background: rgba(255, 255, 255, 0.2);
color: #fff;
height: 50px;
width: 100%;
padding: 0 10px 0 45px;
border: none;
border-radius: 30px;
outline: none;
transition: .2s ease;
margin-bottom: 10px; /*para separar los componentes agregando un margen por debajo*/
}
.input-field:hover, .input-field:focus{
background: rgba(255, 255, 255, 0.25);
}
::-webkit-input-placeholder{
color: #fff;
}
.input-box i{
position: relative;
margin-top: 10px;
margin-bottom: 10px;
top: -35px;
left: 17px;
color: #fff;
}
.input-box i{
position: relative;
margin-top: 10px;
margin-bottom: 10px;
top: -35px;
left: 17px;
color: #fff;
}
.submit{
font-size: 15px;
font-weight: 500;
color: black;
height: 45px;
width: 100%;
border: none;
border-radius: 30px;
outline: none;
background: rgba(255, 255, 255, 0.7);
cursor: pointer;
transition: .3s ease-in-out;
}
.submit:hover{
background: rgba(255, 255, 255, 0.5);
box-shadow: 1px 5px 7px 1px rgba(0, 0, 0, 0.2);
}
.two-col{
display: flex;
justify-content: space-between;
color: #fff;
font-size: small;
margin-top: 10px;
margin-bottom: 10px;
margin-left: 10px;
}
.two-col .one{
display: flex;
gap: 5px;
}
.two label a{
text-decoration: none;
color: #fff;
}
.two label a:hover{
text-decoration: underline;
}
@media only screen and (max-width: 540px) {
.wrapper{
min-height: 100vh;
}
.form-box{
width: 100%;
height: 500px;
}
.register-container, .login-container{
width: 100%;
padding: 0 20px;
}
.register-container .two-forms{
flex-direction: column;
gap: 0;
}
}

View File

@ -0,0 +1,252 @@
import React, { useState, useEffect } from "react";
import './Recuperar.css';
import { FaUser, FaLock, FaHome } from "react-icons/fa";
import { TextField, Button, Box } from "@mui/material";
import axios from "axios";
import { useNavigate } from "react-router-dom";
import emailjs from 'emailjs-com';
import PopupActualizar from "/src/Popups/PopupActualizar";
import PopupActualizarInv from "/src/Popups/PopupActualizarInv.jsx";
import PopupV from "/src/Popups/PopupLoginValido.jsx";
import PopupIv from "/src/Popups/PopupLoginInvalido.jsx";
import Swal from 'sweetalert2';
function RecuperarContra(props) {
const navigate = useNavigate();
const [Cargando, setCargando] = useState(false);
const [datosFormulario, setDatosFormulario] = useState({
correo: '',
password: '',
codigo: ''
});
const [codigoAleatorio, setCodigoAleatorio] = useState(null);
const [mostrarCodigo, setMostrarCodigo] = useState(false);
const [codigoVerificado, setCodigoVerificado] = useState(false);
useEffect(() => {
const codigo = Math.floor(100000 + Math.random() * 900000);
setCodigoAleatorio(codigo);
console.log("Código aleatorio:", codigo);
}, []);
const mostrarAlertaCambioContraExitoso = () => {
Swal.fire({
title: "Cambio de contraseña",
text: "Credenciales actualizadas correctamente",
icon: "success",
button: "Aceptar"
}).then(respuesta => {
if (respuesta) {
redirectToLogin();
}
});
};
const mostrarAlertaCambioContraFallido = () => {
Swal.fire({
title: "Correo no encontrado",
text: "El correo que introdujo no existe o se escribió incorrectamente.",
icon: "error",
button: "Aceptar"
});
};
const mostrarAlertaCodigoInvalido = () => {
Swal.fire({
title: "Código incorrecto",
text: "El código ingresado no es válido. Inténtelo de nuevo.",
icon: "error",
button: "Aceptar"
});
};
const [desactivarCorreo, setDesactivarCorreo] = useState(false);
const [cambio, setCambio] = useState(0);
const enviarCorreo = (correo, codigo) => {
const serviceID = "service_bx84r3q";
const templateID = "template_11jpkjs";
const userID = "AOcEsViQIfZLeg0HL";
const templateParams = {
to: correo,
subject: "Recuperación de contraseña",
replyto: "no-reply@example.com",
message: `Su código de verificación es: ${codigo}`
};
emailjs.send(serviceID, templateID, templateParams, userID)
.then((response) => {
console.log('Correo enviado', response.status, response.text);
})
.catch((err) => {
console.error('Error al enviar el correo', err);
});
};
const loginUsuario = async (evento) => {
evento.preventDefault();
if (cambio === 0) {
try {
const response = await axios.post('http://localhost:4567/frontend/RecuperarContra', { datosFormulario });
console.log(response.data);
if (response.data === 'Usuario encontrado') {
console.log("Sí se encontró");
enviarCorreo(datosFormulario.correo, codigoAleatorio); // Enviar correo con el código aleatorio
setMostrarCodigo(true);
setDesactivarCorreo(true);
setCambio(1);
} else {
console.log("No se encontró");
mostrarAlertaCambioContraFallido();
}
return response.data;
} catch (error) {
throw error;
}
} else if (cambio === 1) {
if (parseInt(datosFormulario.codigo) === codigoAleatorio) {
setCodigoVerificado(true);
setCambio(2);
} else {
mostrarAlertaCodigoInvalido();
}
} else if (cambio === 2) {
try {
const response = await axios.post('http://localhost:4567/frontend/ColocarContra2', { datosFormulario });
console.log(response.data);
console.log(datosFormulario);
enviarCorreo(datosFormulario.correo, codigoAleatorio); // Enviar correo confirmando el cambio de contraseña
mostrarAlertaCambioContraExitoso();
} catch (error) {
throw error;
}
}
};
const [nombre, setNombre] = useState('');
const [mostrarPopupActualizarInv, setMostrarPopupActualizarInv] = useState(false);
const abrirPopupActualizarInv = () => {
setMostrarPopupActualizarInv(true);
};
const [mostrarPopupVeri, setMostrarPopupVeri] = useState(false);
const abrirPopupVeri = () => {
setMostrarPopupVeri(true);
};
const [mostrarPopupV, setMostrarPopupV] = useState(false);
const abrirPopupV = () => {
setMostrarPopupV(true);
};
const [mostrarPopupIv, setMostrarPopupIv] = useState(false);
const abrirPopupIv = () => {
setMostrarPopupIv(true);
};
const cambiosFormulario = (evento) => {
const { name, value } = evento.target;
setDatosFormulario({ ...datosFormulario, [name]: value });
setMostrarPopupActualizarInv(false);
};
const redirectToHome = () => {
navigate("/");
};
const redirectToLogin = () => {
navigate("/Login");
};
return (
<>
<div className="cuerpo">
<div className="wrapper">
<form>
<div className="boton1">
<button type="button" className="button first-button" onClick={redirectToHome}>
<span className="button-text"></span>
<FaHome />
</button>
</div>
<h1>Recuperar Contraseña</h1>
<label htmlFor="correo" className={`label-correo ${desactivarCorreo ? 'desactivado' : ''}`}>Ingrese su correo:</label>
<div className={`input-box ${desactivarCorreo ? 'desactivado' : ''}`}>
<input
type="text"
placeholder="Correo"
onChange={cambiosFormulario}
name="correo"
value={datosFormulario.correo}
disabled={desactivarCorreo}
/>
<FaUser className="icon" />
</div>
{mostrarCodigo && (
<div>
<label htmlFor="codigo" className="label-correo">Ingrese el código enviado a su correo:</label>
<div className="input-box">
<input
type="text"
placeholder="Código"
onChange={cambiosFormulario}
name="codigo"
value={datosFormulario.codigo}
/>
<FaLock className="icon" />
</div>
</div>
)}
{codigoVerificado && (
<div>
<label htmlFor="password" className="label-correo">Nueva contraseña:</label>
<div className="input-box">
<input
type="password"
placeholder="Contraseña"
onChange={cambiosFormulario}
name="password"
value={datosFormulario.password}
/>
<FaLock className="icon" />
</div>
</div>
)}
<button className="Entrar" onClick={loginUsuario} disabled={Cargando}>
Entrar
</button>
<Box m={5}>
{mostrarPopupV && <PopupV nombre={nombre} onClose={() => setMostrarPopupV(false)} />}
</Box>
<Box m={5}>
{mostrarPopupIv && <PopupIv nombre={nombre} onClose={() => setMostrarPopupIv(false)} />}
</Box>
<Box m={5}>
{mostrarPopupVeri && <PopupActualizar nombre={nombre} onClose={() => setMostrarPopupVeri(false)} />}
</Box>
<Box m={5}>
{mostrarPopupActualizarInv && <PopupActualizarInv nombre={nombre} onClose={() => setMostrarPopupActualizarInv(false)} />}
</Box>
</form>
</div>
</div>
</>
);
}
export default RecuperarContra;

183
src/Sesion/Registrar.jsx Normal file
View File

@ -0,0 +1,183 @@
import React, { useState } from "react";
import './LoginForm.css';
import { FaUser, FaLock, FaHome } from "react-icons/fa";
import { TextField, Button, Box } from "@mui/material";
import axios from "axios";
import { useNavigate } from "react-router-dom";
import Swal from 'sweetalert2'
import PopupRegistro from "/src/Popups/PopupRegistro.jsx";
import PopupRegistroS from "/src/Popups/PopupRsindatos.jsx";
function Registrar(props){
const navigate = useNavigate();
const [Cargando, setCargando] = useState(false)
const [datosFormulario, setDatosFormulario] = useState(
{correo: '',
password: '',
nombre: ''
});
const mostrarAlertaRegistroFallido=()=>{
Swal.fire({
title: "Registro Fallido",
text: "Introduzca los datos para poder registrarse.",
icon: "error",
button: "Aceptar"
});
}
const mostrarAlertaRegistroExitoso=()=>{
Swal.fire({
title: "Registro Exitoso",
text: "Usuario registrado correctamente.",
icon: "success",
button: "Aceptar"
});
}
const mostrarAlertaCorreoExistente=()=>{
//console.log(datosFormulario.correo);
Swal.fire({
title: "Registro Fallido",
text: "El correo "+datosFormulario.correo+" ya ha sido registrado",
icon: "error",
button: "Aceptar"
});
}
const registrarUsuario = async (evento) => {
evento.preventDefault();
try{
if(datosFormulario.correo && datosFormulario.password && datosFormulario.nombre) {
const response2 = await axios.post('http://localhost:4567/frontend/correoExiste',{datosFormulario})
console.log(response2.data);
const res = response2.data;
console.log("res: "+res);
// Verificar si el correo existe
if (res.correoExistente) {
// Hacer algo si el correo existe
mostrarAlertaCorreoExistente();
setDatosFormulario({
correo: '',
password: '',
nombre: ''
});
} else {
// Hacer algo en caso de que el correo no existe
const response = await axios.post('http://localhost:4567/frontend/',{datosFormulario})
console.log(response.data)
mostrarAlertaRegistroExitoso();
setDatosFormulario({
correo: '',
password: '',
nombre: ''
});
return response.data
}
}else{
console.log("si entro");
mostrarAlertaRegistroFallido();
setDatosFormulario({
correo: '',
password: '',
nombre: ''
});
return;
}
} catch(error){
throw error
}
}
const [mostrarPopupR, setMostrarPopupR] = useState(false);
const abrirPopupR = () => {
setMostrarPopupR(true);
};
const [mostrarPopupRs, setMostrarPopupRs] = useState(false);
const abrirPopupRs = () => {
setMostrarPopupRs(true);
};
const cambiosFormulario = (evento) => {
//console.log(evento.target)
const {name,value} = evento.target
setDatosFormulario ({...datosFormulario, [name]: value})
setMostrarPopupR(false);
}
const redirectToHome = () => {
// Redirige a la página del hotel cuando se hace clic en el botón
navigate("/");
};
const redirectToLogin = () => {
// Redirige a la página del hotel cuando se hace clic en el botón
navigate("/Login");
};
return(
<>
<div className="cuerpo">
<div className="wrapper">
<form>
<div className="boton1">
<button type="button" className="button first-button" onClick={redirectToHome}>
<span className="button-text"></span>
<FaHome />
</button>
</div>
<h1>Registro</h1>
<div className="input-box">
<input type="text" placeholder="Correo" onChange={cambiosFormulario} name="correo" value={datosFormulario.correo}/>
<FaUser className="icon"/>
</div>
<div className="input-box">
<input type="password" placeholder="Contraseña" onChange={cambiosFormulario} name="password" value={datosFormulario.password}/>
<FaLock className="icon"/>
</div>
<div className="input-box">
<input type="text" placeholder="Nombre" onChange={cambiosFormulario} name="nombre" value={datosFormulario.nombre}/>
<FaUser className="icon"/>
</div>
<button className="Entrar" onClick={(evento) => registrarUsuario(evento)}>Registrar</button>
<div className="register-link">
<p>¿Tienes cuenta? <a href="" onClick={redirectToLogin}>Login</a></p>
</div>
<Box m={5}>
{mostrarPopupRs && <PopupRegistroS onClose={() => setMostrarPopupRs(false)} />}
</Box>
<Box m={5}>
{mostrarPopupR && <PopupRegistro onClose={() => setMostrarPopupR(false)} />}
</Box>
</form>
</div>
</div>
</>
)
}
export default Registrar;

BIN
src/assets/Edicion1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

BIN
src/assets/Edicion12.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

BIN
src/assets/Edicion13.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

BIN
src/assets/Edicion14.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

BIN
src/assets/Edicion15.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 KiB

BIN
src/assets/Edicion16.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

BIN
src/assets/Edicion2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

BIN
src/assets/Edicion21.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

BIN
src/assets/Edicion3.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

BIN
src/assets/Edicion4.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

BIN
src/assets/Edicion5.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

BIN
src/assets/Edicion6.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 944 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1013 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1021 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 975 KiB

BIN
src/assets/ejemplo.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 481 KiB

BIN
src/assets/pastel-fondo.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 857 KiB

BIN
src/assets/pastel-moka.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 390 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 KiB

BIN
src/assets/pastel-texto.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

BIN
src/assets/pastel-zarza.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 342 KiB

BIN
src/assets/pastel1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

1
src/assets/react.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" className="iconify iconify--logos" width="35.93" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 228"><path fill="#00D8FF" d="M210.483 73.824a171.49 171.49 0 0 0-8.24-2.597c.465-1.9.893-3.777 1.273-5.621c6.238-30.281 2.16-54.676-11.769-62.708c-13.355-7.7-35.196.329-57.254 19.526a171.23 171.23 0 0 0-6.375 5.848a155.866 155.866 0 0 0-4.241-3.917C100.759 3.829 77.587-4.822 63.673 3.233C50.33 10.957 46.379 33.89 51.995 62.588a170.974 170.974 0 0 0 1.892 8.48c-3.28.932-6.445 1.924-9.474 2.98C17.309 83.498 0 98.307 0 113.668c0 15.865 18.582 31.778 46.812 41.427a145.52 145.52 0 0 0 6.921 2.165a167.467 167.467 0 0 0-2.01 9.138c-5.354 28.2-1.173 50.591 12.134 58.266c13.744 7.926 36.812-.22 59.273-19.855a145.567 145.567 0 0 0 5.342-4.923a168.064 168.064 0 0 0 6.92 6.314c21.758 18.722 43.246 26.282 56.54 18.586c13.731-7.949 18.194-32.003 12.4-61.268a145.016 145.016 0 0 0-1.535-6.842c1.62-.48 3.21-.974 4.76-1.488c29.348-9.723 48.443-25.443 48.443-41.52c0-15.417-17.868-30.326-45.517-39.844Zm-6.365 70.984c-1.4.463-2.836.91-4.3 1.345c-3.24-10.257-7.612-21.163-12.963-32.432c5.106-11 9.31-21.767 12.459-31.957c2.619.758 5.16 1.557 7.61 2.4c23.69 8.156 38.14 20.213 38.14 29.504c0 9.896-15.606 22.743-40.946 31.14Zm-10.514 20.834c2.562 12.94 2.927 24.64 1.23 33.787c-1.524 8.219-4.59 13.698-8.382 15.893c-8.067 4.67-25.32-1.4-43.927-17.412a156.726 156.726 0 0 1-6.437-5.87c7.214-7.889 14.423-17.06 21.459-27.246c12.376-1.098 24.068-2.894 34.671-5.345a134.17 134.17 0 0 1 1.386 6.193ZM87.276 214.515c-7.882 2.783-14.16 2.863-17.955.675c-8.075-4.657-11.432-22.636-6.853-46.752a156.923 156.923 0 0 1 1.869-8.499c10.486 2.32 22.093 3.988 34.498 4.994c7.084 9.967 14.501 19.128 21.976 27.15a134.668 134.668 0 0 1-4.877 4.492c-9.933 8.682-19.886 14.842-28.658 17.94ZM50.35 144.747c-12.483-4.267-22.792-9.812-29.858-15.863c-6.35-5.437-9.555-10.836-9.555-15.216c0-9.322 13.897-21.212 37.076-29.293c2.813-.98 5.757-1.905 8.812-2.773c3.204 10.42 7.406 21.315 12.477 32.332c-5.137 11.18-9.399 22.249-12.634 32.792a134.718 134.718 0 0 1-6.318-1.979Zm12.378-84.26c-4.811-24.587-1.616-43.134 6.425-47.789c8.564-4.958 27.502 2.111 47.463 19.835a144.318 144.318 0 0 1 3.841 3.545c-7.438 7.987-14.787 17.08-21.808 26.988c-12.04 1.116-23.565 2.908-34.161 5.309a160.342 160.342 0 0 1-1.76-7.887Zm110.427 27.268a347.8 347.8 0 0 0-7.785-12.803c8.168 1.033 15.994 2.404 23.343 4.08c-2.206 7.072-4.956 14.465-8.193 22.045a381.151 381.151 0 0 0-7.365-13.322Zm-45.032-43.861c5.044 5.465 10.096 11.566 15.065 18.186a322.04 322.04 0 0 0-30.257-.006c4.974-6.559 10.069-12.652 15.192-18.18ZM82.802 87.83a323.167 323.167 0 0 0-7.227 13.238c-3.184-7.553-5.909-14.98-8.134-22.152c7.304-1.634 15.093-2.97 23.209-3.984a321.524 321.524 0 0 0-7.848 12.897Zm8.081 65.352c-8.385-.936-16.291-2.203-23.593-3.793c2.26-7.3 5.045-14.885 8.298-22.6a321.187 321.187 0 0 0 7.257 13.246c2.594 4.48 5.28 8.868 8.038 13.147Zm37.542 31.03c-5.184-5.592-10.354-11.779-15.403-18.433c4.902.192 9.899.29 14.978.29c5.218 0 10.376-.117 15.453-.343c-4.985 6.774-10.018 12.97-15.028 18.486Zm52.198-57.817c3.422 7.8 6.306 15.345 8.596 22.52c-7.422 1.694-15.436 3.058-23.88 4.071a382.417 382.417 0 0 0 7.859-13.026a347.403 347.403 0 0 0 7.425-13.565Zm-16.898 8.101a358.557 358.557 0 0 1-12.281 19.815a329.4 329.4 0 0 1-23.444.823c-7.967 0-15.716-.248-23.178-.732a310.202 310.202 0 0 1-12.513-19.846h.001a307.41 307.41 0 0 1-10.923-20.627a310.278 310.278 0 0 1 10.89-20.637l-.001.001a307.318 307.318 0 0 1 12.413-19.761c7.613-.576 15.42-.876 23.31-.876H128c7.926 0 15.743.303 23.354.883a329.357 329.357 0 0 1 12.335 19.695a358.489 358.489 0 0 1 11.036 20.54a329.472 329.472 0 0 1-11 20.722Zm22.56-122.124c8.572 4.944 11.906 24.881 6.52 51.026c-.344 1.668-.73 3.367-1.15 5.09c-10.622-2.452-22.155-4.275-34.23-5.408c-7.034-10.017-14.323-19.124-21.64-27.008a160.789 160.789 0 0 1 5.888-5.4c18.9-16.447 36.564-22.941 44.612-18.3ZM128 90.808c12.625 0 22.86 10.235 22.86 22.86s-10.235 22.86-22.86 22.86s-22.86-10.235-22.86-22.86s10.235-22.86 22.86-22.86Z"></path></svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

69
src/index.css Normal file
View File

@ -0,0 +1,69 @@
:root {
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
font-weight: 400;
color-scheme: light dark;
color: rgba(255, 255, 255, 0.87);
background-color: #242424;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
}
body {
margin: 0;
display: flex;
place-items: center;
min-width: 320px;
min-height: 100vh;
}
h1 {
font-size: 3.2em;
line-height: 1.1;
}
button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
background-color: #1a1a1a;
cursor: pointer;
transition: border-color 0.25s;
}
button:hover {
border-color: #646cff;
}
button:focus,
button:focus-visible {
outline: 4px auto -webkit-focus-ring-color;
}
@media (prefers-color-scheme: light) {
:root {
color: #213547;
background-color: #ffffff;
}
a:hover {
color: #747bff;
}
button {
background-color: #f9f9f9;
}
}

49
src/main.jsx Normal file
View File

@ -0,0 +1,49 @@
import React from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import ReactDOM from 'react-dom';
import { createRoot } from 'react-dom/client';
import AppInicio from './AppInicio.jsx'
import AdminVista from './AdminPackages/AdminVista.jsx'
import PersPastel1 from './PersPastel1.jsx'
import Pedidos from './Pedidos.jsx'
import Pasteles from './Pasteles.jsx'
import LoginForm from './Sesion/LoginForm.jsx';
import RegistrarForm from './Sesion/Registrar.jsx';
import RecuperarContraForm from './Sesion/RecuperarContraForm.jsx';
import ChocolateBlanco from './Pasteles/ChocolateBlanco.jsx';
import PastelMoka from './Pasteles/PastelMoka.jsx';
import PastelChocolate from './Pasteles/PastelChocolate.jsx';
import PastelZanahoria from './Pasteles/PastelZanahoria.jsx';
import PastelFrambuesa from './Pasteles/PastelFrambuesa.jsx';
import PastelCajeta from './Pasteles/PastelCajeta.jsx';
createRoot(document.getElementById('root')).render(
<React.StrictMode>
<Router>
<Routes>
<Route path = "/" element = {<AppInicio/>}/>
<Route path = "/PersonalizarPastel/PastelArcoiris" element = {<PersPastel1/>}/>
<Route path = "/Pedidos" element = {<Pedidos/>}/>
<Route path = "/Pasteles" element = {<Pasteles/>}/>
<Route path = "/Login" element = {<LoginForm/>}/>
<Route path = "/Registro" element = {<RegistrarForm/>}/>
<Route path = "/RecuperarContraseña" element = {<RecuperarContraForm/>}/>
<Route path = "/Pasteles/ChocolateBlanco" element = {<ChocolateBlanco/>}/>
<Route path = "/Pasteles/PastelMoka" element = {<PastelMoka/>}/>
<Route path = "/Pasteles/PastelChocolate" element = {<PastelChocolate/>}/>
<Route path = "/Pasteles/PastelZanahoria" element = {<PastelZanahoria/>}/>
<Route path = "/Pasteles/PastelFrambuesa" element = {<PastelFrambuesa/>}/>
<Route path = "/Pasteles/PastelCajeta" element = {<PastelCajeta/>}/>
<Route path = "/AdminVista" element = {<AdminVista/>}/>
</Routes>
</Router>
</React.StrictMode>,
);

7
vite.config.js Normal file
View File

@ -0,0 +1,7 @@
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
})