Files
plantillas-proyectos/frontend/src/lib/components/dashboard/invoices/delete-dialog.svelte
AlexeerCT e937f48de4 feat: add logistics tab form for invoice editing
feat: implement server-side loading for invoices page with authentication and filters

feat: create invoices page with filtering, infinite scroll, and data table

feat: add server-side loading for invoice edit page with data fetching

feat: implement invoice edit page with tabbed interface and form handling
2025-12-19 10:52:09 -06:00

112 lines
3.3 KiB
Svelte

<script lang="ts">
import { Button } from "$lib/components/ui/button";
import * as AlertDialog from "$lib/components/ui/alert-dialog";
import { invoicesApi, type Invoice } from "$lib/api/dashboard/a76/invoices";
import { companyStore } from "$lib/stores/company.svelte";
import { LoaderCircle } from 'lucide-svelte';
interface Props {
invoice: Invoice;
onClose: () => void;
onSuccess?: () => void;
}
let { invoice, onClose, onSuccess }: Props = $props();
let open = $state(true);
let loading = $state(false);
let error = $state<string | null>(null);
async function handleDelete() {
if (!invoice || !companyStore.activeCompany) return;
loading = true;
error = null;
try {
const response = await invoicesApi.delete(invoice.id, companyStore.activeCompany.id);
if (response.error) {
error = response.error;
return;
}
// Éxito
onClose();
if (onSuccess) {
onSuccess();
}
} catch (e) {
error = e instanceof Error ? e.message : "Error al eliminar";
console.error("Error deleting:", e);
} finally {
loading = false;
}
}
function handleOpenChange(newOpen: boolean) {
if (!newOpen) {
error = null;
onClose();
} else {
open = newOpen;
}
}
</script>
<AlertDialog.Root bind:open onOpenChange={handleOpenChange}>
<AlertDialog.Content>
<AlertDialog.Header>
<AlertDialog.Title>¿Estás seguro?</AlertDialog.Title>
<AlertDialog.Description class="space-y-2">
<p>Esta acción no se puede deshacer. Se eliminará permanentemente esta factura:</p>
{#if invoice}
<div class="mt-2 rounded-lg bg-muted p-3 space-y-2">
<div class="flex items-center justify-between text-sm">
<span class="font-medium">ID:</span>
<span class="font-semibold">{invoice.id}</span>
</div>
<div class="flex items-center justify-between text-sm">
<span class="font-medium">Número de Factura:</span>
<code class="font-mono font-semibold">{invoice.invoice_number || 'N/A'}</code>
</div>
<div class="flex items-center justify-between text-sm">
<span class="font-medium">Tipo:</span>
<span class="text-xs">
{invoice.operation_type === 'imp' ? 'Importación' :
invoice.operation_type === 'exp' ? 'Exportación' : 'N/A'}
</span>
</div>
<div class="flex items-center justify-between text-sm">
<span class="font-medium">Proyecto:</span>
<span class="text-xs">{invoice.project_number || 'N/A'}</span>
</div>
<div class="flex items-center justify-between text-sm">
<span class="font-medium">Pedimento:</span>
<span class="text-xs">{invoice.compliance_mx?.pedimento || 'N/A'}</span>
</div>
</div>
{/if}
{#if error}
<div class="mt-2 rounded-lg border border-destructive bg-destructive/10 p-3 text-sm text-destructive">
{error}
</div>
{/if}
</AlertDialog.Description>
</AlertDialog.Header>
<AlertDialog.Footer>
<AlertDialog.Cancel disabled={loading}>Cancelar</AlertDialog.Cancel>
<AlertDialog.Action
onclick={handleDelete}
disabled={loading}
class="bg-destructive text-destructive-foreground hover:bg-destructive/90"
>
{#if loading}
<LoaderCircle class="mr-2 h-4 w-4 animate-spin" />
{/if}
Eliminar
</AlertDialog.Action>
</AlertDialog.Footer>
</AlertDialog.Content>
</AlertDialog.Root>