diff --git a/frontend/messages/en.json b/frontend/messages/en.json index 3b1e30d2..f89b3438 100644 --- a/frontend/messages/en.json +++ b/frontend/messages/en.json @@ -259,7 +259,29 @@ "transporters": "Carriers", "drivers": "Drivers", "trailers": "Trailers", - "vehicles": "Vehicles" + "vehicles": "Vehicles", + "vehicle_transport_types": { + "ar": "Armored Truck", + "au": "Automobiles", + "bt": "Box Truck", + "bu": "Bus", + "bv": "Beverage Truck (Refer or not)", + "by": "Bicycle", + "co": "Construction Vehicle (general)", + "ev": "Emergency Vehicle (general)", + "fe": "Ferry", + "fm": "Farm Tractor", + "gb": "Garbage Truck", + "mc": "Motorcycle", + "oc": "Other", + "pm": "Pick-up Truck w/camper", + "pn": "Panel Truck", + "pu": "Pickup Truck", + "pv": "Passenger", + "rv": "Recreation Vehicle (RV)", + "tr": "Semi Tracker", + "tv": "Van" + } }, "reports": { "title": "Reports", diff --git a/frontend/messages/es.json b/frontend/messages/es.json index 6ecb0021..20fdeb57 100644 --- a/frontend/messages/es.json +++ b/frontend/messages/es.json @@ -258,7 +258,29 @@ "transporters": "Transportistas", "drivers": "Conductores", "trailers": "Trailers", - "vehicles": "Vehículos" + "vehicles": "Vehículos", + "vehicle_transport_types": { + "ar": "Camión Blindado", + "au": "Automóviles", + "bt": "Camión de Caja", + "bu": "Autobús", + "bv": "Camión de Bebidas", + "by": "Bicicleta", + "co": "Vehículo de Construcción", + "ev": "Vehículo de Emergencia", + "fe": "Ferry", + "fm": "Tractor Agrícola", + "gb": "Camión de Basura", + "mc": "Motocicleta", + "oc": "Otro", + "pm": "Camioneta con cabina", + "pn": "Camión Panel", + "pu": "Camioneta (Pick-up)", + "pv": "Pasajero", + "rv": "Vehículo Recreativo (RV)", + "tr": "Tractocamión", + "tv": "Van" + } }, "reports": { "title": "Reportes", diff --git a/frontend/src/lib/components/dashboard/transportation/vehicles/columns.ts b/frontend/src/lib/components/dashboard/transportation/vehicles/columns.ts index 2c9caa6f..cdda5571 100644 --- a/frontend/src/lib/components/dashboard/transportation/vehicles/columns.ts +++ b/frontend/src/lib/components/dashboard/transportation/vehicles/columns.ts @@ -5,6 +5,7 @@ import type { Vehicle } from '$lib/api/dashboard/a76/vehicles'; import type { ColumnDef } from '@tanstack/table-core'; import { renderComponent } from '$lib/components/ui/data-table'; import DataTableActions from './data-table-actions.svelte'; +import { tv, tvTransportType } from '$lib/i18n/vehicles'; export function createColumns( onSuccess: () => void, @@ -13,49 +14,50 @@ export function createColumns( return [ { accessorKey: 'vehicle_key', - header: 'Clave', + header: tv('col_key'), cell: ({ row }) => { return row.original.vehicle_key; } }, { accessorKey: 'brand', - header: 'Marca', + header: tv('col_brand'), cell: ({ row }) => { return row.original.brand || '-'; } }, { accessorKey: 'year', - header: 'Año', + header: tv('col_year'), cell: ({ row }) => { return row.original.year || '-'; } }, { accessorKey: 'plate_number', - header: 'Placas', + header: tv('col_plate'), cell: ({ row }) => { return row.original.plate_number || '-'; } }, { accessorKey: 'transporter_key', - header: 'Transportista', + header: tv('col_transporter'), cell: ({ row }) => { return row.original.transporter_key || '-'; } }, { accessorKey: 'transport_type', - header: 'Tipo Transporte', + header: tv('col_transport_type'), cell: ({ row }) => { - return row.original.transport_type || '-'; + if (!row.original.transport_type) return '-'; + return `${row.original.transport_type} - ${tvTransportType(row.original.transport_type, row.original.transport_type)}`; } }, { id: 'actions', - header: 'Acciones', + header: tv('col_actions'), cell: ({ row }) => { return renderComponent(DataTableActions, { item: row.original, diff --git a/frontend/src/lib/components/dashboard/transportation/vehicles/create-edit-dialog.svelte b/frontend/src/lib/components/dashboard/transportation/vehicles/create-edit-dialog.svelte index 8bbc2f07..b3b57717 100644 --- a/frontend/src/lib/components/dashboard/transportation/vehicles/create-edit-dialog.svelte +++ b/frontend/src/lib/components/dashboard/transportation/vehicles/create-edit-dialog.svelte @@ -11,6 +11,7 @@ import { countriesApi, type Country } from '$lib/api/dashboard/reference_data/countries'; import { statesApi, type State } from '$lib/api/dashboard/reference_data/states'; import { companyStore } from '$lib/stores/company.svelte'; + import { tv, tvTransportType } from '$lib/i18n/vehicles'; import { browser } from '$app/environment'; let { @@ -25,7 +26,7 @@ // Determinar si es modo edición o creación const isEdit = $derived(!!item); - const title = $derived(isEdit ? 'Editar Vehículo' : 'Nuevo Vehículo'); + const title = $derived(isEdit ? tv('dialog_edit_title') : tv('dialog_new_title')); // Estado del formulario let formData = $state({ @@ -66,35 +67,16 @@ let refsLoading = $state(false); const ENTITY_OPTS = [ - { value: '', label: '— Sin código —' }, + { value: '', label: tv('no_code') }, { value: 'C', label: 'C' }, { value: 'I', label: 'I' }, { value: 'A', label: 'A' }, { value: 'B', label: 'B' } ]; - const TRANSPORT_TYPE_TRANSLATIONS: Record = { - AR: 'Camión Blindado', - AU: 'Automóviles', - BT: 'Camión de Caja', - BU: 'Autobús', - BV: 'Camión de Bebidas', - BY: 'Bicicleta', - CO: 'Vehículo de Construcción', - EV: 'Vehículo de Emergencia', - FE: 'Ferry', - FM: 'Tractor Agrícola', - GB: 'Camión de Basura', - MC: 'Motocicleta', - OC: 'Otro', - PM: 'Camioneta con cabina', - PN: 'Camión Panel', - PU: 'Camioneta (Pick-up)', - PV: 'Pasajero', - RV: 'Vehículo Recreativo (RV)', - TR: 'Tractocamión', - TV: 'Van' - }; + function getTransportTypeText(transportCode?: string, description?: string): string { + return tvTransportType(transportCode, description); + } const countryM3 = $derived( countries.find((c) => c.ame_key === formData.country)?.m3_key ?? null @@ -110,7 +92,7 @@ try { const [tr, tt, cc, ss] = await Promise.all([ transportersApi.list(cid, { page: 1, page_size: 100 }), - transportTypesApi.list(1, 100), + transportTypesApi.list(cid, 1, 100), countriesApi.list(1, 100), statesApi.list(1, 100) ]); @@ -181,12 +163,12 @@ try { const companyId = companyStore.activeCompany?.id; if (!companyId) { - throw new Error('No hay una compañía seleccionada'); + throw new Error(tv('no_company_selected')); } // Validación básica if (!formData.vehicle_key.trim()) { - throw new Error('La clave del vehículo es requerida'); + throw new Error(tv('vehicle_key_required')); } let response; @@ -210,7 +192,7 @@ onSuccess(); } } catch (e) { - error = e instanceof Error ? e.message : 'Error al guardar el vehículo'; + error = e instanceof Error ? e.message : tv('save_error'); } finally { loading = false; } @@ -238,8 +220,8 @@ {title} {isEdit - ? 'Modifica los datos del vehículo' - : 'Completa los datos para crear un nuevo vehículo de transporte'} + ? tv('dialog_edit_description') + : tv('dialog_new_description')} @@ -258,21 +240,21 @@ - Información General - Seguro y Detalles + {tv('tab_general')} + {tv('tab_details')}

- Identificación del Vehículo + {tv('section_vehicle_identification')}

{tv('label_vehicle_key')} *
- - + +
- - + +
- - + +
- - + +
@@ -308,22 +290,22 @@

- Datos de Transporte + {tv('section_transport_data')}

- + {refsLoading ? '...' : formData.transporter_key ? `${formData.transporter_key} — ${transporters.find((t) => t.transporter_key === formData.transporter_key)?.name ?? ''}` - : '— Seleccionar transportista —'} + : tv('select_transporter')} - — Vacío — + {tv('empty')} {#each transporters as t} {t.transporter_key} — {t.name || t.short_name || ''} @@ -334,30 +316,30 @@
- +
- + {refsLoading ? '...' : formData.transport_type - ? `${formData.transport_type} — ${TRANSPORT_TYPE_TRANSLATIONS[formData.transport_type] || transportTypes.find((x) => x.transport_code === formData.transport_type)?.description || ''}` - : '— Opcional —'} + ? `${formData.transport_type} — ${getTransportTypeText(formData.transport_type, transportTypes.find((x) => (x.transport_code || '').trim().toUpperCase() === (formData.transport_type || '').trim().toUpperCase())?.description)}` + : tv('optional')} - — Vacío — + {tv('empty')} {#each transportTypes as x} - {x.transport_code} — {TRANSPORT_TYPE_TRANSLATIONS[x.transport_code] || x.description} + {x.transport_code} — {getTransportTypeText(x.transport_code, x.description)} {/each} @@ -365,11 +347,11 @@
- + {ENTITY_OPTS.find((o) => o.value === (formData.entity_code || ''))?.label ?? - '— Sin código —'} + tv('no_code')} {#each ENTITY_OPTS as o} @@ -377,12 +359,12 @@ {/each} -

Obligatorio al crear (reglas CSV)

+

{tv('entity_required_hint')}

- - + +
@@ -392,31 +374,31 @@

- Seguro y Otros + {tv('section_insurance')}

- +
- +
- +
- +
@@ -435,22 +417,22 @@

- Ubicación y Detalles + {tv('section_location')}

- + {refsLoading ? '...' : formData.country ? `${formData.country} — ${countries.find((c) => c.ame_key === formData.country)?.description_es ?? ''}` - : '— Opcional —'} + : tv('optional')} - — Vacío — + {tv('empty')} {#each countries as c} {c.ame_key} — {c.description_es} @@ -460,16 +442,16 @@
- + {refsLoading ? '...' : formData.state || - (formData.country ? '— Selecciona —' : '— Primero el país —')} + (formData.country ? tv('select_state') : tv('select_country_first'))} - — Vacío — + {tv('empty')} {#each statesFiltered as s} {s.description} @@ -480,21 +462,21 @@
- - + +
- - + +
- +
@@ -502,12 +484,12 @@
- +
@@ -516,10 +498,10 @@ diff --git a/frontend/src/lib/components/dashboard/transportation/vehicles/data-table-actions.svelte b/frontend/src/lib/components/dashboard/transportation/vehicles/data-table-actions.svelte index 255014ce..678d30e7 100644 --- a/frontend/src/lib/components/dashboard/transportation/vehicles/data-table-actions.svelte +++ b/frontend/src/lib/components/dashboard/transportation/vehicles/data-table-actions.svelte @@ -5,6 +5,7 @@ import { companyStore } from '$lib/stores/company.svelte'; import { EllipsisVertical, Pencil, LoaderCircle, Trash2 } from 'lucide-svelte'; import CreateEditDialog from './create-edit-dialog.svelte'; + import { tv } from '$lib/i18n/vehicles'; let { item, @@ -26,14 +27,14 @@ async function handleDelete() { if ( !confirm( - `¿Estás seguro de eliminar el vehículo "${item.vehicle_key}"?\n\nNota: No se puede eliminar si tiene registros relacionados.` + tv('delete_confirm', { key: item.vehicle_key }) ) ) { return; } if (!companyStore.activeCompany) { - alert('❌ Error: No hay una compañía seleccionada'); + alert(tv('no_company_error')); return; } @@ -45,25 +46,25 @@ if (response.error) { if (response.status === 401) { - error = 'Sesión expirada. Recargando página...'; + error = tv('session_expired'); setTimeout(() => { window.location.reload(); }, 1500); } else { error = response.error; - alert(`❌ Error al eliminar:\n\n${response.error}`); + alert(`${tv('delete_error_title')}\n\n${response.error}`); } return; } // Éxito - alert(`✅ Vehículo "${item.vehicle_key}" eliminado correctamente`); + alert(tv('delete_success_item', { key: item.vehicle_key })); if (onSuccess) { onSuccess(); } } catch (e) { - error = e instanceof Error ? e.message : 'Error al eliminar'; - alert(`❌ Error: ${error}`); + error = e instanceof Error ? e.message : tv('delete_generic_error'); + alert(tv('delete_error_alert', { error })); console.error('Error deleting:', e); } finally { loading = false; @@ -88,18 +89,18 @@ {#snippet child({ props })} {/snippet} - Acciones + {tv('menu_actions')} {#if canEdit} - Editar + {tv('edit')} {/if} {#if canDelete} @@ -110,7 +111,7 @@ {:else} {/if} - Eliminar + {tv('delete')} {/if} diff --git a/frontend/src/lib/i18n/vehicles.ts b/frontend/src/lib/i18n/vehicles.ts new file mode 100644 index 00000000..16a2efc7 --- /dev/null +++ b/frontend/src/lib/i18n/vehicles.ts @@ -0,0 +1,266 @@ +import { getLocale } from '$lib/paraglide/runtime'; + +type VehiclesLocale = 'es' | 'en'; + +const MESSAGES = { + es: { + shortcuts_scope: 'Vehículos (transporte)', + shortcuts_save: 'Guardar', + page_title: 'Vehículos (Transporte)', + page_subtitle: 'Gestión del catálogo de camiones y vehículos de transporte', + new_vehicle: 'Nuevo Vehículo', + vehicle_list: 'Listado de Vehículos', + search_key: 'Clave', + search_plate: 'Placas', + loading_vehicles: 'Cargando vehículos...', + showing_records: 'Mostrando {shown} de {total} registros', + edit: 'Editar', + delete: 'Eliminar', + delete_confirm: '¿Estás seguro de eliminar el vehículo "{key}"?\n\nNota: No se puede eliminar si tiene registros relacionados.', + delete_error_title: '❌ Error al eliminar:', + delete_success: '✅ Vehículo eliminado correctamente', + col_key: 'Clave', + col_brand: 'Marca', + col_year: 'Año', + col_plate: 'Placas', + col_transporter: 'Transportista', + col_transport_type: 'Tipo Transporte', + col_actions: 'Acciones', + menu_open: 'Abrir menú', + menu_actions: 'Acciones', + session_expired: 'Sesión expirada. Recargando página...', + no_company_error: '❌ Error: No hay una compañía seleccionada', + delete_generic_error: 'Error al eliminar', + delete_error_alert: '❌ Error: {error}', + delete_success_item: '✅ Vehículo "{key}" eliminado correctamente', + dialog_edit_title: 'Editar Vehículo', + dialog_new_title: 'Nuevo Vehículo', + dialog_edit_description: 'Modifica los datos del vehículo', + dialog_new_description: 'Completa los datos para crear un nuevo vehículo de transporte', + tab_general: 'Información General', + tab_details: 'Seguro y Detalles', + section_vehicle_identification: 'Identificación del Vehículo', + label_vehicle_key: 'Clave del Vehículo', + placeholder_vehicle_key: 'Ej: VH001', + label_brand: 'Marca', + placeholder_brand: 'Ej: Kenworth', + label_year: 'Año', + placeholder_year: 'YYYY', + label_plate_number: 'Placas', + placeholder_plate_number: 'Placas actuales', + label_series: 'Serie / VIN', + placeholder_series: 'Número de serie', + section_transport_data: 'Datos de Transporte', + label_transporter: 'Transportista', + select_transporter: '— Seleccionar transportista —', + empty: '— Vacío —', + label_transport_identifier: 'ID Transporte', + placeholder_transport_identifier: 'Identificador único', + label_transport_type: 'Tipo de Transporte', + optional: '— Opcional —', + label_entity_code: 'Código de Entidad', + no_code: '— Sin código —', + entity_required_hint: 'Obligatorio al crear (reglas CSV)', + label_sct_permission: 'Permiso SCT', + placeholder_sct_permission: 'Número de permiso', + section_insurance: 'Seguro y Otros', + label_insurance_company: 'Aseguradora', + placeholder_insurance_company: 'Nombre de la compañía', + label_insurance_number: 'Póliza', + placeholder_insurance_number: 'Número de póliza', + label_insurance_amount: 'Monto', + label_dot_number: 'Número DOT', + label_country: 'País (AME)', + label_state: 'Estado', + select_state: '— Selecciona —', + select_country_first: '— Primero el país —', + label_city: 'Ciudad', + placeholder_city: 'Ciudad/Localidad', + label_color: 'Color', + placeholder_color: 'Color del vehículo', + label_container_type: 'Tipo Contenedor', + placeholder_container_type: 'Ej: 40G', + section_location: 'Ubicación y Detalles', + label_additional_description: 'Descripción Adicional', + placeholder_additional_description: 'Notas adicionales sobre el vehículo...', + cancel: 'Cancelar', + saving: 'Guardando...', + update: 'Actualizar', + create: 'Crear', + no_company_selected: 'No hay una compañía seleccionada', + vehicle_key_required: 'La clave del vehículo es requerida', + save_error: 'Error al guardar el vehículo', + transport_types: { + AR: 'Camión Blindado', + AU: 'Automóviles', + BT: 'Camión de Caja', + BU: 'Autobús', + BV: 'Camión de Bebidas', + BY: 'Bicicleta', + CO: 'Vehículo de Construcción', + EV: 'Vehículo de Emergencia', + FE: 'Ferry', + FM: 'Tractor Agrícola', + GB: 'Camión de Basura', + MC: 'Motocicleta', + OC: 'Otro', + PM: 'Camioneta con cabina', + PN: 'Camión Panel', + PU: 'Camioneta (Pick-up)', + PV: 'Pasajero', + RV: 'Vehículo Recreativo (RV)', + TR: 'Tractocamión', + TV: 'Van' + } + }, + en: { + shortcuts_scope: 'Vehicles (transport)', + shortcuts_save: 'Save', + page_title: 'Vehicles (Transport)', + page_subtitle: 'Transport trucks and vehicles catalog management', + new_vehicle: 'New Vehicle', + vehicle_list: 'Vehicle List', + search_key: 'Key', + search_plate: 'Plates', + loading_vehicles: 'Loading vehicles...', + showing_records: 'Showing {shown} of {total} records', + edit: 'Edit', + delete: 'Delete', + delete_confirm: 'Are you sure you want to delete vehicle "{key}"?\n\nNote: It cannot be deleted if it has related records.', + delete_error_title: '❌ Error deleting:', + delete_success: '✅ Vehicle deleted successfully', + col_key: 'Key', + col_brand: 'Brand', + col_year: 'Year', + col_plate: 'Plates', + col_transporter: 'Transporter', + col_transport_type: 'Transport Type', + col_actions: 'Actions', + menu_open: 'Open menu', + menu_actions: 'Actions', + session_expired: 'Session expired. Reloading page...', + no_company_error: '❌ Error: No company selected', + delete_generic_error: 'Error deleting', + delete_error_alert: '❌ Error: {error}', + delete_success_item: '✅ Vehicle "{key}" deleted successfully', + dialog_edit_title: 'Edit Vehicle', + dialog_new_title: 'New Vehicle', + dialog_edit_description: 'Modify vehicle data', + dialog_new_description: 'Complete the data to create a new transport vehicle', + tab_general: 'General Information', + tab_details: 'Insurance and Details', + section_vehicle_identification: 'Vehicle Identification', + label_vehicle_key: 'Vehicle Key', + placeholder_vehicle_key: 'Eg: VH001', + label_brand: 'Brand', + placeholder_brand: 'Eg: Kenworth', + label_year: 'Year', + placeholder_year: 'YYYY', + label_plate_number: 'Plates', + placeholder_plate_number: 'Current plates', + label_series: 'Series / VIN', + placeholder_series: 'Serial number', + section_transport_data: 'Transport Data', + label_transporter: 'Transporter', + select_transporter: '— Select transporter —', + empty: '— Empty —', + label_transport_identifier: 'Transport ID', + placeholder_transport_identifier: 'Unique identifier', + label_transport_type: 'Transport Type', + optional: '— Optional —', + label_entity_code: 'Entity Code', + no_code: '— No code —', + entity_required_hint: 'Required on create (CSV rules)', + label_sct_permission: 'SCT Permit', + placeholder_sct_permission: 'Permit number', + section_insurance: 'Insurance and Others', + label_insurance_company: 'Insurance Company', + placeholder_insurance_company: 'Company name', + label_insurance_number: 'Policy', + placeholder_insurance_number: 'Policy number', + label_insurance_amount: 'Amount', + label_dot_number: 'DOT Number', + label_country: 'Country (AME)', + label_state: 'State', + select_state: '— Select —', + select_country_first: '— Select country first —', + label_city: 'City', + placeholder_city: 'City/Location', + label_color: 'Color', + placeholder_color: 'Vehicle color', + label_container_type: 'Container Type', + placeholder_container_type: 'Eg: 40G', + section_location: 'Location and Details', + label_additional_description: 'Additional Description', + placeholder_additional_description: 'Additional notes about the vehicle...', + cancel: 'Cancel', + saving: 'Saving...', + update: 'Update', + create: 'Create', + no_company_selected: 'No company selected', + vehicle_key_required: 'Vehicle key is required', + save_error: 'Error saving vehicle', + transport_types: { + AR: 'Armored Truck', + AU: 'Automobiles', + BT: 'Box Truck', + BU: 'Bus', + BV: 'Beverage Truck (Refer or not)', + BY: 'Bicycle', + CO: 'Construction Vehicle (general)', + EV: 'Emergency Vehicle (general)', + FE: 'Ferry', + FM: 'Farm Tractor', + GB: 'Garbage Truck', + MC: 'Motorcycle', + OC: 'Other', + PM: 'Pick-up Truck w/camper', + PN: 'Panel Truck', + PU: 'Pickup Truck', + PV: 'Passenger', + RV: 'Recreation Vehicle (RV)', + TR: 'Semi Tracker', + TV: 'Van' + } + } +} as const; + +export type VehiclesMessageKey = Exclude; + +function activeLocale(): VehiclesLocale { + if (typeof window !== 'undefined') { + const htmlLang = document.documentElement?.lang?.toLowerCase() || ''; + if (htmlLang.startsWith('es')) return 'es'; + if (htmlLang.startsWith('en')) return 'en'; + + const storedLocaleCandidates = [ + window.localStorage.getItem('locale'), + window.localStorage.getItem('lang'), + window.localStorage.getItem('language') + ] + .filter(Boolean) + .map((value) => String(value).toLowerCase()); + + if (storedLocaleCandidates.some((value) => value.startsWith('es'))) return 'es'; + if (storedLocaleCandidates.some((value) => value.startsWith('en'))) return 'en'; + } + + return getLocale().startsWith('es') ? 'es' : 'en'; +} + +export function tv(key: VehiclesMessageKey, vars?: Record): string { + const locale = activeLocale(); + let text = MESSAGES[locale][key] as string; + if (!vars) return text; + for (const [name, value] of Object.entries(vars)) { + text = text.replaceAll(`{${name}}`, String(value)); + } + return text; +} + +export function tvTransportType(code?: string, fallback?: string): string { + const normalizedCode = (code || '').trim().toUpperCase(); + if (!normalizedCode) return fallback || ''; + const locale = activeLocale(); + return MESSAGES[locale].transport_types[normalizedCode as keyof (typeof MESSAGES)['es']['transport_types']] || fallback || ''; +} diff --git a/frontend/src/routes/dashboard/general_catalogs/vehicles/+page.svelte b/frontend/src/routes/dashboard/general_catalogs/vehicles/+page.svelte index 660e044d..dc93b19f 100644 --- a/frontend/src/routes/dashboard/general_catalogs/vehicles/+page.svelte +++ b/frontend/src/routes/dashboard/general_catalogs/vehicles/+page.svelte @@ -4,7 +4,7 @@ import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; import { Input } from '$lib/components/ui/input'; - import { Plus, RefreshCw, Pencil, Trash2 } from 'lucide-svelte'; + import { Plus, Pencil, Trash2 } from 'lucide-svelte'; // Importar componentes de la librería import InfiniteDataTable from '$lib/components/dashboard/common/infinite-data-table.svelte'; @@ -16,6 +16,7 @@ import { browser } from '$app/environment'; import { useShortcuts } from '$lib/hooks/use-shortcuts'; import { obtenerAtajosCatalogoSimple } from '$lib/config/shortcuts/dashboard/general_catalogs/common/factory'; + import { tv } from '$lib/i18n/vehicles'; // --- ESTADO --- let data = $state([]); @@ -115,7 +116,7 @@ if (!selectedVehicle) return; if ( !confirm( - `¿Estás seguro de eliminar el vehículo "${selectedVehicle.vehicle_key}"?\n\nNota: No se puede eliminar si tiene registros relacionados.` + tv('delete_confirm', { key: selectedVehicle.vehicle_key }) ) ) { return; @@ -129,9 +130,9 @@ companyStore.activeCompany.id ); if (response.error) { - alert(`❌ Error al eliminar:\n\n${response.error}`); + alert(`${tv('delete_error_title')}\n\n${response.error}`); } else { - alert(`✅ Vehículo eliminado correctamente`); + alert(tv('delete_success')); selectedIds = []; loadData(); } @@ -166,7 +167,7 @@ } }); - useShortcuts('Vehículos (transporte)', [ + useShortcuts(tv('shortcuts_scope'), [ ...obtenerAtajosCatalogoSimple({ manejarNuevo: () => { createDialogOpen = true; @@ -175,7 +176,7 @@ }), { key: 'Ctrl+S', - description: 'Guardar', + description: tv('shortcuts_save'), action: () => { if (!createDialogOpen) return; document.dispatchEvent(new CustomEvent('save-form')); @@ -189,20 +190,20 @@
-

Vehículos (Transporte)

+

{tv('page_title')}

- Gestión del catálogo de camiones y vehículos de transporte + {tv('page_subtitle')}

-
+
-
Listado de Vehículos
- {#if loading && data.length === 0}
Cargando vehículos...
{:else}
(selectedIds = ids)} onRowClick={handleRowClick} onRowDoubleClick={handleRowDoubleClick} getRowId={(row) => row.vehicle_key} />
{/if}
+
{tv('vehicle_list')}
+ {#if loading && data.length === 0}
{tv('loading_vehicles')}
{:else}
(selectedIds = ids)} onRowClick={handleRowClick} onRowDoubleClick={handleRowDoubleClick} getRowId={(row) => row.vehicle_key} />
{/if}
-
Mostrando {data.length} de {totalItems} registros
+
{tv('showing_records', { shown: data.length, total: totalItems })}
@@ -220,7 +221,7 @@ disabled={selectedIds.length !== 1} > - Editar + {tv('edit')}