Files
plantillas-proyectos/frontend/src/lib/components/dashboard/identifiers/create-edit-dialog.svelte

178 lines
6.2 KiB
Svelte

<script lang="ts">
import { Button } from "$lib/components/ui/button";
import * as Dialog from "$lib/components/ui/dialog";
import { Input } from "$lib/components/ui/input";
import { Label } from "$lib/components/ui/label";
import { Textarea } from "$lib/components/ui/textarea";
// 👇 Importar tipos correctos
import {
createIdentifier,
updateIdentifier,
type Identifier
} from "$lib/api/dashboard/a76/general_catalogs/identifiers";
import { companyStore } from "$lib/stores/company.svelte";
let {
open = $bindable(false),
item = null,
onSuccess
}: {
open: boolean;
item?: Identifier | null;
onSuccess?: () => void;
} = $props();
// Calculamos si es edición basado en si hay item
const isEdit = $derived(!!item);
const title = $derived(isEdit ? "Editar Identificador" : "Nuevo Identificador");
let formData = $state({
code: '',
description: '',
level: '',
complement: ''
});
let loading = $state(false);
let error = $state<string | null>(null);
// Efecto para cargar o limpiar datos
$effect(() => {
if (open) {
if (item) {
formData = {
code: item.code,
description: item.description || '',
level: item.level || '',
complement: item.complement || ''
};
} else {
formData = {
code: '',
description: '',
level: '',
complement: ''
};
}
error = null;
}
});
async function handleSubmit() {
loading = true;
error = null;
try {
const companyId = companyStore.activeCompany?.id;
if (!companyId) throw new Error('No hay una compañía seleccionada');
// Validaciones básicas
if (!formData.code.trim()) throw new Error('La clave es requerida');
// Preparar payload (SIN company_id adentro)
const dataToSend = {
code: formData.code.trim(),
description: formData.description.trim() || null,
level: formData.level.trim() || null,
complement: formData.complement.trim() || null
};
let response;
// 👇 AQUI ESTA EL CAMBIO IMPORTANTE: companyId va por fuera
if (isEdit && item) {
response = await updateIdentifier(item.id, dataToSend, companyId);
} else {
response = await createIdentifier(dataToSend, companyId);
}
if (response.error) {
throw new Error(response.error);
}
open = false;
if (onSuccess) onSuccess();
} catch (e) {
error = e instanceof Error ? e.message : 'Error al guardar';
} finally {
loading = false;
}
}
</script>
<Dialog.Root bind:open>
<Dialog.Content class="sm:max-w-[500px]">
<Dialog.Header>
<Dialog.Title>{title}</Dialog.Title>
</Dialog.Header>
<form onsubmit={(e) => { e.preventDefault(); handleSubmit(); }} class="space-y-4 py-4">
{#if error}
<div class="rounded-md bg-destructive/15 p-3 text-sm text-destructive">
{error}
</div>
{/if}
<div class="grid gap-4">
<div class="grid grid-cols-4 items-center gap-4">
<Label for="code" class="text-right">Clave <span class="text-destructive">*</span></Label>
<div class="col-span-3">
<Input
id="code"
bind:value={formData.code}
disabled={loading || isEdit}
placeholder="Ej: CI"
maxlength={2}
required
/>
<p class="text-[10px] text-muted-foreground mt-1">Máximo 2 caracteres.</p>
</div>
</div>
<div class="grid grid-cols-4 items-center gap-4">
<Label for="description" class="text-right">Descripción</Label>
<Textarea
id="description"
bind:value={formData.description}
class="col-span-3"
disabled={loading}
maxlength={1000}
/>
</div>
<div class="grid grid-cols-4 items-center gap-4">
<Label for="level" class="text-right">Nivel</Label>
<div class="col-span-3">
<Input
id="level"
bind:value={formData.level}
disabled={loading}
placeholder="Ej: G"
maxlength={1}
/>
<p class="text-[10px] text-muted-foreground mt-1">Máximo 1 caracter (G, S, etc).</p>
</div>
</div>
<div class="grid grid-cols-4 items-center gap-4">
<Label for="complement" class="text-right">Complemento</Label>
<Textarea
id="complement"
bind:value={formData.complement}
class="col-span-3"
disabled={loading}
maxlength={5000}
/>
</div>
</div>
<Dialog.Footer>
<Button type="button" variant="outline" onclick={() => open = false} disabled={loading}>
Cancelar
</Button>
<Button type="submit" disabled={loading}>
{loading ? 'Guardando...' : isEdit ? 'Actualizar' : 'Crear'}
</Button>
</Dialog.Footer>
</form>
</Dialog.Content>
</Dialog.Root>