se modificaron filtros y campos de expedientes, se agrego paginacion
se modificaron algunos campos de la tabla de pedimentoDetail. de igualforma se modificadron los filtros se modifico el filtrado de pedimento en Procesos.jsx y se modifico el filtrado
This commit is contained in:
@@ -235,7 +235,7 @@ export default function Documents() {
|
|||||||
className="w-full border border-gray-300 rounded-xl px-3 py-2.5 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 bg-white shadow-sm transition-all duration-200 hover:shadow-md"
|
className="w-full border border-gray-300 rounded-xl px-3 py-2.5 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 bg-white shadow-sm transition-all duration-200 hover:shadow-md"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{/* Pedimento */}
|
{/* Pedimento_app */}
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<label className="text-xs font-semibold text-gray-700 mb-1.5">Pedimento</label>
|
<label className="text-xs font-semibold text-gray-700 mb-1.5">Pedimento</label>
|
||||||
<input
|
<input
|
||||||
@@ -418,9 +418,9 @@ export default function Documents() {
|
|||||||
<th className="px-4 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider border-b border-gray-200">Fecha de pago</th>
|
<th className="px-4 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider border-b border-gray-200">Fecha de pago</th>
|
||||||
<th className="px-4 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider border-b border-gray-200">Contribuyente</th>
|
<th className="px-4 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider border-b border-gray-200">Contribuyente</th>
|
||||||
<th className="px-4 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider border-b border-gray-200">CURP Apoderado</th>
|
<th className="px-4 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider border-b border-gray-200">CURP Apoderado</th>
|
||||||
<th className="px-4 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider border-b border-gray-200">Importe total</th>
|
<th className="px-4 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider border-b border-gray-200">Partidas</th>
|
||||||
<th className="px-4 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider border-b border-gray-200">Saldo disponible</th>
|
<th className="px-4 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider border-b border-gray-200">Saldo disponible</th>
|
||||||
<th className="px-4 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider border-b border-gray-200">Importe pedimento_app</th>
|
<th className="px-4 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider border-b border-gray-200">Importe pedimento</th>
|
||||||
<th className="px-4 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider border-b border-gray-200">Expediente</th>
|
<th className="px-4 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider border-b border-gray-200">Expediente</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@@ -455,13 +455,13 @@ export default function Documents() {
|
|||||||
to={`/expedientes/pedimento/${ped.id}`}
|
to={`/expedientes/pedimento/${ped.id}`}
|
||||||
className="text-blue-600 hover:text-blue-800 font-semibold transition-colors duration-200 group-hover:underline"
|
className="text-blue-600 hover:text-blue-800 font-semibold transition-colors duration-200 group-hover:underline"
|
||||||
>
|
>
|
||||||
{ped.pedimento}
|
{ped.pedimento_app}
|
||||||
</Link>
|
</Link>
|
||||||
</td>
|
</td>
|
||||||
<td className="px-4 py-4 whitespace-nowrap text-sm text-gray-700">{ped.fecha_pago}</td>
|
<td className="px-4 py-4 whitespace-nowrap text-sm text-gray-700">{ped.fecha_pago}</td>
|
||||||
<td className="px-4 py-4 whitespace-nowrap text-sm text-gray-700 max-w-xs truncate" title={ped.contribuyente}>{ped.contribuyente}</td>
|
<td className="px-4 py-4 whitespace-nowrap text-sm text-gray-700 max-w-xs truncate" title={ped.contribuyente}>{ped.contribuyente}</td>
|
||||||
<td className="px-4 py-4 whitespace-nowrap text-sm text-gray-700">{ped.curp_apoderado}</td>
|
<td className="px-4 py-4 whitespace-nowrap text-sm text-gray-700">{ped.curp_apoderado}</td>
|
||||||
<td className="px-4 py-4 whitespace-nowrap text-sm text-gray-900 font-semibold">${ped.importe_total}</td>
|
<td className="px-4 py-4 whitespace-nowrap text-sm text-gray-900 font-semibold">{ped.numero_partidas}</td>
|
||||||
<td className="px-4 py-4 whitespace-nowrap text-sm text-gray-900 font-semibold">${ped.saldo_disponible}</td>
|
<td className="px-4 py-4 whitespace-nowrap text-sm text-gray-900 font-semibold">${ped.saldo_disponible}</td>
|
||||||
<td className="px-4 py-4 whitespace-nowrap text-sm text-gray-900 font-semibold">${ped.importe_pedimento_app}</td>
|
<td className="px-4 py-4 whitespace-nowrap text-sm text-gray-900 font-semibold">${ped.importe_pedimento_app}</td>
|
||||||
<td className="px-4 py-4 whitespace-nowrap">
|
<td className="px-4 py-4 whitespace-nowrap">
|
||||||
@@ -540,7 +540,7 @@ export default function Documents() {
|
|||||||
to={`/expedientes/pedimento/${ped.id}`}
|
to={`/expedientes/pedimento/${ped.id}`}
|
||||||
className="text-lg font-semibold text-blue-600 hover:text-blue-800 transition-colors duration-200"
|
className="text-lg font-semibold text-blue-600 hover:text-blue-800 transition-colors duration-200"
|
||||||
>
|
>
|
||||||
{ped.pedimento}
|
{ped.pedimento_app}
|
||||||
</Link>
|
</Link>
|
||||||
<p className="text-sm text-gray-500">{ped.fechapago}</p>
|
<p className="text-sm text-gray-500">{ped.fechapago}</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -569,15 +569,15 @@ export default function Documents() {
|
|||||||
)}
|
)}
|
||||||
<div className="grid grid-cols-1 gap-2">
|
<div className="grid grid-cols-1 gap-2">
|
||||||
<div className="flex items-center justify-between bg-green-50 rounded-lg p-2">
|
<div className="flex items-center justify-between bg-green-50 rounded-lg p-2">
|
||||||
<span className="text-sm font-medium text-green-700">Importe total:</span>
|
<span className="text-sm font-medium text-green-700">Partidas</span>
|
||||||
<span className="text-sm font-bold text-green-800">${ped.importe_total}</span>
|
<span className="text-sm font-bold text-green-800">${ped.numero_partidas}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center justify-between bg-blue-50 rounded-lg p-2">
|
<div className="flex items-center justify-between bg-blue-50 rounded-lg p-2">
|
||||||
<span className="text-sm font-medium text-blue-700">Saldo disponible:</span>
|
<span className="text-sm font-medium text-blue-700">Saldo disponible:</span>
|
||||||
<span className="text-sm font-bold text-blue-800">${ped.saldo_disponible}</span>
|
<span className="text-sm font-bold text-blue-800">${ped.saldo_disponible}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center justify-between bg-gray-50 rounded-lg p-2">
|
<div className="flex items-center justify-between bg-gray-50 rounded-lg p-2">
|
||||||
<span className="text-sm font-medium text-gray-700">Importe pedimento_app:</span>
|
<span className="text-sm font-medium text-gray-700">Importe pedimento:</span>
|
||||||
<span className="text-sm font-bold text-gray-800">${ped.importe_pedimento_app}</span>
|
<span className="text-sm font-bold text-gray-800">${ped.importe_pedimento_app}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -326,6 +326,21 @@ const [docsPrev, setDocsPrev] = useState(null);
|
|||||||
setPreviewXmlHtml('');
|
setPreviewXmlHtml('');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Lógica para botones numerados de paginación
|
||||||
|
const totalPages = Math.max(1, Math.ceil(docsCount / pageSize));
|
||||||
|
let pageNumbers = [];
|
||||||
|
if (totalPages <= 7) {
|
||||||
|
pageNumbers = Array.from({ length: totalPages }, (_, i) => i + 1);
|
||||||
|
} else {
|
||||||
|
if (page <= 4) {
|
||||||
|
pageNumbers = [1, 2, 3, 4, 5, '...', totalPages];
|
||||||
|
} else if (page >= totalPages - 3) {
|
||||||
|
pageNumbers = [1, '...', totalPages - 4, totalPages - 3, totalPages - 2, totalPages - 1, totalPages];
|
||||||
|
} else {
|
||||||
|
pageNumbers = [1, '...', page - 1, page, page + 1, '...', totalPages];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-gradient-to-br from-blue-50 via-white to-blue-50 p-4 lg:p-6">
|
<div className="min-h-screen bg-gradient-to-br from-blue-50 via-white to-blue-50 p-4 lg:p-6">
|
||||||
<div className="max-w-7xl mx-auto">
|
<div className="max-w-7xl mx-auto">
|
||||||
@@ -481,7 +496,7 @@ const [docsPrev, setDocsPrev] = useState(null);
|
|||||||
</svg>
|
</svg>
|
||||||
Pedimento
|
Pedimento
|
||||||
</dt>
|
</dt>
|
||||||
<dd className="text-xl font-bold text-gray-900">{pedimento.pedimento}</dd>
|
<dd className="text-xl font-bold text-gray-900">{pedimento.pedimento_app}</dd>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="bg-gradient-to-br from-green-50 to-green-100/50 p-4 rounded-xl border border-green-200/50 shadow-sm hover:shadow-md transition-all duration-300 hover:scale-105">
|
<div className="bg-gradient-to-br from-green-50 to-green-100/50 p-4 rounded-xl border border-green-200/50 shadow-sm hover:shadow-md transition-all duration-300 hover:scale-105">
|
||||||
@@ -706,10 +721,10 @@ const [docsPrev, setDocsPrev] = useState(null);
|
|||||||
{/* Vista Desktop - Tabla */}
|
{/* Vista Desktop - Tabla */}
|
||||||
<div className="hidden lg:block">
|
<div className="hidden lg:block">
|
||||||
<div className="overflow-x-auto">
|
<div className="overflow-x-auto">
|
||||||
<table className="min-w-full divide-y divide-gray-200">
|
<table className="min-w-full border border-gray-200 rounded-xl shadow-sm bg-white">
|
||||||
<thead className="bg-gradient-to-r from-blue-500 to-blue-700">
|
<thead className="sticky top-0 z-10 bg-white border-b border-gray-200">
|
||||||
<tr>
|
<tr>
|
||||||
<th className="px-4 py-3 text-left text-xs font-bold text-white uppercase tracking-wider">
|
<th className="px-4 py-3 text-left text-xs font-bold text-gray-700 uppercase tracking-wider bg-gray-50 border-r border-gray-200 first:rounded-tl-xl last:rounded-tr-xl">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
checked={allSelected}
|
checked={allSelected}
|
||||||
@@ -717,42 +732,42 @@ const [docsPrev, setDocsPrev] = useState(null);
|
|||||||
className="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded"
|
className="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded"
|
||||||
/>
|
/>
|
||||||
</th>
|
</th>
|
||||||
<th className="px-4 py-3 text-left text-xs font-bold text-white uppercase tracking-wider cursor-pointer" onClick={() => {
|
<th className="px-4 py-3 text-left text-xs font-bold text-gray-700 uppercase tracking-wider bg-gray-50 border-r border-gray-200 cursor-pointer select-none" onClick={() => {
|
||||||
setOrderBy('archivo');
|
setOrderBy('archivo');
|
||||||
setOrderDir(orderBy === 'archivo' && orderDir === 'asc' ? 'desc' : 'asc');
|
setOrderDir(orderBy === 'archivo' && orderDir === 'asc' ? 'desc' : 'asc');
|
||||||
}}>
|
}}>
|
||||||
Archivo {orderBy === 'archivo' && (<span className="ml-1">{orderDir === 'asc' ? '▲' : '▼'}</span>)}
|
Archivo {orderBy === 'archivo' && (<span className="ml-1">{orderDir === 'asc' ? '▲' : '▼'}</span>)}
|
||||||
</th>
|
</th>
|
||||||
<th className="px-4 py-3 text-left text-xs font-bold text-white uppercase tracking-wider cursor-pointer" onClick={() => {
|
<th className="px-4 py-3 text-left text-xs font-bold text-gray-700 uppercase tracking-wider bg-gray-50 border-r border-gray-200 cursor-pointer select-none" onClick={() => {
|
||||||
setOrderBy('document_type');
|
setOrderBy('document_type');
|
||||||
setOrderDir(orderBy === 'document_type' && orderDir === 'asc' ? 'desc' : 'asc');
|
setOrderDir(orderBy === 'document_type' && orderDir === 'asc' ? 'desc' : 'asc');
|
||||||
}}>
|
}}>
|
||||||
Tipo {orderBy === 'document_type' && (<span className="ml-1">{orderDir === 'asc' ? '▲' : '▼'}</span>)}
|
Tipo {orderBy === 'document_type' && (<span className="ml-1">{orderDir === 'asc' ? '▲' : '▼'}</span>)}
|
||||||
</th>
|
</th>
|
||||||
<th className="px-4 py-3 text-left text-xs font-bold text-white uppercase tracking-wider cursor-pointer" onClick={() => {
|
<th className="px-4 py-3 text-left text-xs font-bold text-gray-700 uppercase tracking-wider bg-gray-50 border-r border-gray-200 cursor-pointer select-none" onClick={() => {
|
||||||
setOrderBy('extension');
|
setOrderBy('extension');
|
||||||
setOrderDir(orderBy === 'extension' && orderDir === 'asc' ? 'desc' : 'asc');
|
setOrderDir(orderBy === 'extension' && orderDir === 'asc' ? 'desc' : 'asc');
|
||||||
}}>
|
}}>
|
||||||
Extensión {orderBy === 'extension' && (<span className="ml-1">{orderDir === 'asc' ? '▲' : '▼'}</span>)}
|
Extensión {orderBy === 'extension' && (<span className="ml-1">{orderDir === 'asc' ? '▲' : '▼'}</span>)}
|
||||||
</th>
|
</th>
|
||||||
<th className="px-4 py-3 text-left text-xs font-bold text-white uppercase tracking-wider cursor-pointer" onClick={() => {
|
<th className="px-4 py-3 text-left text-xs font-bold text-gray-700 uppercase tracking-wider bg-gray-50 border-r border-gray-200 cursor-pointer select-none" onClick={() => {
|
||||||
setOrderBy('size');
|
setOrderBy('size');
|
||||||
setOrderDir(orderBy === 'size' && orderDir === 'asc' ? 'desc' : 'asc');
|
setOrderDir(orderBy === 'size' && orderDir === 'asc' ? 'desc' : 'asc');
|
||||||
}}>
|
}}>
|
||||||
Tamaño {orderBy === 'size' && (<span className="ml-1">{orderDir === 'asc' ? '▲' : '▼'}</span>)}
|
Tamaño {orderBy === 'size' && (<span className="ml-1">{orderDir === 'asc' ? '▲' : '▼'}</span>)}
|
||||||
</th>
|
</th>
|
||||||
<th className="px-4 py-3 text-left text-xs font-bold text-white uppercase tracking-wider cursor-pointer" onClick={() => {
|
<th className="px-4 py-3 text-left text-xs font-bold text-gray-700 uppercase tracking-wider bg-gray-50 border-r border-gray-200 cursor-pointer select-none" onClick={() => {
|
||||||
setOrderBy('created_at');
|
setOrderBy('created_at');
|
||||||
setOrderDir(orderBy === 'created_at' && orderDir === 'asc' ? 'desc' : 'asc');
|
setOrderDir(orderBy === 'created_at' && orderDir === 'asc' ? 'desc' : 'asc');
|
||||||
}}>
|
}}>
|
||||||
Fecha {orderBy === 'created_at' && (<span className="ml-1">{orderDir === 'asc' ? '▲' : '▼'}</span>)}
|
Fecha {orderBy === 'created_at' && (<span className="ml-1">{orderDir === 'asc' ? '▲' : '▼'}</span>)}
|
||||||
</th>
|
</th>
|
||||||
<th className="px-4 py-3 text-center text-xs font-bold text-white uppercase tracking-wider">
|
<th className="px-4 py-3 text-center text-xs font-bold text-gray-700 uppercase tracking-wider bg-gray-50 first:rounded-tr-xl last:rounded-tr-xl">
|
||||||
Acciones
|
Acciones
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody className="bg-white/50 divide-y divide-gray-100">
|
<tbody className="bg-white divide-y divide-gray-100">
|
||||||
{documents
|
{documents
|
||||||
.filter(doc => {
|
.filter(doc => {
|
||||||
if (!documentTypeFilter) return true;
|
if (!documentTypeFilter) return true;
|
||||||
@@ -798,8 +813,8 @@ const [docsPrev, setDocsPrev] = useState(null);
|
|||||||
return 0;
|
return 0;
|
||||||
})
|
})
|
||||||
.map((doc, index) => (
|
.map((doc, index) => (
|
||||||
<tr key={doc.id} className="hover:bg-blue-50 transition-all duration-200">
|
<tr key={doc.id} className="hover:bg-blue-100/60 transition-all duration-150 border-b border-gray-100 last:border-b-0">
|
||||||
<td className="px-4 py-3 whitespace-nowrap">
|
<td className="px-4 py-3 whitespace-nowrap align-middle border-r border-gray-100">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
checked={selected.includes(doc.id)}
|
checked={selected.includes(doc.id)}
|
||||||
@@ -807,32 +822,32 @@ const [docsPrev, setDocsPrev] = useState(null);
|
|||||||
className="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded"
|
className="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded"
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
<td className="px-4 py-3 whitespace-nowrap">
|
<td className="px-4 py-3 whitespace-nowrap align-middle border-r border-gray-100">
|
||||||
<div className="text-sm font-medium text-gray-900 max-w-xs truncate" title={doc.archivo || 'Sin nombre'}>
|
<div className="text-sm font-medium text-gray-900 max-w-xs truncate" title={doc.archivo || 'Sin nombre'}>
|
||||||
{doc.archivo ? doc.archivo.split('/').pop() : 'Sin nombre'}
|
{doc.archivo ? doc.archivo.split('/').pop() : 'Sin nombre'}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td className="px-4 py-3 whitespace-nowrap">
|
<td className="px-4 py-3 whitespace-nowrap align-middle border-r border-gray-100">
|
||||||
<span className="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-800">
|
<span className="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-800">
|
||||||
{getDocumentTypeName(doc.document_type)}
|
{getDocumentTypeName(doc.document_type)}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td className="px-4 py-3 whitespace-nowrap">
|
<td className="px-4 py-3 whitespace-nowrap align-middle border-r border-gray-100">
|
||||||
<span className="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800">
|
<span className="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800">
|
||||||
{doc.extension || 'N/A'}
|
{doc.extension || 'N/A'}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td className="px-4 py-3 whitespace-nowrap text-sm text-gray-700">
|
<td className="px-4 py-3 whitespace-nowrap text-sm text-gray-700 align-middle border-r border-gray-100">
|
||||||
{doc.size || 'N/A'}
|
{doc.size || 'N/A'}
|
||||||
</td>
|
</td>
|
||||||
<td className="px-4 py-3 whitespace-nowrap text-sm text-gray-700">
|
<td className="px-4 py-3 whitespace-nowrap text-sm text-gray-700 align-middle border-r border-gray-100">
|
||||||
{doc.created_at ? new Date(doc.created_at).toLocaleDateString('es-ES', {
|
{doc.created_at ? new Date(doc.created_at).toLocaleDateString('es-ES', {
|
||||||
year: 'numeric',
|
year: 'numeric',
|
||||||
month: 'short',
|
month: 'short',
|
||||||
day: 'numeric'
|
day: 'numeric'
|
||||||
}) : 'N/A'}
|
}) : 'N/A'}
|
||||||
</td>
|
</td>
|
||||||
<td className="px-4 py-3 whitespace-nowrap text-center">
|
<td className="px-4 py-3 whitespace-nowrap text-center align-middle">
|
||||||
<div className="flex justify-center space-x-2">
|
<div className="flex justify-center space-x-2">
|
||||||
<button
|
<button
|
||||||
onClick={() => handlePreview(doc)}
|
onClick={() => handlePreview(doc)}
|
||||||
@@ -859,6 +874,65 @@ const [docsPrev, setDocsPrev] = useState(null);
|
|||||||
))}
|
))}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
{/* Paginación Desktop */}
|
||||||
|
<div className="flex flex-col sm:flex-row justify-between items-center mt-4 gap-2 w-full">
|
||||||
|
{/* Izquierda: Selector de registros por página */}
|
||||||
|
<div className="flex items-center gap-2 w-full sm:w-auto justify-start">
|
||||||
|
<span className="text-sm text-gray-600 whitespace-nowrap">Registros por página</span>
|
||||||
|
<select
|
||||||
|
value={pageSize}
|
||||||
|
onChange={e => setPageSize(Number(e.target.value))}
|
||||||
|
className="px-2 py-1 rounded border border-gray-300 text-sm"
|
||||||
|
>
|
||||||
|
{[10, 20, 50, 100].map(size => (
|
||||||
|
<option key={size} value={size}>{size}</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
{/* Centro: Paginación numerada */}
|
||||||
|
<div className="flex gap-1 items-center flex-wrap justify-center w-full sm:w-auto">
|
||||||
|
<button
|
||||||
|
onClick={e => handlePageChange(1, e)}
|
||||||
|
disabled={page === 1}
|
||||||
|
className="px-2 py-1 rounded-lg border border-gray-300 bg-white text-gray-700 hover:bg-blue-50 disabled:opacity-50"
|
||||||
|
title="Primera página"
|
||||||
|
>«</button>
|
||||||
|
<button
|
||||||
|
onClick={e => handlePageChange(page - 1, e)}
|
||||||
|
disabled={page === 1}
|
||||||
|
className="px-2 py-1 rounded-lg border border-gray-300 bg-white text-gray-700 hover:bg-blue-50 disabled:opacity-50"
|
||||||
|
title="Anterior"
|
||||||
|
><</button>
|
||||||
|
{pageNumbers.map((num, idx) =>
|
||||||
|
num === '...'
|
||||||
|
? <span key={idx} className="px-2 text-gray-400 select-none">…</span>
|
||||||
|
: <button
|
||||||
|
key={num}
|
||||||
|
onClick={e => handlePageChange(num, e)}
|
||||||
|
className={`px-2 py-1 rounded-lg border border-gray-300 ${num === page ? 'bg-blue-500 text-white font-bold' : 'bg-white text-gray-700 hover:bg-blue-50'} transition-colors`}
|
||||||
|
disabled={num === page}
|
||||||
|
>{num}</button>
|
||||||
|
)}
|
||||||
|
<button
|
||||||
|
onClick={e => handlePageChange(page + 1, e)}
|
||||||
|
disabled={page >= totalPages}
|
||||||
|
className="px-2 py-1 rounded-lg border border-gray-300 bg-white text-gray-700 hover:bg-blue-50 disabled:opacity-50"
|
||||||
|
title="Siguiente"
|
||||||
|
>></button>
|
||||||
|
<button
|
||||||
|
onClick={e => handlePageChange(totalPages, e)}
|
||||||
|
disabled={page >= totalPages}
|
||||||
|
className="px-2 py-1 rounded-lg border border-gray-300 bg-white text-gray-700 hover:bg-blue-50 disabled:opacity-50"
|
||||||
|
title="Última página"
|
||||||
|
>»</button>
|
||||||
|
</div>
|
||||||
|
{/* Derecha: Rango de registros */}
|
||||||
|
<div className="text-sm text-gray-600 w-full sm:w-auto text-right">
|
||||||
|
{docsCount > 0
|
||||||
|
? `Mostrando ${((page - 1) * pageSize) + 1} a ${Math.min(page * pageSize, docsCount)} de ${docsCount} registros`
|
||||||
|
: 'Mostrando 0 de 0 registros'}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -958,6 +1032,65 @@ const [docsPrev, setDocsPrev] = useState(null);
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
{/* Controles de paginación móvil */}
|
||||||
|
<div className="flex flex-col sm:flex-row justify-between items-center mt-4 gap-2 w-full">
|
||||||
|
{/* Izquierda: Selector de registros por página */}
|
||||||
|
<div className="flex items-center gap-2 w-full sm:w-auto justify-start">
|
||||||
|
<span className="text-sm text-gray-600 whitespace-nowrap">Registros por página</span>
|
||||||
|
<select
|
||||||
|
value={pageSize}
|
||||||
|
onChange={e => setPageSize(Number(e.target.value))}
|
||||||
|
className="px-2 py-1 rounded border border-gray-300 text-sm"
|
||||||
|
>
|
||||||
|
{[10, 20, 50, 100].map(size => (
|
||||||
|
<option key={size} value={size}>{size}</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
{/* Centro: Paginación numerada */}
|
||||||
|
<div className="flex gap-1 items-center flex-wrap justify-center w-full sm:w-auto">
|
||||||
|
<button
|
||||||
|
onClick={e => handlePageChange(1, e)}
|
||||||
|
disabled={page === 1}
|
||||||
|
className="px-2 py-1 rounded-lg border border-gray-300 bg-white text-gray-700 hover:bg-blue-50 disabled:opacity-50"
|
||||||
|
title="Primera página"
|
||||||
|
>«</button>
|
||||||
|
<button
|
||||||
|
onClick={e => handlePageChange(page - 1, e)}
|
||||||
|
disabled={page === 1}
|
||||||
|
className="px-2 py-1 rounded-lg border border-gray-300 bg-white text-gray-700 hover:bg-blue-50 disabled:opacity-50"
|
||||||
|
title="Anterior"
|
||||||
|
><</button>
|
||||||
|
{pageNumbers.map((num, idx) =>
|
||||||
|
num === '...'
|
||||||
|
? <span key={idx} className="px-2 text-gray-400 select-none">…</span>
|
||||||
|
: <button
|
||||||
|
key={num}
|
||||||
|
onClick={e => handlePageChange(num, e)}
|
||||||
|
className={`px-2 py-1 rounded-lg border border-gray-300 ${num === page ? 'bg-blue-500 text-white font-bold' : 'bg-white text-gray-700 hover:bg-blue-50'} transition-colors`}
|
||||||
|
disabled={num === page}
|
||||||
|
>{num}</button>
|
||||||
|
)}
|
||||||
|
<button
|
||||||
|
onClick={e => handlePageChange(page + 1, e)}
|
||||||
|
disabled={page >= totalPages}
|
||||||
|
className="px-2 py-1 rounded-lg border border-gray-300 bg-white text-gray-700 hover:bg-blue-50 disabled:opacity-50"
|
||||||
|
title="Siguiente"
|
||||||
|
>></button>
|
||||||
|
<button
|
||||||
|
onClick={e => handlePageChange(totalPages, e)}
|
||||||
|
disabled={page >= totalPages}
|
||||||
|
className="px-2 py-1 rounded-lg border border-gray-300 bg-white text-gray-700 hover:bg-blue-50 disabled:opacity-50"
|
||||||
|
title="Última página"
|
||||||
|
>»</button>
|
||||||
|
</div>
|
||||||
|
{/* Derecha: Rango de registros */}
|
||||||
|
<div className="text-sm text-gray-600 w-full sm:w-auto text-right">
|
||||||
|
{docsCount > 0
|
||||||
|
? `Mostrando ${((page - 1) * pageSize) + 1} a ${Math.min(page * pageSize, docsCount)} de ${docsCount} registros`
|
||||||
|
: 'Mostrando 0 de 0 registros'}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -695,7 +695,7 @@ export default function Procesos() {
|
|||||||
try {
|
try {
|
||||||
// Construir filtros
|
// Construir filtros
|
||||||
const filters = {};
|
const filters = {};
|
||||||
if (pedimentoPedimentoFilter) filters['pedimento__pedimento'] = pedimentoPedimentoFilter;
|
if (pedimentoPedimentoFilter) filters['pedimento__pedimento_app'] = pedimentoPedimentoFilter;
|
||||||
if (estadoFilter) filters['estado'] = estadoFilter;
|
if (estadoFilter) filters['estado'] = estadoFilter;
|
||||||
if (servicioFilter) filters['servicio'] = servicioFilter;
|
if (servicioFilter) filters['servicio'] = servicioFilter;
|
||||||
if (sortField) {
|
if (sortField) {
|
||||||
@@ -1158,7 +1158,7 @@ export default function Procesos() {
|
|||||||
</td>
|
</td>
|
||||||
<td className="px-4 py-4 whitespace-nowrap align-middle text-sm text-gray-900 font-mono">
|
<td className="px-4 py-4 whitespace-nowrap align-middle text-sm text-gray-900 font-mono">
|
||||||
{typeof proc.pedimento === 'object' && proc.pedimento !== null
|
{typeof proc.pedimento === 'object' && proc.pedimento !== null
|
||||||
? proc.pedimento.pedimento || JSON.stringify(proc.pedimento)
|
? proc.pedimento.pedimento_app || proc.pedimento.pedimento || JSON.stringify(proc.pedimento)
|
||||||
: proc.pedimento}
|
: proc.pedimento}
|
||||||
</td>
|
</td>
|
||||||
<td className="px-4 py-4 whitespace-nowrap align-middle text-sm text-gray-700">
|
<td className="px-4 py-4 whitespace-nowrap align-middle text-sm text-gray-700">
|
||||||
|
|||||||
Reference in New Issue
Block a user