Primera version para produccion

This commit is contained in:
2025-08-04 11:05:41 -06:00
parent 0dac802736
commit 4bc8a92021
8 changed files with 747 additions and 100 deletions

View File

@@ -9,6 +9,7 @@ const MICROSERVICE_URL = import.meta.env.VITE_EFC_MICROSERVICE_URL;
export default function Procesos() {
const [procesos, setProcesos] = useState([]);
const [loading, setLoading] = useState(true);
@@ -21,6 +22,10 @@ export default function Procesos() {
const [estadoFilter, setEstadoFilter] = useState('');
const [servicioFilter, setServicioFilter] = useState('');
// Sorting
const [sortField, setSortField] = useState('');
const [sortOrder, setSortOrder] = useState('asc'); // 'asc' | 'desc'
// Estado para loading de ejecución de servicio
const [executingId, setExecutingId] = useState(null);
@@ -34,6 +39,9 @@ export default function Procesos() {
let endpoint = '';
// Determinar endpoint según el tipo de servicio
switch (proc.servicio) {
case 3:
endpoint = '/services/pedimento_completo';
break;
case 4: // Partidas
endpoint = '/services/partidas';
break;
@@ -43,7 +51,10 @@ export default function Procesos() {
case 6: // Acuse
endpoint = '/services/acuse';
break;
case 8: // Acuse Cove
case 8: // Coves
endpoint = '/services/Coves';
break;
case 9: // Acuse Cove
endpoint = '/services/acuseCove';
break;
default:
@@ -102,7 +113,9 @@ export default function Procesos() {
if (pedimentoPedimentoFilter) params.append('pedimento__pedimento', pedimentoPedimentoFilter);
if (estadoFilter) params.append('estado', estadoFilter);
if (servicioFilter) params.append('servicio', servicioFilter);
// ...existing code...
if (sortField) {
params.append('ordering', (sortOrder === 'desc' ? '-' : '') + sortField);
}
const API_URL = import.meta.env.VITE_EFC_API_URL;
const headers = token ? { 'Authorization': `Bearer ${token}` } : {};
const res = await fetch(`${API_URL}/customs/procesamientopedimentos/?${params.toString()}`, { headers });
@@ -117,7 +130,7 @@ export default function Procesos() {
}
}
fetchProcesos();
}, [page, itemsPerPage, pedimentoPedimentoFilter, estadoFilter, servicioFilter]);
}, [page, itemsPerPage, pedimentoPedimentoFilter, estadoFilter, servicioFilter, sortField, sortOrder]);
return (
<div className="p-6 bg-gray-50 min-h-screen">
@@ -131,6 +144,9 @@ export default function Procesos() {
<div>
<h1 className="text-3xl font-extrabold text-blue-900 tracking-tight mb-1 flex items-center gap-2">
Procesos del Sistema
<span className="inline-block bg-blue-200 text-blue-800 text-xs font-semibold px-2 py-0.5 rounded-full ml-2 animate-fade-in" title="Total de procesos">
{count}
</span>
</h1>
<p className="text-lg text-blue-700/80 font-medium">Estado actual de los procesos de la agencia aduanal</p>
</div>
@@ -160,10 +176,19 @@ export default function Procesos() {
.animate-fadein-slideup {
animation: fadein-slideup 0.7s cubic-bezier(0.22,1,0.36,1) 0.05s forwards;
}
@keyframes fade-in {
from { opacity: 0; transform: scale(0.9); }
to { opacity: 1; transform: scale(1); }
}
.animate-fade-in {
animation: fade-in 0.7s ease;
}
`}</style>
</div>
<div className="bg-white rounded-xl shadow-lg border border-gray-200 p-8 animate-fadein-slideup opacity-0" style={{ animation: 'fadein-slideup 0.7s cubic-bezier(0.22,1,0.36,1) 0.15s forwards' }}>
<h2 className="text-2xl font-bold text-blue-800 mb-6">Procesamiento de Pedimentos</h2>
<div className="flex items-center justify-between mb-2">
<h2 className="text-2xl font-bold text-blue-800">Procesamiento de Pedimentos</h2>
</div>
{/* Filtros */}
<div className="mb-4 flex flex-wrap gap-4 items-end justify-between">
<div className="flex flex-col flex-1 min-w-[150px]">
@@ -206,9 +231,10 @@ export default function Procesos() {
<option value="6">Acuse</option>
<option value="7">EDocument</option>
<option value="8">Cove</option>
<option value="9">Acuse Cove</option>
</select>
</div>
{/* ...filtros anteriores... */}
</div>
{loading ? (
<div className="text-center text-gray-500 py-8">Cargando procesos...</div>
@@ -220,14 +246,51 @@ export default function Procesos() {
<table className="min-w-full divide-y divide-gray-200 rounded-lg overflow-hidden sticky text-xs">
<thead className="bg-gradient-to-r from-gray-50 sticky top-0 z-20">
<tr>
<th className="px-2 py-2 text-center font-bold text-blue-700 uppercase tracking-wider border-b border-gray-200 whitespace-nowrap">ID</th>
<th className="px-2 py-2 text-left font-bold uppercase tracking-wider border-b border-gray-200 whitespace-nowrap">Organización</th>
<th className="px-2 py-2 text-left font-bold uppercase tracking-wider border-b border-gray-200 whitespace-nowrap">Estado</th>
<th className="px-2 py-2 text-left font-bold uppercase tracking-wider border-b border-gray-200 whitespace-nowrap">Pedimento</th>
<th className="px-2 py-2 text-left font-bold uppercase tracking-wider border-b border-gray-200 whitespace-nowrap">Servicio</th>
<th className="px-2 py-2 text-center font-bold text-blue-700 uppercase tracking-wider border-b border-gray-200 whitespace-nowrap">Acciones</th>
</tr>
</thead>
<th className="px-2 py-2 text-center font-bold text-blue-700 uppercase tracking-wider border-b border-gray-200 whitespace-nowrap cursor-pointer select-none"
onClick={() => {
setSortField('id');
setSortOrder(sortField === 'id' && sortOrder === 'asc' ? 'desc' : 'asc');
}}
>
ID {sortField === 'id' && (sortOrder === 'asc' ? '▲' : '▼')}
</th>
<th className="px-2 py-2 text-left font-bold uppercase tracking-wider border-b border-gray-200 whitespace-nowrap cursor-pointer select-none"
onClick={() => {
setSortField('organizacion_name');
setSortOrder(sortField === 'organizacion_name' && sortOrder === 'asc' ? 'desc' : 'asc');
}}
>
Organización {sortField === 'organizacion_name' && (sortOrder === 'asc' ? '▲' : '▼')}
</th>
<th className="px-2 py-2 text-left font-bold uppercase tracking-wider border-b border-gray-200 whitespace-nowrap cursor-pointer select-none"
onClick={() => {
setSortField('estado');
setSortOrder(sortField === 'estado' && sortOrder === 'asc' ? 'desc' : 'asc');
}}
>
Estado {sortField === 'estado' && (sortOrder === 'asc' ? '▲' : '▼')}
</th>
<th className="px-2 py-2 text-left font-bold uppercase tracking-wider border-b border-gray-200 whitespace-nowrap cursor-pointer select-none"
onClick={() => {
setSortField('pedimento');
setSortOrder(sortField === 'pedimento' && sortOrder === 'asc' ? 'desc' : 'asc');
}}
>
Pedimento {sortField === 'pedimento' && (sortOrder === 'asc' ? '▲' : '▼')}
</th>
<th className="px-2 py-2 text-left font-bold uppercase tracking-wider border-b border-gray-200 whitespace-nowrap cursor-pointer select-none"
onClick={() => {
setSortField('servicio');
setSortOrder(sortField === 'servicio' && sortOrder === 'asc' ? 'desc' : 'asc');
}}
>
Servicio {sortField === 'servicio' && (sortOrder === 'asc' ? '▲' : '▼')}
</th>
<th className="px-2 py-2 text-center font-bold text-blue-700 uppercase tracking-wider border-b border-gray-200 whitespace-nowrap">
Acciones
</th>
</tr>
</thead>
<tbody className="bg-white divide-y divide-gray-100" style={{ position: 'relative', minHeight: 'calc(12 * 40px)' }}>
{procesos.length === 0 ? (
<tr>
@@ -259,6 +322,7 @@ export default function Procesos() {
: proc.servicio === 6 ? 'Acuse'
: proc.servicio === 7 ? 'EDocument'
: proc.servicio === 8 ? 'Cove'
: proc.servicio === 9 ? 'Acuse Cove'
: String(proc.servicio)
}</td>
<td className="px-2 py-2 text-center align-middle whitespace-nowrap">
@@ -277,11 +341,21 @@ export default function Procesos() {
<button
className="block w-full text-left px-4 py-2 text-xs text-blue-700 hover:bg-blue-100 disabled:opacity-60"
onClick={() => handleEjecutarServicio(proc)}
disabled={executingId === proc.id}
disabled={
executingId === proc.id ||
proc.estado === 2 || // Procesando
proc.estado === 3 || // Finalizado
proc.estado === 4 // Error
}
>
{executingId === proc.id ? 'Ejecutando...' : 'Ejecutar Servicio'}
</button>
<button className="block w-full text-left px-4 py-2 text-xs text-gray-700 hover:bg-blue-100">Pasar a espera</button>
<button
className={`block w-full text-left px-4 py-2 text-xs text-gray-700 hover:bg-blue-100${(proc.estado === 2 || proc.estado === 4) ? '' : ' opacity-50 cursor-not-allowed'}`}
disabled={!(proc.estado === 2 || proc.estado === 4)}
>
Pasar a espera
</button>
<button className="block w-full text-left px-4 py-2 text-xs text-gray-700 hover:bg-blue-100">Editar</button>
</div>
</div>