Files
plantillas-proyectos/frontend/src/lib/components/dashboard/pedimentos/edit/digitization-tab-form.svelte
2025-12-23 14:15:05 -06:00

415 lines
10 KiB
Svelte

<script lang="ts">
import { Card, CardContent } from '$lib/components/ui/card';
import { Button } from '$lib/components/ui/button';
import { Input } from '$lib/components/ui/input';
import { Label } from '$lib/components/ui/label';
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow
} from '$lib/components/ui/table';
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
DialogFooter
} from '$lib/components/ui/dialog';
import { Textarea } from '$lib/components/ui/textarea';
import {
Plus,
Pencil,
Trash2,
Upload,
FileText,
Search,
FolderOpen,
CheckCircle,
ChevronsLeft,
ChevronLeft,
ChevronRight,
ChevronsRight
} from 'lucide-svelte';
interface Digitalizacion {
id?: number;
linea: number;
clave: string;
documento: string;
e_document: string;
operacion: string;
observaciones: string;
}
let {
formData = $bindable({
digitalizaciones: [] as Digitalizacion[]
})
}: {
formData: {
digitalizaciones: Digitalizacion[];
};
} = $props();
// Estados para diálogo
let isDialogOpen = $state(false);
let editingIndex = $state<number | null>(null);
// Paginación
let currentPage = $state(0);
let pageSize = 10;
let currentDigitalizacion = $state<Digitalizacion>({
linea: 0,
clave: '',
documento: '',
e_document: '',
operacion: '',
observaciones: ''
});
const totalPages = $derived(
Math.ceil((formData?.digitalizaciones?.length ?? 0) / pageSize)
);
const paginatedDigitalizaciones = $derived(
formData?.digitalizaciones?.slice(
currentPage * pageSize,
(currentPage + 1) * pageSize
) ?? []
);
function openNewDigitalizacion() {
editingIndex = null;
const nextLinea = formData?.digitalizaciones?.length
? Math.max(...formData.digitalizaciones.map((d) => d.linea)) + 1
: 1;
currentDigitalizacion = {
linea: nextLinea,
clave: '',
documento: '',
e_document: '',
operacion: '',
observaciones: ''
};
isDialogOpen = true;
}
function openEditDigitalizacion(index: number) {
if (!formData?.digitalizaciones) return;
const realIndex = currentPage * pageSize + index;
editingIndex = realIndex;
currentDigitalizacion = { ...formData.digitalizaciones[realIndex] };
isDialogOpen = true;
}
function saveDigitalizacion() {
if (!formData?.digitalizaciones) return;
if (editingIndex !== null) {
formData.digitalizaciones[editingIndex] = { ...currentDigitalizacion };
} else {
formData.digitalizaciones = [...formData.digitalizaciones, { ...currentDigitalizacion }];
}
isDialogOpen = false;
}
function deleteDigitalizacion(index: number) {
if (!formData?.digitalizaciones) return;
const realIndex = currentPage * pageSize + index;
if (confirm('¿Está seguro de eliminar esta digitalización?')) {
formData.digitalizaciones = formData.digitalizaciones.filter((_, i) => i !== realIndex);
// Reordenar líneas
formData.digitalizaciones = formData.digitalizaciones.map((d, idx) => ({
...d,
linea: idx + 1
}));
// Ajustar página si es necesario
if (paginatedDigitalizaciones.length === 0 && currentPage > 0) {
currentPage--;
}
}
}
function digitalizarVU() {
alert('Digitalizar en VU no implementado aún');
}
function acuseDigitalizacion() {
alert('Acuse de Digitalización no implementado aún');
}
function procesarDigitalizacion() {
alert('Procesar Digitalización no implementado aún');
}
function consultarOperacion() {
alert('Consultar Operación no implementado aún');
}
function abrirDocumento() {
alert('Abrir Documento no implementado aún');
}
function cargarEDocument() {
alert('Cargar E-Document no implementado aún');
}
function goToFirstPage() {
currentPage = 0;
}
function goToPreviousPage() {
if (currentPage > 0) currentPage--;
}
function goToNextPage() {
if (currentPage < totalPages - 1) currentPage++;
}
function goToLastPage() {
currentPage = totalPages - 1;
}
</script>
<Card>
<CardContent class="p-6 space-y-4">
<!-- Tabla de digitalizaciones -->
<div class="border rounded-lg overflow-hidden">
<Table>
<TableHeader>
<TableRow>
<TableHead class="w-[80px]">Línea</TableHead>
<TableHead>Clave</TableHead>
<TableHead>Documento</TableHead>
<TableHead>E-Document</TableHead>
<TableHead>Operación</TableHead>
<TableHead>Observaciones</TableHead>
<TableHead class="w-[100px]">Acciones</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{#if !formData?.digitalizaciones || formData.digitalizaciones.length === 0}
<TableRow>
<TableCell colspan={7} class="text-center text-muted-foreground py-8">
No hay digitalizaciones registradas
</TableCell>
</TableRow>
{:else if paginatedDigitalizaciones.length === 0}
<TableRow>
<TableCell colspan={7} class="text-center text-muted-foreground py-8">
No hay datos en esta página
</TableCell>
</TableRow>
{:else}
{#each paginatedDigitalizaciones as digitalizacion, index}
<TableRow>
<TableCell class="font-medium">{digitalizacion.linea}</TableCell>
<TableCell>{digitalizacion.clave}</TableCell>
<TableCell>{digitalizacion.documento}</TableCell>
<TableCell>{digitalizacion.e_document}</TableCell>
<TableCell>{digitalizacion.operacion}</TableCell>
<TableCell class="max-w-[200px] truncate" title={digitalizacion.observaciones}>
{digitalizacion.observaciones}
</TableCell>
<TableCell>
<div class="flex gap-1">
<Button
size="sm"
variant="ghost"
onclick={() => openEditDigitalizacion(index)}
>
<Pencil size={14} />
</Button>
<Button size="sm" variant="ghost" onclick={() => deleteDigitalizacion(index)}>
<Trash2 size={14} />
</Button>
</div>
</TableCell>
</TableRow>
{/each}
{/if}
</TableBody>
</Table>
</div>
<!-- Controles de paginación -->
{#if formData?.digitalizaciones && formData.digitalizaciones.length > 0}
<div class="flex items-center justify-center gap-2 border-t pt-3">
<Button
size="sm"
variant="outline"
onclick={goToFirstPage}
disabled={currentPage === 0}
class="w-8 h-8 p-0"
>
<ChevronsLeft size={16} />
</Button>
<Button
size="sm"
variant="outline"
onclick={goToPreviousPage}
disabled={currentPage === 0}
class="w-8 h-8 p-0"
>
<ChevronLeft size={16} />
</Button>
<span class="text-sm text-muted-foreground px-2">
Página {currentPage + 1} de {totalPages || 1}
</span>
<Button
size="sm"
variant="outline"
onclick={goToNextPage}
disabled={currentPage >= totalPages - 1}
class="w-8 h-8 p-0"
>
<ChevronRight size={16} />
</Button>
<Button
size="sm"
variant="outline"
onclick={goToLastPage}
disabled={currentPage >= totalPages - 1}
class="w-8 h-8 p-0"
>
<ChevronsRight size={16} />
</Button>
</div>
{/if}
<!-- Botones de acción -->
<div class="flex flex-wrap gap-2 border-t pt-4">
<Button size="sm" variant="outline" onclick={digitalizarVU}>
<Upload class="mr-1.5" size={14} />
Digitalizar en VU
</Button>
<Button size="sm" variant="outline" onclick={acuseDigitalizacion}>
<CheckCircle class="mr-1.5" size={14} />
Acuse de Digitalización
</Button>
<Button size="sm" variant="outline" onclick={procesarDigitalizacion}>
<FileText class="mr-1.5" size={14} />
Procesar Digitalización
</Button>
<Button size="sm" onclick={openNewDigitalizacion}>
<Plus class="mr-1.5" size={14} />
Nuevo
</Button>
<Button
size="sm"
variant="outline"
disabled={formData?.digitalizaciones?.length === 0}
onclick={() => {
if (paginatedDigitalizaciones[0]) openEditDigitalizacion(0);
}}
>
<Pencil class="mr-1.5" size={14} />
Editar
</Button>
<Button
size="sm"
variant="destructive"
disabled={formData?.digitalizaciones?.length === 0}
onclick={() => {
if (paginatedDigitalizaciones[0]) deleteDigitalizacion(0);
}}
>
<Trash2 class="mr-1.5" size={14} />
Borrar
</Button>
<Button size="sm" variant="outline" onclick={consultarOperacion}>
<Search class="mr-1.5" size={14} />
Consultar Operación
</Button>
<Button size="sm" variant="outline" onclick={abrirDocumento}>
<FolderOpen class="mr-1.5" size={14} />
Abrir Documento
</Button>
<Button size="sm" variant="outline" onclick={cargarEDocument}>
<Upload class="mr-1.5" size={14} />
Cargar E-Document
</Button>
</div>
</CardContent>
</Card>
<!-- Dialog para Digitalización -->
<Dialog bind:open={isDialogOpen}>
<DialogContent class="max-w-2xl">
<DialogHeader>
<DialogTitle>
{editingIndex !== null ? 'Editar Digitalización' : 'Nueva Digitalización'}
</DialogTitle>
</DialogHeader>
<div class="grid gap-4 py-4">
<div class="grid grid-cols-2 gap-4">
<div class="space-y-2">
<Label for="linea">Línea *</Label>
<Input
id="linea"
type="number"
bind:value={currentDigitalizacion.linea}
placeholder="1"
readonly
/>
</div>
<div class="space-y-2">
<Label for="clave">Clave *</Label>
<Input id="clave" bind:value={currentDigitalizacion.clave} placeholder="Clave" />
</div>
</div>
<div class="space-y-2">
<Label for="documento">Documento *</Label>
<Input
id="documento"
bind:value={currentDigitalizacion.documento}
placeholder="Nombre o tipo del documento"
/>
</div>
<div class="space-y-2">
<Label for="e_document">E-Document</Label>
<Input
id="e_document"
bind:value={currentDigitalizacion.e_document}
placeholder="Referencia del documento electrónico"
/>
</div>
<div class="space-y-2">
<Label for="operacion">Operación</Label>
<Input
id="operacion"
bind:value={currentDigitalizacion.operacion}
placeholder="Tipo de operación"
/>
</div>
<div class="space-y-2">
<Label for="observaciones">Observaciones</Label>
<Textarea
id="observaciones"
bind:value={currentDigitalizacion.observaciones}
placeholder="Observaciones adicionales"
rows={3}
/>
</div>
</div>
<DialogFooter>
<Button variant="outline" onclick={() => (isDialogOpen = false)}>Cancelar</Button>
<Button
onclick={saveDigitalizacion}
disabled={!currentDigitalizacion.clave || !currentDigitalizacion.documento}
>
{editingIndex !== null ? 'Actualizar' : 'Guardar'}
</Button>
</DialogFooter>
</DialogContent>
</Dialog>