no se que modificaciones se hizo posible error
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { usersApi } from '../api/client';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { usersApi, settingsApi } from '../api/client';
|
||||
|
||||
const SHEET_LABELS = {
|
||||
ventas: 'Ventas',
|
||||
@@ -22,12 +23,30 @@ export default function AdminPage() {
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState('');
|
||||
const [newUser, setNewUser] = useState({ username: '', password: '', permissions: emptyPerms() });
|
||||
const [gestion, setGestion] = useState(null);
|
||||
const [fechaCierre, setFechaCierre] = useState('');
|
||||
const [gestionMsg, setGestionMsg] = useState('');
|
||||
const [gestionError, setGestionError] = useState('');
|
||||
const location = useLocation();
|
||||
|
||||
const load = async () => {
|
||||
setError('');
|
||||
setGestionError('');
|
||||
try {
|
||||
setUsers(await usersApi.list());
|
||||
} catch (e) {
|
||||
setError(e.message);
|
||||
}
|
||||
try {
|
||||
const gestionData = await settingsApi.getGestion();
|
||||
setGestion(gestionData);
|
||||
setFechaCierre(gestionData.sugerirCierre || gestionData.fechaCierreGestion || '');
|
||||
} catch (e) {
|
||||
setGestionError(
|
||||
e.message.includes('404') || e.message.includes('Error en la solicitud')
|
||||
? 'No se pudo cargar el cierre de gestión. Reconstruya Docker: docker compose build --no-cache && docker compose up -d'
|
||||
: e.message
|
||||
);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
@@ -37,6 +56,12 @@ export default function AdminPage() {
|
||||
load();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (location.hash === '#cierre-gestion') {
|
||||
document.getElementById('cierre-gestion')?.scrollIntoView({ behavior: 'smooth' });
|
||||
}
|
||||
}, [location.hash, loading]);
|
||||
|
||||
const handleCreate = async (e) => {
|
||||
e.preventDefault();
|
||||
setError('');
|
||||
@@ -69,18 +94,112 @@ export default function AdminPage() {
|
||||
}
|
||||
};
|
||||
|
||||
if (loading) return <p className="loading">Cargando usuarios…</p>;
|
||||
const cerrarGestion = async (e) => {
|
||||
e.preventDefault();
|
||||
if (!fechaCierre) {
|
||||
setError('Indique el último día de la gestión a cerrar.');
|
||||
return;
|
||||
}
|
||||
const etiqueta = gestion?.gestionActual?.fechaInicio
|
||||
? `del ${gestion.gestionActual.fechaInicio} al ${fechaCierre}`
|
||||
: `hasta el ${fechaCierre}`;
|
||||
if (
|
||||
!window.confirm(
|
||||
`¿Cerrar la gestión ${etiqueta}?\n\nSe bloqueará el período para todos (excepto JEFE) y comenzará una gestión nueva. El historial quedará en la barra lateral de cada planilla.`
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
setGestionMsg('');
|
||||
setError('');
|
||||
try {
|
||||
const data = await settingsApi.cerrarGestion(fechaCierre);
|
||||
setGestion(data);
|
||||
setFechaCierre(data.sugerirCierre || '');
|
||||
const nombre = data.cierre?.cerrada?.etiqueta || 'gestión cerrada';
|
||||
setGestionMsg(`"${nombre}" cerrada. Nueva gestión desde ${data.cierre?.nueva?.fechaInicio || 'mañana'}.`);
|
||||
} catch (err) {
|
||||
setError(err.message);
|
||||
}
|
||||
};
|
||||
|
||||
if (loading) return <p className="loading">Cargando administración…</p>;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1 className="page-title">Administración de usuarios</h1>
|
||||
<h1 className="page-title">Administración</h1>
|
||||
<p style={{ color: 'var(--muted)' }}>
|
||||
El superusuario <strong>JEFE</strong> puede crear usuarios, asignar contraseñas y habilitar acceso por planilla.
|
||||
Solo visible para el administrador <strong>JEFE</strong>. Gestione el cierre del período y los usuarios.
|
||||
</p>
|
||||
{error && <div className="alert alert-error">{error}</div>}
|
||||
|
||||
<div className="card admin-grid" style={{ marginBottom: '1.5rem' }}>
|
||||
<h2 style={{ marginTop: 0 }}>Nuevo usuario</h2>
|
||||
<nav className="admin-subnav">
|
||||
<a href="#cierre-gestion" className="admin-subnav__link admin-subnav__link--active">
|
||||
Cierre de gestión
|
||||
</a>
|
||||
<a href="#usuarios" className="admin-subnav__link">
|
||||
Usuarios
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
{error && <div className="alert alert-error">{error}</div>}
|
||||
{gestionMsg && <div className="alert alert-success">{gestionMsg}</div>}
|
||||
|
||||
<div id="cierre-gestion" className="card card-highlight admin-grid" style={{ marginBottom: '1.5rem' }}>
|
||||
<h2 style={{ marginTop: 0 }}>Cierre de gestión</h2>
|
||||
{gestionError && <div className="alert alert-error">{gestionError}</div>}
|
||||
|
||||
<div className="alert alert-info" style={{ fontSize: '0.88rem', lineHeight: 1.6 }}>
|
||||
<strong>¿Cómo funciona?</strong>
|
||||
<ul style={{ margin: '0.5rem 0 0', paddingLeft: '1.2rem' }}>
|
||||
<li>Al <strong>cerrar la gestión</strong> (típicamente fin de mes), el período queda bloqueado de inmediato.</li>
|
||||
<li>Cada planilla muestra solo la <strong>gestión actual</strong>; el historial está en la <strong>barra lateral</strong> (solo lectura).</li>
|
||||
<li>La nueva gestión comienza el día siguiente al cierre. Use el botón <strong>+</strong> para cargar datos nuevos.</li>
|
||||
<li>Filas con fecha del período cerrado no se pueden editar (excepto JEFE).</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{gestion?.gestionActual && (
|
||||
<p style={{ fontSize: '0.85rem', marginBottom: '1rem' }}>
|
||||
Gestión actual: desde <strong>{gestion.gestionActual.fechaInicio}</strong> — Hoy:{' '}
|
||||
<strong>{gestion.hoy}</strong>
|
||||
</p>
|
||||
)}
|
||||
|
||||
{gestion?.historial?.length > 0 && (
|
||||
<div style={{ marginBottom: '1rem' }}>
|
||||
<p style={{ fontSize: '0.85rem', marginBottom: '0.5rem' }}>
|
||||
<strong>Gestiones cerradas:</strong>
|
||||
</p>
|
||||
<ul style={{ margin: 0, paddingLeft: '1.2rem', fontSize: '0.85rem' }}>
|
||||
{gestion.historial.map((g) => (
|
||||
<li key={g.id}>
|
||||
{g.etiqueta} ({g.fechaInicio} → {g.fechaFin})
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<form onSubmit={cerrarGestion}>
|
||||
<div className="form-group">
|
||||
<label>Último día de la gestión a cerrar</label>
|
||||
<input type="date" value={fechaCierre} onChange={(e) => setFechaCierre(e.target.value)} required />
|
||||
{gestion?.sugerirCierre && (
|
||||
<p style={{ fontSize: '0.8rem', color: 'var(--muted)', marginTop: '0.35rem' }}>
|
||||
Sugerido (fin de mes): {gestion.sugerirCierre}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<div className="toolbar">
|
||||
<button type="submit" className="btn btn-primary">
|
||||
Cerrar gestión
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="usuarios" className="card admin-grid" style={{ marginBottom: '1.5rem' }}>
|
||||
<h2 style={{ marginTop: 0 }}>Usuarios — Nuevo usuario</h2>
|
||||
<form onSubmit={handleCreate}>
|
||||
<div className="form-group">
|
||||
<label>Usuario</label>
|
||||
|
||||
Reference in New Issue
Block a user