125 lines
3.1 KiB
Svelte
125 lines
3.1 KiB
Svelte
<script lang="ts">
|
|
import { Button } from '$lib/components/ui/button';
|
|
import * as DropdownMenu from '$lib/components/ui/dropdown-menu';
|
|
import { driversApi, type Driver } from '$lib/api/dashboard/a76/drivers';
|
|
import { companyStore } from '$lib/stores/company.svelte';
|
|
import { EllipsisVertical, Pencil, LoaderCircle, Trash2 } from 'lucide-svelte';
|
|
import CreateEditDialog from './create-edit-dialog.svelte';
|
|
|
|
let {
|
|
item,
|
|
onSuccess,
|
|
canEdit = true,
|
|
canDelete = true
|
|
}: {
|
|
item: Driver;
|
|
onSuccess?: () => void;
|
|
canEdit?: boolean;
|
|
canDelete?: boolean;
|
|
} = $props();
|
|
|
|
let loading = $state(false);
|
|
let error = $state<string | null>(null);
|
|
let dialogOpen = $state(false);
|
|
let selectedItem = $state<Driver | null>(null);
|
|
|
|
async function handleDelete() {
|
|
if (
|
|
!confirm(
|
|
`¿Estás seguro de eliminar el conductor "${item.driver_name || item.transporter_key + '-' + item.line}"?\n\nNota: No se puede eliminar si tiene registros relacionados.`
|
|
)
|
|
) {
|
|
return;
|
|
}
|
|
|
|
if (!companyStore.activeCompany) {
|
|
alert('❌ Error: No hay una compañía seleccionada');
|
|
return;
|
|
}
|
|
|
|
loading = true;
|
|
error = null;
|
|
|
|
try {
|
|
const response = await driversApi.delete(
|
|
item.transporter_key,
|
|
item.line,
|
|
companyStore.activeCompany.id
|
|
);
|
|
|
|
if (response.error) {
|
|
if (response.status === 401) {
|
|
error = 'Sesión expirada. Recargando página...';
|
|
setTimeout(() => {
|
|
window.location.reload();
|
|
}, 1500);
|
|
} else {
|
|
error = response.error;
|
|
alert(`❌ Error al eliminar:\n\n${response.error}`);
|
|
}
|
|
return;
|
|
}
|
|
|
|
alert(
|
|
`✅ Conductor "${item.driver_name || item.transporter_key + '-' + item.line}" eliminado correctamente`
|
|
);
|
|
if (onSuccess) {
|
|
onSuccess();
|
|
}
|
|
} catch (e) {
|
|
error = e instanceof Error ? e.message : 'Error al eliminar';
|
|
alert(`❌ Error: ${error}`);
|
|
console.error('Error deleting:', e);
|
|
} finally {
|
|
loading = false;
|
|
}
|
|
}
|
|
|
|
function handleEdit() {
|
|
selectedItem = item;
|
|
dialogOpen = true;
|
|
}
|
|
|
|
function handleDialogSuccess() {
|
|
dialogOpen = false;
|
|
selectedItem = null;
|
|
if (onSuccess) {
|
|
onSuccess();
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<DropdownMenu.Root>
|
|
<DropdownMenu.Trigger>
|
|
{#snippet child({ props })}
|
|
<Button {...props} variant="ghost" size="icon" class="relative size-8 p-0">
|
|
<span class="sr-only">Abrir menú</span>
|
|
<EllipsisVertical size={16} />
|
|
</Button>
|
|
{/snippet}
|
|
</DropdownMenu.Trigger>
|
|
<DropdownMenu.Content align="end" class="w-[160px]">
|
|
<DropdownMenu.Label>Acciones</DropdownMenu.Label>
|
|
<DropdownMenu.Separator />
|
|
{#if canEdit}
|
|
<DropdownMenu.Item onclick={handleEdit}>
|
|
<Pencil size={16} class="mr-2" />
|
|
Editar
|
|
</DropdownMenu.Item>
|
|
{/if}
|
|
{#if canDelete}
|
|
<DropdownMenu.Separator />
|
|
<DropdownMenu.Item onclick={handleDelete} class="text-destructive" disabled={loading}>
|
|
{#if loading}
|
|
<LoaderCircle class="mr-2 h-4 w-4 animate-spin" />
|
|
{:else}
|
|
<Trash2 size={16} class="mr-2" />
|
|
{/if}
|
|
Eliminar
|
|
</DropdownMenu.Item>
|
|
{/if}
|
|
</DropdownMenu.Content>
|
|
</DropdownMenu.Root>
|
|
|
|
<CreateEditDialog bind:open={dialogOpen} item={selectedItem} onSuccess={handleDialogSuccess} />
|