se agrego paginacion a datastage
This commit is contained in:
@@ -117,6 +117,8 @@ function downloadDatastageFile(id, filename) {
|
|||||||
export default function Datastage() {
|
export default function Datastage() {
|
||||||
const focusKeeperRef = useRef(null);
|
const focusKeeperRef = useRef(null);
|
||||||
const [datastages, setDatastages] = useState([]);
|
const [datastages, setDatastages] = useState([]);
|
||||||
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
|
const [itemsPerPage, setItemsPerPage] = useState(10);
|
||||||
const [selected, setSelected] = useState(null);
|
const [selected, setSelected] = useState(null);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [error, setError] = useState(null);
|
const [error, setError] = useState(null);
|
||||||
@@ -347,7 +349,7 @@ export default function Datastage() {
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{datastages.map(item => (
|
{datastages.slice((currentPage - 1) * itemsPerPage, currentPage * itemsPerPage).map(item => (
|
||||||
<tr key={item.id} className="hover:bg-slate-50 transition-colors">
|
<tr key={item.id} className="hover:bg-slate-50 transition-colors">
|
||||||
<td className="border px-2 py-2 text-center">{item.id}</td>
|
<td className="border px-2 py-2 text-center">{item.id}</td>
|
||||||
<td className="border px-2 py-2 max-w-xs truncate">
|
<td className="border px-2 py-2 max-w-xs truncate">
|
||||||
@@ -420,7 +422,7 @@ export default function Datastage() {
|
|||||||
disabled={item.procesado}
|
disabled={item.procesado}
|
||||||
>
|
>
|
||||||
<svg className="w-5 h-5 text-green-600" fill="currentColor" viewBox="0 0 24 24">
|
<svg className="w-5 h-5 text-green-600" fill="currentColor" viewBox="0 0 24 24">
|
||||||
<path d="M8 5v14l11-7z"/>
|
<path d="M8 5v14l11-7z" />
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
@@ -428,6 +430,40 @@ export default function Datastage() {
|
|||||||
))}
|
))}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
{/* Paginación */}
|
||||||
|
{datastages.length > itemsPerPage && (
|
||||||
|
<div className="flex flex-col sm:flex-row items-center justify-between gap-2 px-4 py-4 border-t border-gray-200">
|
||||||
|
<div className="text-xs text-gray-700">
|
||||||
|
Mostrando <span className="font-medium">{((currentPage - 1) * itemsPerPage) + 1}</span> a <span className="font-medium">{Math.min(currentPage * itemsPerPage, datastages.length)}</span> de <span className="font-medium">{datastages.length}</span> registros
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-1">
|
||||||
|
<button
|
||||||
|
onClick={() => setCurrentPage(p => Math.max(1, p - 1))}
|
||||||
|
disabled={currentPage === 1}
|
||||||
|
className="px-2 py-1 rounded border text-xs bg-white hover:bg-blue-50 disabled:opacity-50"
|
||||||
|
>Anterior</button>
|
||||||
|
{Array.from({ length: Math.ceil(datastages.length / itemsPerPage) }, (_, i) => i + 1).map(pageNum => (
|
||||||
|
<button
|
||||||
|
key={pageNum}
|
||||||
|
onClick={() => setCurrentPage(pageNum)}
|
||||||
|
className={`px-2 py-1 rounded text-xs border ${currentPage === pageNum ? 'bg-blue-600 text-white' : 'bg-white hover:bg-blue-50'}`}
|
||||||
|
>{pageNum}</button>
|
||||||
|
))}
|
||||||
|
<button
|
||||||
|
onClick={() => setCurrentPage(p => Math.min(Math.ceil(datastages.length / itemsPerPage), p + 1))}
|
||||||
|
disabled={currentPage === Math.ceil(datastages.length / itemsPerPage)}
|
||||||
|
className="px-2 py-1 rounded border text-xs bg-white hover:bg-blue-50 disabled:opacity-50"
|
||||||
|
>Siguiente</button>
|
||||||
|
<select
|
||||||
|
value={itemsPerPage}
|
||||||
|
onChange={e => { setItemsPerPage(Number(e.target.value)); setCurrentPage(1); }}
|
||||||
|
className="ml-2 px-2 py-1 border rounded text-xs"
|
||||||
|
>
|
||||||
|
{[10, 20, 50, 100].map(n => (<option key={n} value={n}>{n} por página</option>))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
{/* Tarjetas para móvil/tablet */}
|
{/* Tarjetas para móvil/tablet */}
|
||||||
<div className="lg:hidden space-y-4 p-2">
|
<div className="lg:hidden space-y-4 p-2">
|
||||||
@@ -497,7 +533,7 @@ export default function Datastage() {
|
|||||||
disabled={item.procesado}
|
disabled={item.procesado}
|
||||||
>
|
>
|
||||||
<svg className="w-5 h-5 text-green-600" fill="currentColor" viewBox="0 0 24 24">
|
<svg className="w-5 h-5 text-green-600" fill="currentColor" viewBox="0 0 24 24">
|
||||||
<path d="M8 5v14l11-7z"/>
|
<path d="M8 5v14l11-7z" />
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -535,7 +571,7 @@ export default function Datastage() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/* Content */}
|
{/* Content */}
|
||||||
<div className="p-6 space-y-4">
|
<div className="p-6 space-y-4 ">
|
||||||
{error && <div className="text-red-500 mb-2">{error}</div>}
|
{error && <div className="text-red-500 mb-2">{error}</div>}
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-xs font-semibold text-slate-700 mb-1">Archivo (.zip)</label>
|
<label className="block text-xs font-semibold text-slate-700 mb-1">Archivo (.zip)</label>
|
||||||
|
|||||||
Reference in New Issue
Block a user