Se modifico Pedimento detail se empezaron a agregar elementos del auditor y detalle completo del pedimento
This commit is contained in:
97
src/api/coves.js
Normal file
97
src/api/coves.js
Normal file
@@ -0,0 +1,97 @@
|
||||
import { fetchWithAuth } from '../fetchWithAuth';
|
||||
|
||||
const API_BASE_URL = process.env.NODE_ENV === 'production'
|
||||
? 'https://your-production-api.com/api/v1'
|
||||
: 'http://192.168.1.79:8000/api/v1';
|
||||
|
||||
export const fetchPedimentoCoves = async (pedimentoId, page = 1, pageSize = 10, filters = {}) => {
|
||||
try {
|
||||
const params = new URLSearchParams({
|
||||
pedimento: pedimentoId,
|
||||
page: page.toString(),
|
||||
page_size: pageSize.toString(),
|
||||
});
|
||||
|
||||
// Agregar filtros si existen
|
||||
if (filters.numero_cove) {
|
||||
params.append('numero_cove__icontains', filters.numero_cove);
|
||||
}
|
||||
if (filters.cove_descargado !== undefined && filters.cove_descargado !== '') {
|
||||
params.append('cove_descargado', filters.cove_descargado);
|
||||
}
|
||||
if (filters.acuse_cove_descargado !== undefined && filters.acuse_cove_descargado !== '') {
|
||||
params.append('acuse_cove_descargado', filters.acuse_cove_descargado);
|
||||
}
|
||||
if (filters.date_from) {
|
||||
params.append('created_at__gte', filters.date_from);
|
||||
}
|
||||
if (filters.date_to) {
|
||||
params.append('created_at__lte', filters.date_to);
|
||||
}
|
||||
|
||||
const response = await fetchWithAuth(`${API_BASE_URL}/customs/coves/?${params}`);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Error ${response.status}: ${response.statusText}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
return {
|
||||
results: data.results,
|
||||
count: data.count,
|
||||
next: data.next,
|
||||
previous: data.previous
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error fetching COVEs:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
export const downloadCove = async (coveId) => {
|
||||
try {
|
||||
const response = await fetchWithAuth(`${API_BASE_URL}/customs/coves/${coveId}/download/`);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Error ${response.status}: ${response.statusText}`);
|
||||
}
|
||||
|
||||
const blob = await response.blob();
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.style.display = 'none';
|
||||
a.href = url;
|
||||
a.download = `COVE_${coveId}.pdf`;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
window.URL.revokeObjectURL(url);
|
||||
document.body.removeChild(a);
|
||||
} catch (error) {
|
||||
console.error('Error downloading COVE:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
export const downloadAcuseCove = async (coveId) => {
|
||||
try {
|
||||
const response = await fetchWithAuth(`${API_BASE_URL}/customs/coves/${coveId}/download-acuse/`);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Error ${response.status}: ${response.statusText}`);
|
||||
}
|
||||
|
||||
const blob = await response.blob();
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.style.display = 'none';
|
||||
a.href = url;
|
||||
a.download = `ACUSE_COVE_${coveId}.pdf`;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
window.URL.revokeObjectURL(url);
|
||||
document.body.removeChild(a);
|
||||
} catch (error) {
|
||||
console.error('Error downloading COVE acuse:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
103
src/api/edocuments.js
Normal file
103
src/api/edocuments.js
Normal file
@@ -0,0 +1,103 @@
|
||||
import { fetchWithAuth } from '../fetchWithAuth';
|
||||
|
||||
const API_BASE_URL = process.env.NODE_ENV === 'production'
|
||||
? 'https://your-production-api.com/api/v1'
|
||||
: 'http://192.168.1.79:8000/api/v1';
|
||||
|
||||
export const fetchPedimentoEdocuments = async (pedimentoId, page = 1, pageSize = 10, filters = {}) => {
|
||||
try {
|
||||
const params = new URLSearchParams({
|
||||
pedimento: pedimentoId,
|
||||
page: page.toString(),
|
||||
page_size: pageSize.toString(),
|
||||
});
|
||||
|
||||
// Agregar filtros si existen
|
||||
if (filters.numero_edocument) {
|
||||
params.append('numero_edocument__icontains', filters.numero_edocument);
|
||||
}
|
||||
if (filters.clave) {
|
||||
params.append('clave__icontains', filters.clave);
|
||||
}
|
||||
if (filters.descripcion) {
|
||||
params.append('descripcion__icontains', filters.descripcion);
|
||||
}
|
||||
if (filters.edocument_descargado !== undefined && filters.edocument_descargado !== '') {
|
||||
params.append('edocument_descargado', filters.edocument_descargado);
|
||||
}
|
||||
if (filters.acuse_descargado !== undefined && filters.acuse_descargado !== '') {
|
||||
params.append('acuse_descargado', filters.acuse_descargado);
|
||||
}
|
||||
if (filters.date_from) {
|
||||
params.append('created_at__gte', filters.date_from);
|
||||
}
|
||||
if (filters.date_to) {
|
||||
params.append('created_at__lte', filters.date_to);
|
||||
}
|
||||
|
||||
const response = await fetchWithAuth(`${API_BASE_URL}/customs/edocuments/?${params}`);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Error ${response.status}: ${response.statusText}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
return {
|
||||
results: data.results,
|
||||
count: data.count,
|
||||
next: data.next,
|
||||
previous: data.previous
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error fetching EDocs:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
export const downloadEdocument = async (edocId) => {
|
||||
try {
|
||||
const response = await fetchWithAuth(`${API_BASE_URL}/customs/edocuments/${edocId}/download/`);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Error ${response.status}: ${response.statusText}`);
|
||||
}
|
||||
|
||||
const blob = await response.blob();
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.style.display = 'none';
|
||||
a.href = url;
|
||||
a.download = `EDOC_${edocId}.pdf`;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
window.URL.revokeObjectURL(url);
|
||||
document.body.removeChild(a);
|
||||
} catch (error) {
|
||||
console.error('Error downloading EDocs:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
export const downloadAcuseEdocument = async (edocId) => {
|
||||
try {
|
||||
const response = await fetchWithAuth(`${API_BASE_URL}/customs/edocuments/${edocId}/download-acuse/`);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Error ${response.status}: ${response.statusText}`);
|
||||
}
|
||||
|
||||
const blob = await response.blob();
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.style.display = 'none';
|
||||
a.href = url;
|
||||
a.download = `ACUSE_EDOC_${edocId}.pdf`;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
window.URL.revokeObjectURL(url);
|
||||
document.body.removeChild(a);
|
||||
} catch (error) {
|
||||
console.error('Error downloading EDocs acuse:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
@@ -5,10 +5,12 @@ export interface PedimentoDocument {
|
||||
id: string;
|
||||
organizacion: string;
|
||||
pedimento: string;
|
||||
pedimento_numero: string;
|
||||
archivo: string;
|
||||
document_type: number;
|
||||
size: number;
|
||||
extension: string;
|
||||
fuente: number;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
@@ -20,17 +22,38 @@ export interface PedimentoDocumentsResponse {
|
||||
results: PedimentoDocument[];
|
||||
}
|
||||
|
||||
export interface DocumentFilters {
|
||||
document_type?: string;
|
||||
archivo__icontains?: string;
|
||||
extension?: string;
|
||||
created_at__date?: string;
|
||||
ordering?: string;
|
||||
}
|
||||
|
||||
const API_URL = (import.meta as any).env.VITE_EFC_API_URL;
|
||||
|
||||
export async function fetchPedimentoDocuments(
|
||||
pedimentoId: string,
|
||||
page: number = 1,
|
||||
pageSize: number = 10
|
||||
pageSize: number = 10,
|
||||
filters: DocumentFilters = {}
|
||||
): Promise<PedimentoDocumentsResponse> {
|
||||
try {
|
||||
const res = await fetchWithAuth(
|
||||
`${API_URL}/record/documents/?page=${page}&page_size=${pageSize}&pedimento=${pedimentoId}`
|
||||
);
|
||||
// Construir URL con filtros
|
||||
const params = new URLSearchParams({
|
||||
page: page.toString(),
|
||||
page_size: pageSize.toString(),
|
||||
pedimento: pedimentoId
|
||||
});
|
||||
|
||||
// Agregar filtros si existen
|
||||
Object.entries(filters).forEach(([key, value]) => {
|
||||
if (value !== undefined && value !== '') {
|
||||
params.append(key, value.toString());
|
||||
}
|
||||
});
|
||||
|
||||
const res = await fetchWithAuth(`${API_URL}/record/documents/?${params.toString()}`);
|
||||
|
||||
if (!res.ok) {
|
||||
throw new Error('No autorizado o error en la petición');
|
||||
|
||||
109
src/api/procesos.js
Normal file
109
src/api/procesos.js
Normal file
@@ -0,0 +1,109 @@
|
||||
import { fetchWithAuth } from '../fetchWithAuth';
|
||||
|
||||
const API_BASE_URL = process.env.NODE_ENV === 'production'
|
||||
? 'https://your-production-api.com/api/v1'
|
||||
: 'http://192.168.1.79:8000/api/v1';
|
||||
|
||||
export const fetchPedimentoProcesos = async (pedimentoId, page = 1, pageSize = 10, filters = {}) => {
|
||||
try {
|
||||
const params = new URLSearchParams({
|
||||
pedimento: pedimentoId,
|
||||
page: page.toString(),
|
||||
page_size: pageSize.toString(),
|
||||
});
|
||||
|
||||
// Agregar filtros si existen
|
||||
if (filters.estado !== undefined && filters.estado !== '') {
|
||||
params.append('estado', filters.estado);
|
||||
}
|
||||
if (filters.servicio !== undefined && filters.servicio !== '') {
|
||||
params.append('servicio', filters.servicio);
|
||||
}
|
||||
if (filters.organizacion_name) {
|
||||
params.append('organizacion_name__icontains', filters.organizacion_name);
|
||||
}
|
||||
if (filters.date_from) {
|
||||
params.append('created_at__gte', filters.date_from);
|
||||
}
|
||||
if (filters.date_to) {
|
||||
params.append('created_at__lte', filters.date_to);
|
||||
}
|
||||
if (filters.updated_from) {
|
||||
params.append('updated_at__gte', filters.updated_from);
|
||||
}
|
||||
if (filters.updated_to) {
|
||||
params.append('updated_at__lte', filters.updated_to);
|
||||
}
|
||||
|
||||
const response = await fetchWithAuth(`${API_BASE_URL}/customs/procesamientopedimentos/?${params}`);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Error ${response.status}: ${response.statusText}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
return {
|
||||
results: data.results,
|
||||
count: data.count,
|
||||
next: data.next,
|
||||
previous: data.previous
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error fetching Procesos:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
// Mapeo de estados
|
||||
export const getEstadoLabel = (estado) => {
|
||||
const estados = {
|
||||
1: 'Pendiente',
|
||||
2: 'En Proceso',
|
||||
3: 'Completado',
|
||||
4: 'Error',
|
||||
5: 'Cancelado'
|
||||
};
|
||||
return estados[estado] || `Estado ${estado}`;
|
||||
};
|
||||
|
||||
export const getEstadoColor = (estado) => {
|
||||
const colores = {
|
||||
1: 'bg-yellow-100 text-yellow-800',
|
||||
2: 'bg-blue-100 text-blue-800',
|
||||
3: 'bg-green-100 text-green-800',
|
||||
4: 'bg-red-100 text-red-800',
|
||||
5: 'bg-gray-100 text-gray-800'
|
||||
};
|
||||
return colores[estado] || 'bg-gray-100 text-gray-800';
|
||||
};
|
||||
|
||||
// Mapeo de servicios
|
||||
export const getServicioLabel = (servicio) => {
|
||||
const servicios = {
|
||||
1: 'Digitalización',
|
||||
2: 'Validación',
|
||||
3: 'Procesamiento SAT',
|
||||
4: 'Generación COVEs',
|
||||
5: 'Generación EDocs',
|
||||
6: 'Envío VUCEM',
|
||||
7: 'Clasificación',
|
||||
8: 'Archivo Digital',
|
||||
9: 'Notificaciones'
|
||||
};
|
||||
return servicios[servicio] || `Servicio ${servicio}`;
|
||||
};
|
||||
|
||||
export const getServicioColor = (servicio) => {
|
||||
const colores = {
|
||||
1: 'bg-purple-100 text-purple-800',
|
||||
2: 'bg-indigo-100 text-indigo-800',
|
||||
3: 'bg-blue-100 text-blue-800',
|
||||
4: 'bg-cyan-100 text-cyan-800',
|
||||
5: 'bg-teal-100 text-teal-800',
|
||||
6: 'bg-green-100 text-green-800',
|
||||
7: 'bg-yellow-100 text-yellow-800',
|
||||
8: 'bg-orange-100 text-orange-800',
|
||||
9: 'bg-pink-100 text-pink-800'
|
||||
};
|
||||
return colores[servicio] || 'bg-gray-100 text-gray-800';
|
||||
};
|
||||
@@ -351,16 +351,16 @@ export default function Datastage() {
|
||||
</div>
|
||||
{/* Tabla para pantallas grandes */}
|
||||
<div className="hidden lg:block overflow-x-auto">
|
||||
<table className="min-w-full divide-y divide-gray-200 rounded-lg overflow-hidden text-xs bg-white">
|
||||
<thead className="bg-slate-100">
|
||||
<table className="min-w-full divide-y divide-gray-300 rounded-lg overflow-hidden text-xs bg-white">
|
||||
<thead className="bg-gray-50">
|
||||
<tr>
|
||||
<th className="border px-2 py-2 whitespace-nowrap">ID</th>
|
||||
<th className="border px-2 py-2 whitespace-nowrap">Archivo</th>
|
||||
<th className="border px-2 py-2 whitespace-nowrap">Contribuyente</th>
|
||||
<th className="border px-2 py-2 whitespace-nowrap">Procesado</th>
|
||||
<th className="border px-2 py-2 whitespace-nowrap">Creado</th>
|
||||
<th className="border px-2 py-2 whitespace-nowrap">Actualizado</th>
|
||||
<th className="border px-2 py-2 whitespace-nowrap">Acciones</th>
|
||||
<th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">ID</th>
|
||||
<th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Archivo</th>
|
||||
<th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Contribuyente</th>
|
||||
<th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Procesado</th>
|
||||
<th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Creado</th>
|
||||
<th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Actualizado</th>
|
||||
<th scope="col" className="px-6 py-3 text-center text-xs font-medium text-gray-500 uppercase tracking-wider">Acciones</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
@@ -415,28 +415,29 @@ export default function Documents() {
|
||||
{/* Tabla para pantallas grandes */}
|
||||
<div className="hidden lg:block">
|
||||
<div style={{ minHeight: 'calc(6 * 56px)', maxHeight: 'calc(6 * 56px)', overflowY: currentDocuments.length > 6 ? 'auto' : 'hidden', position: 'relative' }}>
|
||||
<table className="min-w-full divide-y divide-gray-200 rounded-lg overflow-hidden 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">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={allSelected}
|
||||
ref={el => { if (el) el.indeterminate = someSelected; }}
|
||||
onChange={handleSelectAll}
|
||||
className="h-3.5 w-3.5 text-blue-600 focus:ring-blue-500 border-gray-300 rounded align-middle"
|
||||
style={{ minWidth: '14px', minHeight: '14px' }}
|
||||
/>
|
||||
</th>
|
||||
<th className="px-6 py-3 text-left text-xs font-bold uppercase tracking-wider border-b border-gray-200">Pedimento</th>
|
||||
<th className="px-6 py-3 text-left text-xs font-bold uppercase tracking-wider border-b border-gray-200">Archivo</th>
|
||||
<th className="px-6 py-3 text-left text-xs font-bold uppercase tracking-wider border-b border-gray-200">Tipo</th>
|
||||
<th className="px-6 py-3 text-left text-xs font-bold uppercase tracking-wider border-b border-gray-200">Tamaño</th>
|
||||
<th className="px-6 py-3 text-left text-xs font-bold uppercase tracking-wider border-b border-gray-200">Extensión</th>
|
||||
<th className="px-6 py-3 text-center text-xs font-bold text-blue-700 uppercase tracking-wider border-b border-gray-200">Acciones</th>
|
||||
<div className="overflow-hidden shadow ring-1 ring-black ring-opacity-5 rounded-lg">
|
||||
<table className="min-w-full divide-y divide-gray-300">
|
||||
<thead className="bg-gray-50 sticky top-0 z-20">
|
||||
<tr>
|
||||
<th scope="col" className="px-2 py-3 text-center text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={allSelected}
|
||||
ref={el => { if (el) el.indeterminate = someSelected; }}
|
||||
onChange={handleSelectAll}
|
||||
className="h-3.5 w-3.5 text-blue-600 focus:ring-blue-500 border-gray-300 rounded align-middle"
|
||||
style={{ minWidth: '14px', minHeight: '14px' }}
|
||||
/>
|
||||
</th>
|
||||
<th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Pedimento</th>
|
||||
<th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Archivo</th>
|
||||
<th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Tipo</th>
|
||||
<th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Tamaño</th>
|
||||
<th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Extensión</th>
|
||||
<th scope="col" className="px-6 py-3 text-center text-xs font-medium text-gray-500 uppercase tracking-wider">Acciones</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="bg-white divide-y divide-gray-100" style={{ position: 'relative', minHeight: 'calc(8 * 56px)' }}>
|
||||
<tbody className="bg-white divide-y divide-gray-200" style={{ position: 'relative', minHeight: 'calc(8 * 56px)' }}>
|
||||
{/* Loader/Error/Empty state dentro del área de la tabla, sin cambiar el layout */}
|
||||
{loading ? (
|
||||
<tr>
|
||||
@@ -536,6 +537,7 @@ export default function Documents() {
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -410,27 +410,27 @@ export default function Documents() {
|
||||
<div className="overflow-hidden">
|
||||
{/* Vista de tabla para pantallas grandes */}
|
||||
<div className="hidden lg:block">
|
||||
<div className="overflow-x-auto">
|
||||
<table className="min-w-full divide-y divide-gray-200">
|
||||
<thead className="bg-gradient-to-r from-gray-50 to-blue-50">
|
||||
<div className="overflow-x-auto shadow ring-1 ring-black ring-opacity-5 rounded-lg">
|
||||
<table className="min-w-full divide-y divide-gray-300" style={{ minWidth: '1200px' }}>
|
||||
<thead className="bg-gray-50">
|
||||
<tr>
|
||||
<th className="px-4 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider border-b border-gray-200">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">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">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">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">Fecha de Carga</th>
|
||||
<th className="px-4 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider border-b border-gray-200">Tipo Operacion</th>
|
||||
<th className="px-4 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider border-b border-gray-200">Clave</th>
|
||||
<th className="px-4 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider border-b border-gray-200">No. Archivos</th>
|
||||
<th className="px-4 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider border-b border-gray-200">Peso 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">Expediente</th>
|
||||
<th scope="col" className="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Pedimento</th>
|
||||
<th scope="col" className="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Fecha Pago</th>
|
||||
<th scope="col" className="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Contribuyente</th>
|
||||
<th scope="col" className="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">CURP Apod.</th>
|
||||
<th scope="col" className="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Partidas</th>
|
||||
<th scope="col" className="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">F. Carga</th>
|
||||
<th scope="col" className="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Tipo Op.</th>
|
||||
<th scope="col" className="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Clave</th>
|
||||
<th scope="col" className="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Archivos</th>
|
||||
<th scope="col" className="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Peso Total</th>
|
||||
<th scope="col" className="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Expediente</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="bg-white divide-y divide-gray-100">
|
||||
<tbody className="bg-white divide-y divide-gray-200">
|
||||
{loading ? (
|
||||
<tr>
|
||||
<td colSpan={8} className="px-6 py-12 text-center">
|
||||
<td colSpan={11} className="px-6 py-12 text-center">
|
||||
<div className="flex flex-col items-center">
|
||||
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600 mb-4"></div>
|
||||
<span className="text-gray-500 text-lg font-medium">Cargando expedientes...</span>
|
||||
@@ -439,7 +439,7 @@ export default function Documents() {
|
||||
</tr>
|
||||
) : error ? (
|
||||
<tr>
|
||||
<td colSpan={8} className="px-6 py-12 text-center">
|
||||
<td colSpan={11} className="px-6 py-12 text-center">
|
||||
<div className="flex flex-col items-center">
|
||||
<div className="bg-red-100 rounded-full p-3 mb-4">
|
||||
<svg className="h-8 w-8 text-red-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
@@ -452,35 +452,39 @@ export default function Documents() {
|
||||
</tr>
|
||||
) : currentDocuments.length > 0 ? (
|
||||
currentDocuments.map(ped => (
|
||||
<tr key={ped.id} className="hover:bg-blue-50 transition-all duration-300 group">
|
||||
<td className="px-4 py-4 whitespace-nowrap">
|
||||
<tr key={ped.id} className="hover:bg-gray-50">
|
||||
<td className="px-4 py-3 whitespace-nowrap">
|
||||
<Link
|
||||
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 text-xs"
|
||||
>
|
||||
{ped.pedimento_app}
|
||||
</Link>
|
||||
</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">{ped.curp_apoderado}</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.created_at ? ped.created_at.slice(0, 10) : ''}</td>
|
||||
<td className="px-4 py-4 whitespace-nowrap text-sm text-gray-900 font-semibold">
|
||||
{ped.tipo_operacion === 1
|
||||
? 'Importación'
|
||||
: ped.tipo_operacion === 2
|
||||
? 'Exportación'
|
||||
: ped.tipo_operacion}
|
||||
<td className="px-4 py-3 whitespace-nowrap text-xs text-gray-900">{ped.fecha_pago}</td>
|
||||
<td className="px-4 py-3 text-xs text-gray-900 max-w-xs truncate" title={ped.contribuyente}>{ped.contribuyente}</td>
|
||||
<td className="px-4 py-3 whitespace-nowrap text-xs text-gray-900">{ped.curp_apoderado}</td>
|
||||
<td className="px-4 py-3 whitespace-nowrap text-xs text-gray-900">{ped.numero_partidas}</td>
|
||||
<td className="px-4 py-3 whitespace-nowrap text-xs text-gray-900">{ped.created_at ? ped.created_at.slice(0, 10) : ''}</td>
|
||||
<td className="px-4 py-3 whitespace-nowrap">
|
||||
<span className="inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800">
|
||||
{ped.tipo_operacion === 1
|
||||
? 'Import.'
|
||||
: ped.tipo_operacion === 2
|
||||
? 'Export.'
|
||||
: ped.tipo_operacion}
|
||||
</span>
|
||||
</td>
|
||||
<td className="px-4 py-4 whitespace-nowrap text-sm text-gray-900 font-semibold">{ped.clave_pedimento}</td>
|
||||
<td className="px-4 py-4 whitespace-nowrap text-sm text-gray-900 font-semibold">{ped.documentos_count}</td>
|
||||
<td className="px-4 py-4 whitespace-nowrap text-sm text-gray-900 font-semibold">
|
||||
{typeof ped.documentos_peso_total === 'number'
|
||||
? (ped.documentos_peso_total / 1024).toFixed(2) + ' MB'
|
||||
: ped.documentos_peso_total}
|
||||
<td className="px-4 py-3 whitespace-nowrap text-xs text-gray-900">{ped.clave_pedimento}</td>
|
||||
<td className="px-4 py-3 whitespace-nowrap text-xs text-gray-900">{ped.documentos_count}</td>
|
||||
<td className="px-4 py-3 whitespace-nowrap text-xs text-gray-900 min-w-0">
|
||||
<div className="truncate" title={typeof ped.documentos_peso_total === 'number' ? (ped.documentos_peso_total / 1024).toFixed(2) + ' MB' : ped.documentos_peso_total}>
|
||||
{typeof ped.documentos_peso_total === 'number'
|
||||
? (ped.documentos_peso_total / 1024).toFixed(2) + ' MB'
|
||||
: ped.documentos_peso_total}
|
||||
</div>
|
||||
</td>
|
||||
<td className="px-4 py-4 whitespace-nowrap">
|
||||
<td className="px-4 py-3 whitespace-nowrap">
|
||||
<span className={`inline-flex items-center px-3 py-1 rounded-full text-xs font-semibold ${
|
||||
ped.existe_expediente
|
||||
? 'bg-green-100 text-green-800 border border-green-200'
|
||||
@@ -507,7 +511,7 @@ export default function Documents() {
|
||||
))
|
||||
) : (
|
||||
<tr>
|
||||
<td colSpan={8} className="px-6 py-12 text-center">
|
||||
<td colSpan={11} className="px-6 py-12 text-center">
|
||||
<div className="flex flex-col items-center">
|
||||
<div className="bg-gray-100 rounded-full p-4 mb-4">
|
||||
<svg className="h-8 w-8 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1044,11 +1044,11 @@ export default function Procesos() {
|
||||
style={{
|
||||
overflowY: 'visible' // Permitir que los dropdowns se muestren fuera del contenedor
|
||||
}}>
|
||||
<table className="min-w-full divide-y divide-gray-200 relative"
|
||||
<table className="min-w-full divide-y divide-gray-300 relative"
|
||||
style={{ position: 'relative', zIndex: 1 }}>
|
||||
<thead className="bg-gradient-to-r from-gray-50 to-slate-50 sticky top-0 z-10">
|
||||
<thead className="bg-gray-50 sticky top-0 z-10">
|
||||
<tr>
|
||||
<th className="px-4 py-4 text-center text-xs font-bold text-gray-600 uppercase tracking-wider rounded-tl-2xl">
|
||||
<th scope="col" className="px-6 py-3 text-center text-xs font-medium text-gray-500 uppercase tracking-wider rounded-tl-2xl">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={isSelectAll}
|
||||
|
||||
Reference in New Issue
Block a user