Ajustes visuales y arreglo de bugs

This commit is contained in:
2026-02-09 10:10:44 -06:00
parent 86d70bd9dd
commit 1d3fe21450
2 changed files with 477 additions and 458 deletions

View File

@@ -26,6 +26,7 @@
X,
Save
} from 'lucide-svelte';
import * as Dialog from '$lib/components/ui/dialog';
import { companyStore } from '$lib/stores/company.svelte';
import { manifestDriversApi, type ManifestDriver } from '$lib/api/dashboard/a76/manifest-drivers';
import { toast } from 'svelte-sonner';
@@ -200,278 +201,254 @@
</script>
<div class="space-y-4">
<div class="grid grid-cols-1 gap-6 {showForm ? 'lg:grid-cols-12' : ''}">
<!-- Main Table Column -->
<Card.Root
class="overflow-hidden border shadow-sm {showForm ? 'lg:col-span-7 xl:col-span-8' : ''}"
>
<Card.Header class="border-b bg-muted/30 p-2 px-3">
<div class="flex items-center justify-between">
<div class="flex items-center gap-2">
<div class="rounded-md bg-primary/10 p-1.5">
<Users class="h-4 w-4 text-primary" />
</div>
<div>
<Card.Title class="text-base font-bold tracking-tight">Tripulación</Card.Title>
<Card.Description class="text-xs">Personal activo</Card.Description>
<!-- Main Table -->
<Card.Root class="overflow-hidden border shadow-sm">
<Card.Header class="border-b bg-muted/30 p-2 px-3">
<div class="flex items-center justify-between">
<div class="flex items-center gap-2">
<div class="rounded-md bg-primary/10 p-1.5">
<Users class="h-4 w-4 text-primary" />
</div>
<div>
<Card.Title class="text-base font-bold tracking-tight">Tripulación</Card.Title>
<Card.Description class="text-xs">Personal activo</Card.Description>
</div>
</div>
<Button onclick={handleAdd} size="sm" class="h-7 gap-1.5 px-3 text-xs">
<Plus class="h-3.5 w-3.5" />
Nuevo
</Button>
</div>
</Card.Header>
<Card.Content class="p-0">
<div class="min-h-[300px] overflow-x-auto">
<table class="w-full text-left text-sm">
<thead
class="border-b bg-muted/50 text-xs font-bold tracking-wider text-muted-foreground uppercase"
>
<tr>
<th class="px-4 py-2">Nombre</th>
<th class="px-4 py-2">Tipo</th>
<th class="px-4 py-2">Ubicación</th>
<th class="w-[80px] px-4 py-2 text-right"></th>
</tr>
</thead>
<tbody class="divide-y">
{#if loading && drivers.length === 0}
<tr>
<td colspan="4" class="h-48 text-center text-muted-foreground">
<Loader2 class="mx-auto mb-2 h-6 w-6 animate-spin opacity-50" />
Cargando registros...
</td>
</tr>
{:else if drivers.length === 0}
<tr>
<td colspan="4" class="h-48 text-center text-muted-foreground">
No hay tripulación registrada en este manifiesto.
</td>
</tr>
{:else}
{#each drivers as driver, i}
<tr
class="group transition-colors hover:bg-muted/30 {editingIndex === i
? 'bg-primary/5'
: ''}"
>
<td class="px-4 py-2 text-sm font-medium">
{driver.driver_name}
</td>
<td class="px-4 py-2">
<Badge
variant="outline"
class="h-5 text-[10px] font-bold uppercase {typeLabels[
driver.driver_type as keyof typeof typeLabels
]?.color || ''}"
>
{typeLabels[driver.driver_type as keyof typeof typeLabels]?.label ||
driver.driver_type}
</Badge>
</td>
<td class="px-4 py-2 text-muted-foreground">
<div class="flex items-center gap-1 text-xs">
<MapPin class="h-3 w-3" />
{driver.city || ''}, {driver.country || ''}
</div>
</td>
<td class="px-4 py-2 text-right">
<div class="flex justify-end gap-1">
<Button
variant="ghost"
size="icon"
class="h-7 w-7"
onclick={() => handleEdit(i)}
>
<Pencil class="h-3 w-3" />
</Button>
<Button
variant="ghost"
size="icon"
class="h-7 w-7 text-destructive"
onclick={() => handleDelete(i)}
>
<Trash2 class="h-3 w-3" />
</Button>
</div>
</td>
</tr>
{/each}
{/if}
</tbody>
</table>
</div>
</Card.Content>
</Card.Root>
<!-- Member Form Dialog -->
<Dialog.Root bind:open={showForm}>
<Dialog.Content class="sm:max-w-[550px]">
<Dialog.Header>
<Dialog.Title class="flex items-center gap-2">
<UserPlus class="h-5 w-5 text-primary" />
{editingIndex !== null ? 'Editar' : 'Agregar'} Miembro de Tripulación
</Dialog.Title>
<Dialog.Description>
Ingrese los detalles del personal para este manifiesto.
</Dialog.Description>
</Dialog.Header>
<div class="grid gap-6 py-4">
<!-- Name Section -->
<div class="space-y-2">
<Label class="text-xs font-bold tracking-wide uppercase">Nombre Completo</Label>
<div class="flex gap-2">
<Input
value={formData.driver_name}
placeholder="Seleccione del catálogo..."
class="h-10 cursor-pointer bg-muted/30 text-sm"
readonly
onclick={() => (showDriverDialog = true)}
/>
<Button
variant="outline"
size="icon"
class="h-10 w-10 shrink-0"
onclick={() => (showDriverDialog = true)}
>
<FolderSearch class="h-4 w-4" />
</Button>
</div>
</div>
<!-- Address Grid -->
<div class="grid grid-cols-2 gap-4">
<div class="col-span-2 space-y-2">
<Label class="text-xs font-bold tracking-wide uppercase">Dirección Principal</Label>
<Input
bind:value={formData.address_1}
placeholder="Calle, número..."
class="h-10 text-sm"
/>
</div>
<div class="space-y-2">
<Label class="text-xs font-bold tracking-wide uppercase">Ciudad</Label>
<Input bind:value={formData.city} placeholder="Ciudad..." class="h-10 text-sm" />
</div>
<div class="space-y-2">
<Label class="text-xs font-bold tracking-wide uppercase">Estado</Label>
<Input bind:value={formData.state} placeholder="Estado..." class="h-10 text-sm" />
</div>
<div class="space-y-2">
<Label class="text-xs font-bold tracking-wide uppercase">CP</Label>
<Input bind:value={formData.postal_code} placeholder="00000" class="h-10 text-sm" />
</div>
<div class="space-y-2">
<Label class="text-xs font-bold tracking-wide uppercase">País</Label>
<div class="flex gap-2">
<Input
value={selectedCountryName || formData.country}
readonly
class="h-10 bg-muted/30 text-sm"
onclick={() => (showCountryDialog = true)}
/>
<Button
variant="outline"
size="icon"
class="h-10 w-10 shrink-0"
onclick={() => (showCountryDialog = true)}
>
<Globe class="h-4 w-4" />
</Button>
</div>
</div>
{#if !showForm}
<Button onclick={handleAdd} size="sm" class="h-7 gap-1.5 px-3 text-xs">
<Plus class="h-3.5 w-3.5" />
Nuevo
</Button>
{/if}
</div>
</Card.Header>
<Card.Content class="p-0">
<div class="min-h-[300px] overflow-x-auto">
<table class="w-full text-left text-sm">
<thead
class="border-b bg-muted/50 text-xs font-bold tracking-wider text-muted-foreground uppercase"
<!-- Role Selection -->
<div class="space-y-3 border-t pt-4">
<Label class="text-xs font-bold tracking-wide uppercase">Rol en el viaje</Label>
<RadioGroup.Root bind:value={formData.driver_type} class="grid grid-cols-3 gap-3">
<label
for="modal-r-cond"
class="flex cursor-pointer flex-col items-center justify-center rounded-xl border p-3 py-4 transition-all hover:bg-muted/50 {formData.driver_type ===
'C'
? 'border-primary bg-primary/5 ring-1 ring-primary'
: 'bg-muted/10'}"
>
<tr>
<th class="px-4 py-2">Nombre</th>
<th class="px-4 py-2">Tipo</th>
<th class="px-4 py-2 {showForm ? 'hidden xl:table-cell' : ''}">Ubicación</th>
<th class="w-[80px] px-4 py-2 text-right"></th>
</tr>
</thead>
<tbody class="divide-y">
{#if loading && drivers.length === 0}
<tr>
<td colspan="4" class="h-48 text-center text-muted-foreground">
<Loader2 class="mx-auto mb-2 h-6 w-6 animate-spin opacity-50" />
Cargando registros...
</td>
</tr>
{:else if drivers.length === 0}
<tr>
<td colspan="4" class="h-48 text-center text-muted-foreground">
No hay tripulación registrada en este manifiesto.
</td>
</tr>
{:else}
{#each drivers as driver, i}
<tr
class="group transition-colors hover:bg-muted/30 {editingIndex === i
? 'bg-primary/5'
: ''}"
>
<td class="px-4 py-2 text-sm font-medium">
{driver.driver_name}
</td>
<td class="px-4 py-2">
<Badge
variant="outline"
class="h-5 text-[10px] font-bold uppercase {typeLabels[
driver.driver_type as keyof typeof typeLabels
]?.color || ''}"
>
{typeLabels[driver.driver_type as keyof typeof typeLabels]?.label ||
driver.driver_type}
</Badge>
</td>
<td
class="px-4 py-2 text-muted-foreground {showForm
? 'hidden xl:table-cell'
: ''}"
>
<div class="flex items-center gap-1 text-xs">
<MapPin class="h-3 w-3" />
{driver.city || ''}, {driver.country || ''}
</div>
</td>
<td class="px-4 py-2 text-right">
<div class="flex justify-end gap-1">
<Button
variant="ghost"
size="icon"
class="h-7 w-7"
onclick={() => handleEdit(i)}
>
<Pencil class="h-3 w-3" />
</Button>
<Button
variant="ghost"
size="icon"
class="h-7 w-7 text-destructive"
onclick={() => handleDelete(i)}
>
<Trash2 class="h-3 w-3" />
</Button>
</div>
</td>
</tr>
{/each}
{/if}
</tbody>
</table>
<User
class="mb-2 h-5 w-5 {formData.driver_type === 'C'
? 'text-primary'
: 'text-muted-foreground'}"
/>
<span class="text-xs font-bold">Conductor</span>
<RadioGroup.Item value="C" id="modal-r-cond" class="sr-only" />
</label>
<label
for="modal-r-miem"
class="flex cursor-pointer flex-col items-center justify-center rounded-xl border p-3 py-4 transition-all hover:bg-muted/50 {formData.driver_type ===
'M'
? 'border-primary bg-primary/5 ring-1 ring-primary'
: 'bg-muted/10'}"
>
<Users
class="mb-2 h-5 w-5 {formData.driver_type === 'M'
? 'text-primary'
: 'text-muted-foreground'}"
/>
<span class="text-xs font-bold">Tripulante</span>
<RadioGroup.Item value="M" id="modal-r-miem" class="sr-only" />
</label>
<label
for="modal-r-pas"
class="flex cursor-pointer flex-col items-center justify-center rounded-xl border p-3 py-4 transition-all hover:bg-muted/50 {formData.driver_type ===
'P'
? 'border-primary bg-primary/5 ring-1 ring-primary'
: 'bg-muted/10'}"
>
<UserCheck
class="mb-2 h-5 w-5 {formData.driver_type === 'P'
? 'text-primary'
: 'text-muted-foreground'}"
/>
<span class="text-xs font-bold">Pasajero</span>
<RadioGroup.Item value="P" id="modal-r-pas" class="sr-only" />
</label>
</RadioGroup.Root>
</div>
</Card.Content>
</Card.Root>
<!-- Side Form Column -->
{#if showForm}
<div class="lg:col-span-5 xl:col-span-4" transition:fly={{ x: 20, duration: 300 }}>
<Card.Root class="sticky top-6 border shadow-lg">
<Card.Header class="flex flex-row items-center justify-between border-b pb-3">
<div>
<Card.Title class="text-base font-bold">
{editingIndex !== null ? 'Editar' : 'Agregar'} Miembro
</Card.Title>
<Card.Description class="text-[10px] font-medium"
>Llene los datos requeridos</Card.Description
>
</div>
<Button variant="ghost" size="icon" class="h-8 w-8 rounded-full" onclick={handleCancel}>
<X class="h-4 w-4" />
</Button>
</Card.Header>
<Card.Content class="space-y-4 p-6">
<div class="space-y-1.5">
<Label class="text-xs font-bold">Nombre Completo</Label>
<div class="flex gap-1">
<Input
bind:value={formData.driver_name}
placeholder="Nombre del personal..."
class="h-9 text-sm"
/>
<Button
variant="outline"
size="icon"
class="h-9 w-9 shrink-0"
onclick={() => (showDriverDialog = true)}
>
<FolderSearch class="h-4 w-4" />
</Button>
</div>
</div>
<div class="grid grid-cols-2 gap-4 text-xs font-bold">
<div class="col-span-2 space-y-1.5">
<Label class="text-xs font-bold">Calle 1/Principal</Label>
<Input
bind:value={formData.address_1}
placeholder="Dirección principal..."
class="h-9 text-sm"
/>
</div>
<div class="col-span-2 space-y-1.5">
<Label class="text-xs font-bold">Calle 2 (Opcional)</Label>
<Input
bind:value={formData.address_2}
placeholder="Referencias..."
class="h-9 text-sm"
/>
</div>
<div class="space-y-1.5">
<Label class="text-xs font-bold">Ciudad</Label>
<Input bind:value={formData.city} placeholder="Ciudad..." class="h-9 text-sm" />
</div>
<div class="space-y-1.5">
<Label class="text-xs font-bold">Estado</Label>
<Input bind:value={formData.state} placeholder="Estado..." class="h-9 text-sm" />
</div>
<div class="space-y-1.5">
<Label class="text-xs font-bold">CP</Label>
<Input bind:value={formData.postal_code} placeholder="00000" class="h-9 text-sm" />
</div>
<div class="col-span-2 space-y-1.5 pt-1">
<Label class="text-xs font-bold">País</Label>
<div class="flex gap-1">
<Input
value={selectedCountryName || formData.country}
readonly
class="h-9 bg-muted/30 text-sm"
onclick={() => (showCountryDialog = true)}
/>
<Button
variant="outline"
size="icon"
class="h-9 w-9 shrink-0"
onclick={() => (showCountryDialog = true)}
>
<Globe class="h-4 w-4" />
</Button>
</div>
</div>
</div>
<div class="space-y-3 pt-2">
<Label class="text-xs font-bold">Rol en el viaje</Label>
<RadioGroup.Root bind:value={formData.driver_type} class="grid grid-cols-3 gap-2">
<label
for="r-cond"
class="flex cursor-pointer flex-col items-center justify-center rounded-lg border p-2 py-3 transition-colors hover:bg-muted/50 {formData.driver_type ===
'C'
? 'border-primary bg-primary/5'
: 'bg-muted/10'}"
>
<User
class="mb-1 h-4 w-4 {formData.driver_type === 'C'
? 'text-primary'
: 'text-muted-foreground'}"
/>
<span class="text-[10px] font-bold">Conductor</span>
<RadioGroup.Item value="C" id="r-cond" class="sr-only" />
</label>
<label
for="r-miem"
class="flex cursor-pointer flex-col items-center justify-center rounded-lg border p-2 py-3 transition-colors hover:bg-muted/50 {formData.driver_type ===
'M'
? 'border-primary bg-primary/5'
: 'bg-muted/10'}"
>
<Users
class="mb-1 h-4 w-4 {formData.driver_type === 'M'
? 'text-primary'
: 'text-muted-foreground'}"
/>
<span class="text-[10px] font-bold">Tripulante</span>
<RadioGroup.Item value="M" id="r-miem" class="sr-only" />
</label>
<label
for="r-pas"
class="flex cursor-pointer flex-col items-center justify-center rounded-lg border p-2 py-3 transition-colors hover:bg-muted/50 {formData.driver_type ===
'P'
? 'border-primary bg-primary/5'
: 'bg-muted/10'}"
>
<UserCheck
class="mb-1 h-4 w-4 {formData.driver_type === 'P'
? 'text-primary'
: 'text-muted-foreground'}"
/>
<span class="text-[10px] font-bold">Pasajero</span>
<RadioGroup.Item value="P" id="r-pas" class="sr-only" />
</label>
</RadioGroup.Root>
</div>
</Card.Content>
<Card.Footer class="flex justify-end gap-2 border-t bg-muted/20 p-4">
<Button variant="ghost" size="sm" onclick={handleCancel} disabled={saving}
>Cancelar</Button
>
<Button
size="sm"
onclick={handleSave}
disabled={saving}
class="gap-2 font-bold shadow-sm"
>
{#if saving}
<Loader2 class="h-3.5 w-3.5 animate-spin" />
Guardando...
{:else}
<Save class="h-3.5 w-3.5" />
Guardar
{/if}
</Button>
</Card.Footer>
</Card.Root>
</div>
{/if}
</div>
<Dialog.Footer class="gap-2 sm:gap-0">
<Button variant="ghost" onclick={handleCancel} disabled={saving}>Cancelar</Button>
<Button onclick={handleSave} disabled={saving} class="min-w-[120px] font-bold">
{#if saving}
<Loader2 class="mr-2 h-4 w-4 animate-spin" />
Guardando...
{:else}
<Save class="mr-2 h-4 w-4" />
Guardar cambios
{/if}
</Button>
</Dialog.Footer>
</Dialog.Content>
</Dialog.Root>
</div>
<DriverSelectorDialog bind:open={showDriverDialog} onSelect={handleDriverSelect} />

View File

@@ -7,6 +7,7 @@
import { Separator } from '$lib/components/ui/separator';
import { Textarea } from '$lib/components/ui/textarea';
import * as Tabs from '$lib/components/ui/tabs';
import * as Select from '$lib/components/ui/select';
import { Switch } from '$lib/components/ui/switch';
import { Checkbox } from '$lib/components/ui/checkbox';
import { Badge } from '$lib/components/ui/badge';
@@ -29,7 +30,8 @@
DollarSign,
FileSpreadsheet,
Globe,
Users
Users,
Circle
} from 'lucide-svelte';
import { manifestApi, type Manifest } from '$lib/api/dashboard/a76/manifests';
import { toast } from 'svelte-sonner';
@@ -138,7 +140,8 @@
transport_key: '',
transport_mode: '',
trailer_number: '',
status_description: ''
status_description: '',
vehicle_status: 'NUEVO'
});
// Consolidated Categorized Lists (Merges Available + Selected)
@@ -690,74 +693,70 @@
<div class="mx-auto max-w-[1400px] pb-48">
<Tabs.Root bind:value={activeTab}>
<!-- Top Fields (Global across tabs) -->
<Card.Root class="mb-2.5 border-primary/5 shadow-sm">
<Card.Content class="p-2.5 py-1.5">
<div class="grid grid-cols-1 gap-2.5 md:grid-cols-4">
<div class="space-y-0.5">
<Label class="text-[8px] font-bold text-muted-foreground uppercase"
>Número de Manifiesto</Label
>
<div class="relative">
<Package class="absolute top-1.5 left-2 h-3 w-3 text-muted-foreground" />
<Input
bind:value={formData.manifest_number}
class="h-7 bg-muted/20 pl-7 font-mono text-[10px]"
placeholder="MAN-000"
/>
</div>
</div>
<div class="space-y-0.5">
<Label class="text-[8px] font-bold text-muted-foreground uppercase"
>Fecha Entrada/Arribo</Label
>
<div class="relative">
<Calendar
class="pointer-events-none absolute top-1.5 left-2 h-3 w-3 text-muted-foreground"
/>
<Input type="date" bind:value={entryDateStr} class="h-7 pl-7 text-[10px]" />
</div>
</div>
<div class="space-y-0.5">
<Label class="text-[8px] font-bold text-muted-foreground uppercase"
>Transportista</Label
>
<div class="flex gap-1">
<div class="relative w-full">
<Truck class="absolute top-1.5 left-2 h-3 w-3 text-muted-foreground" />
<Input
value={selectedTransporterName || formData.carrier_code}
class="h-7 pl-7 font-mono text-[10px]"
placeholder="Catálogo..."
readonly
onclick={() => (showTransporterModal = true)}
/>
</div>
<Button
variant="outline"
size="icon"
class="h-7 w-7 shrink-0"
onclick={() => (showTransporterModal = true)}
>
<FolderSearch class="h-3 w-3" />
</Button>
</div>
</div>
<div class="space-y-0.5">
<Label class="text-[8px] font-bold text-muted-foreground uppercase"
>Persona a Cargo</Label
>
<div class="relative">
<User class="absolute top-1.5 left-2 h-3 w-3 text-muted-foreground" />
<Input
bind:value={formData.person_in_charge}
class="h-7 pl-7 text-[10px]"
placeholder="Nombre completo"
/>
</div>
</div>
<!-- Top Fields (Global across tabs) - Compact & Clean (Like Invoice Form) -->
<div class="mb-4 grid grid-cols-1 gap-3 border-b pb-4 md:grid-cols-4">
<div class="space-y-0.5">
<Label class="text-[9px] font-bold text-muted-foreground uppercase"
>Número de Manifiesto</Label
>
<div class="relative">
<Package class="absolute top-1.5 left-2 h-3 w-3 text-muted-foreground" />
<Input
bind:value={formData.manifest_number}
class="h-7 pl-7 font-mono text-[10px]"
placeholder="MAN-000"
/>
</div>
</Card.Content>
</Card.Root>
</div>
<div class="space-y-0.5">
<Label class="text-[9px] font-bold text-muted-foreground uppercase"
>Fecha Entrada/Arribo</Label
>
<div class="relative">
<Calendar
class="pointer-events-none absolute top-1.5 left-2 h-3 w-3 text-muted-foreground"
/>
<Input type="date" bind:value={entryDateStr} class="h-7 pl-7 text-[10px]" />
</div>
</div>
<div class="space-y-0.5">
<Label class="text-[9px] font-bold text-muted-foreground uppercase">Transportista</Label
>
<div class="flex gap-1">
<div class="relative w-full">
<Truck class="absolute top-1.5 left-2 h-3 w-3 text-muted-foreground" />
<Input
value={selectedTransporterName || formData.carrier_code}
class="h-7 pl-7 font-mono text-[10px]"
placeholder="Catálogo..."
readonly
onclick={() => (showTransporterModal = true)}
/>
</div>
<Button
variant="outline"
size="icon"
class="h-7 w-7 shrink-0"
onclick={() => (showTransporterModal = true)}
>
<FolderSearch class="h-3 w-3" />
</Button>
</div>
</div>
<div class="space-y-0.5">
<Label class="text-[9px] font-bold text-muted-foreground uppercase"
>Persona a Cargo</Label
>
<div class="relative">
<User class="absolute top-1.5 left-2 h-3 w-3 text-muted-foreground" />
<Input
bind:value={formData.person_in_charge}
class="h-7 pl-7 text-[10px]"
placeholder="Nombre completo"
/>
</div>
</div>
</div>
<Tabs.Content value="generales" class="animate-in fade-in space-y-6 duration-300">
<div class="grid grid-cols-1 gap-6 md:grid-cols-12">
@@ -1032,133 +1031,176 @@
</Tabs.Content>
<Tabs.Content value="cont" class="animate-in fade-in space-y-6 duration-300">
<ManifestDriverSubForm
manifestNumber={formData.manifest_number}
carrierName={selectedTransporterName || formData.carrier_code}
isNewManifest={isNew}
/>
<div class="grid grid-cols-1 gap-6 lg:grid-cols-12">
<!-- Left Side: Attributes and Truck Info -->
<div class="space-y-6 lg:col-span-5 xl:col-span-4">
<!-- Attributes -->
<Card.Root class="shadow-sm">
<Card.Header class="pb-3">
<Card.Title
class="flex items-center gap-2 text-sm font-bold tracking-wider uppercase"
>
<Info class="h-4 w-4 text-primary" />
Atributos
</Card.Title>
</Card.Header>
<Card.Content class="space-y-4">
<div class="space-y-2">
<Label class="text-xs font-bold">Entry Type (Tipo Manifiesto)</Label>
<Input bind:value={formData.entry_type} placeholder="Ej: General" class="h-9" />
</div>
<div
class="flex items-center justify-between rounded-xl border border-orange-100 bg-orange-50/20 p-4"
>
<div class="flex gap-3">
<AlertTriangle class="h-5 w-5 text-orange-600" />
<div>
<Label class="block text-sm font-bold">Material Peligroso</Label>
<p class="text-xs text-muted-foreground italic">¿Riesgo?</p>
</div>
</div>
<Switch bind:checked={formData.is_hazardous} />
</div>
</Card.Content>
</Card.Root>
<Separator />
<div class="grid grid-cols-1 gap-6 md:grid-cols-2">
<!-- Config -->
<Card.Root class="shadow-sm">
<Card.Header>
<Card.Title class="flex items-center gap-2 text-base">
<Info class="h-4 w-4 text-primary" />
Atributos del Manifiesto
</Card.Title>
</Card.Header>
<Card.Content class="space-y-4">
<div class="space-y-2">
<Label>Entry Type (Tipo Manifiesto)</Label>
<Input bind:value={formData.entry_type} placeholder="Ej: General" />
</div>
<div
class="flex items-center justify-between rounded-xl border border-orange-100 bg-orange-50/20 p-4"
>
<div class="flex gap-3">
<AlertTriangle class="h-5 w-5 text-orange-600" />
<div>
<Label class="block text-sm font-bold">Material Peligroso</Label>
<p class="text-xs text-muted-foreground italic">
¿Contiene mercancía de riesgo?
</p>
<!-- Truck Details -->
<Card.Root class="shadow-sm">
<Card.Header class="pb-3">
<Card.Title
class="flex items-center gap-2 text-sm font-bold tracking-wider uppercase"
>
<Truck class="h-4 w-4 text-primary" />
Vehículo
</Card.Title>
</Card.Header>
<Card.Content class="space-y-4">
<div class="grid grid-cols-2 gap-4">
<div class="space-y-2">
<Label class="text-xs font-bold uppercase">Clave Transporte</Label>
<div class="flex gap-2">
<Input
bind:value={formData.transport_key}
placeholder="..."
readonly
onclick={() => (showVehicleModal = true)}
class="h-9 font-mono text-xs"
/>
<Button
variant="outline"
size="icon"
class="h-9 w-9 shrink-0"
onclick={() => (showVehicleModal = true)}
><FolderSearch class="h-4 w-4" /></Button
>
</div>
</div>
<div class="space-y-2">
<Label class="text-xs font-bold uppercase">Modo Transporte</Label>
<div class="flex gap-2">
<Input
bind:value={formData.transport_mode}
placeholder="..."
readonly
onclick={() => (showTransportModeModal = true)}
class="h-9 font-mono text-xs"
/>
<Button
variant="outline"
size="icon"
class="h-9 w-9 shrink-0"
onclick={() => (showTransportModeModal = true)}
><FolderSearch class="h-4 w-4" /></Button
>
</div>
</div>
<div class="space-y-2">
<Label class="text-xs font-bold uppercase"># Trailer</Label>
<div class="flex gap-2">
<Input
value={selectedTrailerPlate || formData.trailer_number}
placeholder="..."
readonly
onclick={() => (showTrailerModal = true)}
class="h-9 font-mono text-xs"
/>
<Button
variant="outline"
size="icon"
class="h-9 w-9 shrink-0"
onclick={() => (showTrailerModal = true)}
><FolderSearch class="h-4 w-4" /></Button
>
</div>
</div>
<!-- Status Field (Vehicle specific, local state for now) -->
<div class="space-y-2">
<Label class="text-xs font-bold uppercase">Estatus Vehículo</Label>
<Select.Root
type="single"
bind:value={formData.vehicle_status}
onValueChange={(v) => (formData.vehicle_status = v)}
>
<Select.Trigger class="h-9 px-3 text-xs">
<div class="flex items-center gap-2">
{#if formData.vehicle_status === 'NUEVO'}
<Circle class="h-2 w-2 fill-green-500 text-green-500" />
{:else if formData.vehicle_status === 'USADO'}
<Circle class="h-2 w-2 fill-blue-500 text-blue-500" />
{:else if formData.vehicle_status === 'CANCELADO'}
<Circle class="h-2 w-2 fill-red-500 text-red-500" />
{:else}
<Circle class="h-2 w-2 fill-slate-300 text-slate-300" />
{/if}
<span class="truncate uppercase"
>{formData.vehicle_status || 'Estado'}</span
>
</div>
</Select.Trigger>
<Select.Content>
<Select.Item value="NUEVO" class="text-xs">
<div class="flex items-center gap-2">
<Circle class="h-2 w-2 fill-green-500 text-green-500" />
NUEVO
</div>
</Select.Item>
<Select.Item value="USADO" class="text-xs">
<div class="flex items-center gap-2">
<Circle class="h-2 w-2 fill-blue-500 text-blue-500" />
USADO
</div>
</Select.Item>
<Select.Item value="CANCELADO" class="text-xs">
<div class="flex items-center gap-2">
<Circle class="h-2 w-2 fill-red-500 text-red-500" />
CANCELADO
</div>
</Select.Item>
</Select.Content>
</Select.Root>
</div>
</div>
<Switch bind:checked={formData.is_hazardous} />
</div>
</Card.Content>
</Card.Root>
<Separator />
<div class="space-y-2">
<Label class="text-xs font-bold uppercase">Observaciones</Label>
<Textarea
bind:value={formData.status_description}
placeholder="Notas sobre el estado..."
class="min-h-[80px] text-xs"
/>
</div>
</Card.Content>
</Card.Root>
</div>
<!-- Truck -->
<Card.Root class="shadow-sm">
<Card.Header>
<Card.Title class="flex items-center gap-2 text-base">
<Truck class="h-4 w-4 text-primary" />
Detalles del Camión (Truck)
</Card.Title>
</Card.Header>
<Card.Content class="space-y-4">
<div class="grid grid-cols-2 gap-4">
<div class="space-y-2">
<Label class="text-xs font-bold uppercase">Clave Transporte</Label>
<div class="flex gap-2">
<Input
bind:value={formData.transport_key}
placeholder="..."
readonly
onclick={() => (showVehicleModal = true)}
class="font-mono"
/>
<Button
variant="outline"
size="icon"
onclick={() => (showVehicleModal = true)}
><FolderSearch class="h-4 w-4" /></Button
>
</div>
{#if selectedVehicleName}
<p class="truncate px-1 text-[10px] text-muted-foreground">
{selectedVehicleName}
</p>
{/if}
</div>
<div class="space-y-2">
<Label class="text-xs font-bold uppercase">Modo Transporte</Label>
<div class="flex gap-2">
<Input
bind:value={formData.transport_mode}
placeholder="..."
readonly
onclick={() => (showTransportModeModal = true)}
class="font-mono"
/>
<Button
variant="outline"
size="icon"
onclick={() => (showTransportModeModal = true)}
><FolderSearch class="h-4 w-4" /></Button
>
</div>
{#if selectedTransportTypeName}
<p class="truncate px-1 text-[10px] text-muted-foreground">
{selectedTransportTypeName}
</p>
{/if}
</div>
<div class="space-y-2">
<Label class="text-xs font-bold uppercase"># Trailer</Label>
<div class="flex gap-2">
<Input
value={selectedTrailerPlate || formData.trailer_number}
placeholder="..."
readonly
onclick={() => (showTrailerModal = true)}
class="font-mono"
/>
<Button
variant="outline"
size="icon"
onclick={() => (showTrailerModal = true)}
><FolderSearch class="h-4 w-4" /></Button
>
</div>
{#if selectedTrailerPlate && selectedTrailerPlate !== formData.trailer_number}
<!-- Plate already shown in Input -->
{/if}
</div>
</div>
<Separator />
<div class="space-y-2">
<Label class="text-xs font-bold uppercase">Estatus y Observaciones</Label>
<Textarea
bind:value={formData.status_description}
placeholder="Notas sobre el estado del transporte..."
class="min-h-[100px]"
/>
</div>
</Card.Content>
</Card.Root>
<!-- Right Side: Crew/Tripulación Table -->
<div class="lg:col-span-7 xl:col-span-8">
<ManifestDriverSubForm
manifestNumber={formData.manifest_number}
carrierName={selectedTransporterName || formData.carrier_code}
isNewManifest={isNew}
/>
</div>
</div>
</Tabs.Content>
<Tabs.Content value="facturas_expo" class="animate-in fade-in space-y-8 duration-300">