first commit
This commit is contained in:
@@ -0,0 +1,145 @@
|
||||
.barNavigation {
|
||||
text-align: center;
|
||||
background-color: rgb(1, 92, 184);
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.barNavigation ul {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.barNavigation li {
|
||||
transition: all 0.3s ease;
|
||||
cursor: pointer;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.barNavigation li:hover {
|
||||
background-color: #f9f9f9;
|
||||
color: rgba(0, 61, 121, 1);
|
||||
}
|
||||
|
||||
.barNavigation ul.active {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.menuToggle {
|
||||
display: none;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
cursor: pointer;
|
||||
padding: 10px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.menuToggle div {
|
||||
width: 25px;
|
||||
height: 3px;
|
||||
background-color: white;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.subMenu {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
gap: 10px;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
border-radius: 4px 4px 0 0;
|
||||
padding: 15px 0;
|
||||
}
|
||||
|
||||
.subMenu ul {
|
||||
display: none;
|
||||
position: absolute;
|
||||
flex-direction: column;
|
||||
top: 100%;
|
||||
width: 100%;
|
||||
background-color: rgba(0, 61, 121, 1);
|
||||
transition: max-height 0.3s ease, opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.subMenu.open ul {
|
||||
display: flex;
|
||||
color: rgba(0, 61, 121, 1);
|
||||
}
|
||||
|
||||
.subMenu ul:hover {
|
||||
color: #5b8cc9;
|
||||
}
|
||||
|
||||
.subMenu:hover ul {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.subMenu li {
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
.containerLinks{
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.links {
|
||||
color: white;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@media (max-width: 800px) {
|
||||
|
||||
.menuToggle {
|
||||
display: flex;
|
||||
position: relative;
|
||||
align-items: end;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.menuToggle.center {
|
||||
align-items: center;
|
||||
transform: translateX(-50%);
|
||||
left: 50%;
|
||||
}
|
||||
|
||||
.barNavigation {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.barNavigation ul {
|
||||
position: absolute;
|
||||
background-color: rgb(1, 92, 184);
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
padding: 10px 0;
|
||||
align-items: center;
|
||||
display: none;
|
||||
z-index: 1;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.barNavigation {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.barNavigation li:hover {
|
||||
background-color: rgba(0, 61, 121, 1);
|
||||
color: white;
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.subMenu ul {
|
||||
width: 90%;
|
||||
border-radius: 4px;
|
||||
position: relative;
|
||||
background-color: rgba(0, 61, 121, 1);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
'use client';
|
||||
import { useState } from "react";
|
||||
import './BarNavigation.css';
|
||||
import Link from "next/link";
|
||||
|
||||
function BarNavigation() {
|
||||
const [openMenu, setOpenMenu] = useState(false);
|
||||
const [openSubMenu, setOpenSubMenu] = useState<number | null>(null);
|
||||
|
||||
const toggleMenu = () => setOpenMenu(!openMenu);
|
||||
const toggleSubMenu = (index: number) => {
|
||||
setOpenSubMenu(openSubMenu === index ? null : index);
|
||||
};
|
||||
return (
|
||||
<nav className="barNavigation">
|
||||
<div
|
||||
className={`menuToggle ${openMenu ? 'center' : ''}`}
|
||||
onClick={toggleMenu}>
|
||||
<div></div>
|
||||
<div></div>
|
||||
<div></div>
|
||||
</div>
|
||||
|
||||
<ul className={openMenu ? "active" : ""}>
|
||||
<li className={`subMenu ${openSubMenu === 0 ? "open" : ""}`} onClick={() => toggleSubMenu(0)}>
|
||||
Inscripciones
|
||||
<ul className="containerLinks">
|
||||
<Link href="/Alta" className="links">
|
||||
<li >Alta</li>
|
||||
</Link>
|
||||
<Link href="/AgregarTiempo" className="links">
|
||||
<li >Agregar Tiempo</li>
|
||||
</Link>
|
||||
<Link href="/Inscripciones" className="links">
|
||||
<li>Inscripciones</li>
|
||||
</Link>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li className={`subMenu ${openSubMenu === 1 ? "open" : ""}`} onClick={() => toggleSubMenu(1)}>
|
||||
Servicios
|
||||
<ul>
|
||||
<Link href="/Impresiones" className="links">
|
||||
<li >
|
||||
Impresiones y Ploteo
|
||||
</li>
|
||||
</Link>
|
||||
<Link href="/AsignacionMesas" className="links">
|
||||
<li>
|
||||
Asignacion de Mesas
|
||||
</li>
|
||||
</Link>
|
||||
<Link href="/AsignacionEquipo" className="links">
|
||||
<li>
|
||||
Asignacion de Equipos
|
||||
</li>
|
||||
</Link>
|
||||
<Link href="/Monitor" className="links">
|
||||
<li>
|
||||
Monitor
|
||||
</li>
|
||||
</Link>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li className={`subMenu ${openSubMenu === 2 ? "open" : ""}`} onClick={() => toggleSubMenu(2)}>
|
||||
Equipo
|
||||
<ul >
|
||||
<Link href="/InformacionEquipo" className="links">
|
||||
<li>Informacion de Equipos</li>
|
||||
</Link>
|
||||
<Link href="/ActivosMantenimiento" className="links">
|
||||
<li >Activos y en Mantenimiento</li>
|
||||
</Link>
|
||||
<Link href="/Mensajes" className="links">
|
||||
<li>Mensajes</li>
|
||||
</Link>
|
||||
<Link href="/Programas" className="links">
|
||||
<li>Programas</li>
|
||||
</Link>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li className={`subMenu ${openSubMenu === 2 ? "open" : ""}`}>Reportes</li>
|
||||
<li className={`subMenu ${openSubMenu === 2 ? "open" : ""}`}>Quitar sancion</li>
|
||||
<li className={`subMenu ${openSubMenu === 2 ? "open" : ""}`}>Cambiar contraseña</li>
|
||||
</ul>
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
|
||||
export default BarNavigation;
|
||||
@@ -0,0 +1,12 @@
|
||||
|
||||
function Footer() {
|
||||
return (
|
||||
<footer>
|
||||
Hecho en México. Todos los derechos reservados 2025.
|
||||
Esta página puede ser reproducida con fines no lucrativos, siempre y cuando no se mutile, se cite la fuente completa y su dirección electrónica. De otra forma, requiere permiso previo por escrito de la institución.
|
||||
</footer>
|
||||
)
|
||||
}
|
||||
|
||||
export default Footer;
|
||||
//IO
|
||||
@@ -0,0 +1,34 @@
|
||||
.logo {
|
||||
position: relative;
|
||||
filter: invert(1);
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.cedetecContainer {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 300px;
|
||||
height: 100%;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.cedetecContainer::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: linear-gradient(to right, #f9f9f9, rgba(128, 128, 128, 0));
|
||||
}
|
||||
|
||||
.yellowPart {
|
||||
position: absolute;
|
||||
content: "";
|
||||
top: 0;
|
||||
left: -20px;
|
||||
width: 30%;
|
||||
height: 50%;
|
||||
min-width: 300px;
|
||||
background-color: #d59f0f;
|
||||
transform: skew(-45deg);
|
||||
z-index: 0;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import Image from "next/image";
|
||||
import "./Header.css";
|
||||
import Link from "next/link";
|
||||
|
||||
function Header() {
|
||||
return (
|
||||
<header>
|
||||
<Link href="https://www.unam.mx/" className="center">
|
||||
<Image
|
||||
className="logo"
|
||||
src="/logo_fes.png"
|
||||
alt="Logo FES"
|
||||
width={200}
|
||||
height={50}
|
||||
/>
|
||||
</Link>
|
||||
<div className="yellowPart"></div>
|
||||
<div className="cedetecContainer">
|
||||
<Image
|
||||
src="/cedetec.jpg"
|
||||
alt="Image of CEDETEC"
|
||||
width={300}
|
||||
height={71}
|
||||
/>
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
}
|
||||
|
||||
export default Header;
|
||||
//IO
|
||||
@@ -0,0 +1,6 @@
|
||||
.impressions {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
padding: 1rem;
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
'use client'
|
||||
import { useState } from "react";
|
||||
import './Impressions.css'
|
||||
function Impressions() {
|
||||
const [pages, setPages] = useState('');
|
||||
|
||||
const [error, setError] = useState('');
|
||||
const [alert, setAlert] = useState('');
|
||||
const [showError, setShowError] = useState(false);
|
||||
const [showAlert, setShowAlert] = useState(false);
|
||||
|
||||
// const handlePayment = async () => {
|
||||
// setAlert('')
|
||||
// setError('')
|
||||
// if (!studentData) {
|
||||
// setError('Error busca denuevo al estudiante');
|
||||
// return;
|
||||
// }
|
||||
// if (!pages) {
|
||||
// setError('Ingresa el numero de hojas a imprimir')
|
||||
// return;
|
||||
// }
|
||||
// try {
|
||||
// await axios.post(
|
||||
// `${url}/impressions`,
|
||||
// {
|
||||
// numAccount: numAccount,
|
||||
// pages: parseInt(pages),
|
||||
// cost: parseInt(pages),
|
||||
// },
|
||||
// { headers }
|
||||
// );
|
||||
// handleSearch()
|
||||
// setAlert('Cobro realizado correctamente');
|
||||
// setPages('')
|
||||
// } catch (error) {
|
||||
// const errorMessage = error.response?.data?.error || 'No se encontró el estudiante';
|
||||
|
||||
// if (errorMessage === 'Token inválido') {
|
||||
// handleLogout();
|
||||
// }
|
||||
|
||||
// setError(errorMessage);
|
||||
// }
|
||||
// };
|
||||
|
||||
return (
|
||||
<form
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
// handlePayment();
|
||||
}}>
|
||||
|
||||
<div className='impressions'>
|
||||
<div className='groupLabel'>
|
||||
<label className='label'>Costo: $1.00</label>
|
||||
</div>
|
||||
|
||||
<div className='groupInput'>
|
||||
<label className='label'>Hojas:</label>
|
||||
<input
|
||||
type='text'
|
||||
value={pages}
|
||||
onChange={(e) => {
|
||||
const value = e.target.value;
|
||||
if (/^\d*$/.test(value)) {
|
||||
setPages(value);
|
||||
}
|
||||
}}
|
||||
placeholder='Numero de hojas a imprimir...'
|
||||
inputMode='numeric'
|
||||
pattern='[0-9]*'
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className='groupLabel'>
|
||||
<label className='label'>Total: {pages && `$${pages}.00`}</label>
|
||||
</div>
|
||||
|
||||
<div className='containerButton'>
|
||||
<button
|
||||
className='button buttonCharge'
|
||||
type='submit'>
|
||||
Cobrar
|
||||
</button>
|
||||
|
||||
{error &&
|
||||
<div className={`messageBox error ${!showError ? 'hidden' : ''}`}>
|
||||
{error}
|
||||
</div>
|
||||
}
|
||||
{alert &&
|
||||
<div className={`messageBox success ${!showAlert ? 'hidden' : ''}`}>
|
||||
{alert}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
)
|
||||
}
|
||||
|
||||
export default Impressions
|
||||
@@ -0,0 +1,19 @@
|
||||
.login {
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.relative {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.eyeClose,
|
||||
.eyeOpen {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
bottom: -1px;
|
||||
transform: translateY(-50%);
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background-size: cover;
|
||||
cursor: pointer;
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
import "./Login.css";
|
||||
|
||||
function Login() {
|
||||
return (
|
||||
<section className='containerSection'>
|
||||
|
||||
<form
|
||||
className='login'
|
||||
//onSubmit={(e) => {
|
||||
//e.preventDefault();
|
||||
//handleLogin();
|
||||
//</section>}}
|
||||
>
|
||||
<h2 className='textHeader'>Inicio de sesión</h2>
|
||||
|
||||
<div className='containerInput'>
|
||||
<label className='label'>Usuario</label>
|
||||
<input
|
||||
type='text'
|
||||
//value={user}
|
||||
//onChange={(e) => setUser(e.target.value)}
|
||||
placeholder='Coloca tu usuario...'
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className='containerInput relative'>
|
||||
<label className='label'>Contraseña</label>
|
||||
<input
|
||||
//type={showPassword ? 'text' : 'password'}
|
||||
//value={password}
|
||||
//onChange={(e) => setPassword(e.target.value)}
|
||||
placeholder='Coloca tu contraseña...'
|
||||
/>
|
||||
<span
|
||||
//onClick={() => setShowPassword(!showPassword)}
|
||||
//className={showPassword ? 'eyeOpen' : 'eyeClose'}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<button
|
||||
className='button buttonSearch'
|
||||
style={{ maxWidth: '100%', width: '100%' }}
|
||||
type='submit'
|
||||
>Iniciar sesión
|
||||
</button>
|
||||
</form>
|
||||
{/*message &&
|
||||
<div
|
||||
className={`messageBox ${message.includes('exitoso') ? 'success' : 'error'}`}
|
||||
style={{ marginTop: '10px' }}
|
||||
>
|
||||
{message}
|
||||
</div>
|
||||
*/}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
export default Login;
|
||||
@@ -0,0 +1,128 @@
|
||||
'use client'
|
||||
import { useEffect, useState } from "react";
|
||||
import "./Receipt.css"
|
||||
import Selection from "../Selection/Selection";
|
||||
|
||||
function Receipt() {
|
||||
const [folio, setFolio] = useState('');
|
||||
const [amount, setAmount] = useState('');
|
||||
const [date, setDate] = useState('');
|
||||
|
||||
const [error, setError] = useState('');
|
||||
const [alert, setAlert] = useState('');
|
||||
const [showError, setShowError] = useState(false);
|
||||
const [showAlert, setShowAlert] = useState(false);
|
||||
|
||||
//restrict this month//
|
||||
const day = new Date();
|
||||
const year = day.getFullYear();
|
||||
const month = day.getMonth();
|
||||
const today = day.getDate();
|
||||
|
||||
const minFecha = new Date(year, month, 1).toISOString().split('T')[0];
|
||||
const maxFecha = new Date(year, month, today).toISOString().split('T')[0];
|
||||
//restrict this month//
|
||||
|
||||
//fadeOut alert and error
|
||||
useEffect(() => {
|
||||
if (alert) {
|
||||
setShowAlert(true);
|
||||
const timeout = setTimeout(() => {
|
||||
setShowAlert(false);
|
||||
setTimeout(() => setAlert(''), 500);
|
||||
}, 6000);
|
||||
return () => clearTimeout(timeout);
|
||||
}
|
||||
}, [alert]);
|
||||
|
||||
useEffect(() => {
|
||||
if (error) {
|
||||
setShowError(true);
|
||||
const timeout = setTimeout(() => {
|
||||
setShowError(false);
|
||||
setTimeout(() => setError(''), 500);
|
||||
}, 6000);
|
||||
return () => clearTimeout(timeout);
|
||||
}
|
||||
}, [error]);
|
||||
//fadeOut alert and error//
|
||||
|
||||
return (
|
||||
<form
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
// handleSaveReceipt();
|
||||
}}
|
||||
>
|
||||
<div className='groupInput'>
|
||||
<label className='label'>Folio:</label>
|
||||
<input
|
||||
type='text'
|
||||
value={folio}
|
||||
onChange={(e) => {
|
||||
const value = e.target.value;
|
||||
if (/^\d*$/.test(value)) {
|
||||
setFolio(value);
|
||||
}
|
||||
}}
|
||||
placeholder='Numero de folio...'
|
||||
inputMode='numeric'
|
||||
pattern='[0-9]*'
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className='groupInput'>
|
||||
<label className='label'>Monto:</label>
|
||||
<input
|
||||
type='text'
|
||||
value={amount}
|
||||
onChange={(e) => {
|
||||
const value = e.target.value;
|
||||
|
||||
if (/^\d*\.?\d*$/.test(value)) {
|
||||
const numericValue = parseFloat(value);
|
||||
|
||||
if (value === '' || (numericValue <= 1000)) {
|
||||
setAmount(value);
|
||||
} else {
|
||||
setAlert('')
|
||||
setError('El monto no puede superar $1000.00')
|
||||
}
|
||||
}
|
||||
}}
|
||||
placeholder='Monto recibido...'
|
||||
inputMode='numeric'
|
||||
pattern="^\d*\.?\d+$"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className='groupInput'>
|
||||
<label className='label'>Fecha de Pago:</label>
|
||||
<input
|
||||
type='date'
|
||||
value={date}
|
||||
onChange={(e) => setDate(e.target.value)}
|
||||
min={minFecha}
|
||||
max={maxFecha}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className='containerButton'>
|
||||
|
||||
{error &&
|
||||
<div className={`messageBox error ${!showError ? 'hidden' : ''}`}>
|
||||
{error}
|
||||
</div>
|
||||
}
|
||||
{alert &&
|
||||
<div className={`messageBox success ${!showAlert ? 'hidden' : ''}`}>
|
||||
{alert}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</form>
|
||||
)
|
||||
}
|
||||
|
||||
export default Receipt
|
||||
//IO
|
||||
@@ -0,0 +1,42 @@
|
||||
'use client'
|
||||
import { useState } from "react";
|
||||
|
||||
function SearchUser() {
|
||||
const [numAccount, setNumAccount] = useState('');
|
||||
return (
|
||||
<>
|
||||
<form>
|
||||
<label className='label'>No.Cuenta</label>
|
||||
<div className='groupInput'>
|
||||
<input
|
||||
type='text'
|
||||
value={numAccount}
|
||||
onChange={(e) => {
|
||||
const value = e.target.value;
|
||||
if (/^\d*$/.test(value) && value.length <= 9) {
|
||||
setNumAccount(value);
|
||||
}
|
||||
}}
|
||||
placeholder='Coloca un número de cuenta...'
|
||||
inputMode='numeric'
|
||||
pattern='[0-9]*'
|
||||
/>
|
||||
<button
|
||||
className='button buttonSearch'
|
||||
type='submit'
|
||||
>Buscar
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div className='information'>
|
||||
<label><b>No.Cuenta: </b>id_cuenta</label>
|
||||
<label><b>Nombre: </b>nombre</label>
|
||||
<label><b>Carrera: </b>carrera</label>
|
||||
<label><b>Crédito: </b>credito</label>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default SearchUser
|
||||
@@ -0,0 +1,41 @@
|
||||
.selection {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin: 10px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.selectionItem {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.buttonSelection {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border-radius: 100%;
|
||||
border: 2px solid #5b8cc9;
|
||||
background-color: #f0f0f0;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.buttonSelection:hover {
|
||||
transform: scale(1.1);
|
||||
background-color: #d0e1ff;
|
||||
}
|
||||
|
||||
.buttonSelection.active {
|
||||
background-color: #5b8cc9;
|
||||
box-shadow: 0 0 10px #5b8cc9;
|
||||
}
|
||||
|
||||
.buttonLabel {
|
||||
margin-top: 8px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
text-align: center;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
'use client';
|
||||
|
||||
import { useState } from "react";
|
||||
import "./Selection.css";
|
||||
|
||||
function Selection() {
|
||||
const [selected, setSelected] = useState<string | null>(null);
|
||||
|
||||
const options = [
|
||||
{
|
||||
name: "WINDOWS",
|
||||
img: "https://images.icon-icons.com/2235/PNG/512/windows_os_logo_icon_134678.png",
|
||||
},
|
||||
{
|
||||
name: "MACINTOSH",
|
||||
img: "https://upload.wikimedia.org/wikipedia/commons/f/fa/Apple_logo_black.svg",
|
||||
},
|
||||
{
|
||||
name: "LINUX",
|
||||
img: "https://upload.wikimedia.org/wikipedia/commons/3/35/Tux.svg",
|
||||
},
|
||||
{
|
||||
name: "PROFESORES",
|
||||
img: "https://cdn-icons-png.flaticon.com/512/3135/3135715.png",
|
||||
},
|
||||
];
|
||||
|
||||
const handleSelect = (optionName: string) => {
|
||||
setSelected(selected === optionName ? null : optionName);
|
||||
};
|
||||
|
||||
return (
|
||||
<section className="selection">
|
||||
{options.map((option, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="selectionItem"
|
||||
onClick={() => handleSelect(option.name)}
|
||||
>
|
||||
<button
|
||||
className={`buttonSelection ${selected === option.name ? "active" : ""}`}
|
||||
>
|
||||
<img
|
||||
src={option.img}
|
||||
alt={option.name.toLowerCase()}
|
||||
height={30}
|
||||
width={30}
|
||||
/>
|
||||
</button>
|
||||
<span className="buttonLabel">{option.name}</span>
|
||||
</div>
|
||||
))}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
export default Selection;
|
||||
@@ -0,0 +1,10 @@
|
||||
.receipt {
|
||||
max-width: 600px;
|
||||
margin-top: 1rem;
|
||||
border: 1px solid #e5e7eb;
|
||||
border-radius: 4px;
|
||||
background-color: #f9fafb;
|
||||
padding: 1rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
'use client'
|
||||
|
||||
import { useState, ReactNode } from "react";
|
||||
import "./StepNavigator.css"
|
||||
|
||||
interface StepNavigatorProps {
|
||||
totalSteps: number;
|
||||
children: ReactNode[];
|
||||
onFinish?: () => void;
|
||||
}
|
||||
|
||||
export default function StepNavigator({ totalSteps, children, onFinish }: StepNavigatorProps) {
|
||||
const [step, setStep] = useState(1);
|
||||
|
||||
const handleNext = (e: React.MouseEvent<HTMLButtonElement>) => {
|
||||
e.preventDefault();
|
||||
if (step < totalSteps) setStep(step + 1);
|
||||
else if (onFinish) onFinish();
|
||||
};
|
||||
|
||||
const handlePrev = (e: React.MouseEvent<HTMLButtonElement>) => {
|
||||
e.preventDefault();
|
||||
if (step > 1) setStep(step - 1);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="receipt">
|
||||
{children[step - 1]}
|
||||
|
||||
<div className="buttonContainer">
|
||||
{step > 1 && (
|
||||
<button
|
||||
onClick={handlePrev}
|
||||
className="button buttonSearch">
|
||||
Atrás
|
||||
</button>
|
||||
)}
|
||||
|
||||
<button
|
||||
onClick={handleNext}
|
||||
className="button buttonSearch"
|
||||
>
|
||||
{step === totalSteps ? "Inscribir" : "Siguiente"}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user