feature/nav-tab-client-provider
This commit is contained in:
@@ -22,6 +22,9 @@ export const GLOBAL_NAV = {
|
||||
// Customs & Brokers
|
||||
'a': '/dashboard/customs_brokers',
|
||||
|
||||
// Clients & Providers
|
||||
'o': '/dashboard/clients_and_providers',
|
||||
|
||||
// Invoices
|
||||
'i': '/dashboard/invoices',
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import type { ShortcutDef } from '$lib/stores/shortcut-store';
|
||||
|
||||
export const obtenerAtajosEdicionSocio = (acciones: {
|
||||
irGeneral: () => void;
|
||||
irDireccion: () => void;
|
||||
irProgramas: () => void;
|
||||
irConfig: () => void;
|
||||
guardar: () => void;
|
||||
cancelar: () => void;
|
||||
}): ShortcutDef[] => [
|
||||
{
|
||||
key: 'Alt+Digit1',
|
||||
description: 'Tab General',
|
||||
action: acciones.irGeneral
|
||||
},
|
||||
{
|
||||
key: 'Alt+Digit2',
|
||||
description: 'Tab Dirección',
|
||||
action: acciones.irDireccion
|
||||
},
|
||||
{
|
||||
key: 'Alt+Digit3',
|
||||
description: 'Tab Programas',
|
||||
action: acciones.irProgramas
|
||||
},
|
||||
{
|
||||
key: 'Alt+Digit4',
|
||||
description: 'Tab Configuración',
|
||||
action: acciones.irConfig
|
||||
},
|
||||
{
|
||||
key: 'Ctrl+S',
|
||||
description: 'Guardar',
|
||||
action: acciones.guardar
|
||||
},
|
||||
{
|
||||
key: 'Escape',
|
||||
description: 'Cancelar / Volver',
|
||||
action: acciones.cancelar
|
||||
}
|
||||
];
|
||||
@@ -0,0 +1,38 @@
|
||||
import type { ShortcutDef } from '$lib/stores/shortcut-store';
|
||||
|
||||
export const obtenerAtajosListaSocios = (acciones: {
|
||||
filtrarTodos: () => void;
|
||||
filtrarClientes: () => void;
|
||||
filtrarProveedores: () => void;
|
||||
nuevo: () => void;
|
||||
recargar: () => void;
|
||||
}): ShortcutDef[] => [
|
||||
{
|
||||
key: 'Alt+Digit1',
|
||||
description: 'Ver Todos',
|
||||
action: acciones.filtrarTodos,
|
||||
context: 'Clients Providers Navigation'
|
||||
},
|
||||
{
|
||||
key: 'Alt+Digit2',
|
||||
description: 'Ver Clientes',
|
||||
action: acciones.filtrarClientes,
|
||||
context: 'Clients Providers Navigation'
|
||||
},
|
||||
{
|
||||
key: 'Alt+Digit3',
|
||||
description: 'Ver Proveedores',
|
||||
action: acciones.filtrarProveedores,
|
||||
context: 'Clients Providers Navigation'
|
||||
},
|
||||
{
|
||||
key: 'Alt+Shift+N',
|
||||
description: 'Nuevo Socio',
|
||||
action: acciones.nuevo
|
||||
},
|
||||
{
|
||||
key: 'Alt+Shift+R',
|
||||
description: 'Actualizar Lista',
|
||||
action: acciones.recargar
|
||||
}
|
||||
];
|
||||
@@ -3,7 +3,10 @@
|
||||
import { browser } from '$app/environment';
|
||||
import { goto } from '$app/navigation';
|
||||
import { page } from '$app/stores';
|
||||
import { clientsProvidersApi, type ClientProvider } from '$lib/api/dashboard/a76/clients-providers';
|
||||
import {
|
||||
clientsProvidersApi,
|
||||
type ClientProvider
|
||||
} from '$lib/api/dashboard/a76/clients-providers';
|
||||
import { Button } from '$lib/components/ui/button';
|
||||
import * as Card from '$lib/components/ui/card';
|
||||
import { Input } from '$lib/components/ui/input';
|
||||
@@ -21,7 +24,7 @@
|
||||
let items = $state<ClientProvider[]>(data.items || []);
|
||||
let selectedItem = $state<ClientProvider | null>(null);
|
||||
let isLoading = $state(false);
|
||||
|
||||
|
||||
// Server-side filtering/pagination parameters
|
||||
let currentPage = $state(data.page || 1);
|
||||
let pageSize = $state(50);
|
||||
@@ -37,7 +40,7 @@
|
||||
let error = $state<string | ApiError | null>(data.error || null);
|
||||
|
||||
// --- Lifecycle ---
|
||||
|
||||
|
||||
onMount(() => {
|
||||
if (browser) {
|
||||
// Sincronizar token de cookies a localStorage si es necesario
|
||||
@@ -49,7 +52,8 @@
|
||||
};
|
||||
const cookieToken = getCookie('access_token');
|
||||
const localToken = localStorage.getItem('access_token');
|
||||
if (cookieToken && cookieToken !== localToken) localStorage.setItem('access_token', cookieToken);
|
||||
if (cookieToken && cookieToken !== localToken)
|
||||
localStorage.setItem('access_token', cookieToken);
|
||||
|
||||
// Listen for company changes
|
||||
const handleCompanyChange = () => loadItems(1); // Reload from page 1
|
||||
@@ -68,9 +72,9 @@
|
||||
try {
|
||||
const filters: any = {};
|
||||
if (searchType !== 'both') filters.type = searchType;
|
||||
// Note: The API technically supports name/rfc fitlering if backend implements it.
|
||||
// Assuming backend supports 'name' and 'rfc' query params based on standard patterns,
|
||||
// or we filter client side if the list is small.
|
||||
// Note: The API technically supports name/rfc fitlering if backend implements it.
|
||||
// Assuming backend supports 'name' and 'rfc' query params based on standard patterns,
|
||||
// or we filter client side if the list is small.
|
||||
// Given pagination, we should try sending them. If backend ignores them, we might need client filtering.
|
||||
// Ideally backend should handle this. I will assume backend filters for now or add query params.
|
||||
if (searchName) filters.name = searchName;
|
||||
@@ -105,7 +109,7 @@
|
||||
searchType = value;
|
||||
loadItems(1);
|
||||
}
|
||||
|
||||
|
||||
function handleSearch() {
|
||||
loadItems(1);
|
||||
}
|
||||
@@ -118,10 +122,13 @@
|
||||
if (selectedItem) goto(`/dashboard/clients_and_providers/edit/${selectedItem.id}`);
|
||||
}
|
||||
|
||||
import { useShortcuts } from '$lib/hooks/use-shortcuts';
|
||||
import { obtenerAtajosListaSocios } from '$lib/config/shortcuts/clients-providers-list-shortcuts';
|
||||
|
||||
async function handleDelete() {
|
||||
if (!selectedItem || !companyStore.activeCompany?.id) return;
|
||||
if (!confirm('¿Estás seguro de eliminar este registro?')) return;
|
||||
|
||||
|
||||
try {
|
||||
await clientsProvidersApi.delete(selectedItem.id, companyStore.activeCompany.id);
|
||||
toast.success('Registro eliminado');
|
||||
@@ -132,6 +139,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
useShortcuts(
|
||||
'Clients Providers List',
|
||||
obtenerAtajosListaSocios({
|
||||
filtrarTodos: () => handleTypeChange('both'),
|
||||
filtrarClientes: () => handleTypeChange('client'),
|
||||
filtrarProveedores: () => handleTypeChange('provider'),
|
||||
nuevo: () => goto('/dashboard/clients_and_providers/edit/new'),
|
||||
recargar: () => loadItems(1)
|
||||
})
|
||||
);
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col h-[calc(100vh-4rem)] p-4 gap-4 pb-15">
|
||||
@@ -145,7 +162,9 @@
|
||||
|
||||
<!-- Error Message -->
|
||||
{#if error}
|
||||
<Card.Root class="bg-card dark:bg-black text-card-foreground dark:text-white border-destructive dark:border-red-800">
|
||||
<Card.Root
|
||||
class="bg-card dark:bg-black text-card-foreground dark:text-white border-destructive dark:border-red-800"
|
||||
>
|
||||
<Card.Header>
|
||||
<Card.Title class="text-destructive">Error</Card.Title>
|
||||
<Card.Description>
|
||||
@@ -168,18 +187,18 @@
|
||||
<div class="grid grid-cols-4 gap-4">
|
||||
<div class="space-y-2">
|
||||
<Label class="text-xs">Nombre / Razón Social</Label>
|
||||
<Input
|
||||
bind:value={searchName}
|
||||
placeholder="Buscar por nombre..."
|
||||
<Input
|
||||
bind:value={searchName}
|
||||
placeholder="Buscar por nombre..."
|
||||
class="h-9"
|
||||
onkeydown={(e) => e.key === 'Enter' && handleSearch()}
|
||||
/>
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<Label class="text-xs">RFC</Label>
|
||||
<Input
|
||||
bind:value={searchRfc}
|
||||
placeholder="RFC..."
|
||||
<Input
|
||||
bind:value={searchRfc}
|
||||
placeholder="RFC..."
|
||||
class="h-9"
|
||||
onkeydown={(e) => e.key === 'Enter' && handleSearch()}
|
||||
/>
|
||||
@@ -188,7 +207,11 @@
|
||||
<Label class="text-xs">Tipo</Label>
|
||||
<Select.Root type="single" value={searchType} onValueChange={handleTypeChange}>
|
||||
<Select.Trigger class="h-9">
|
||||
{searchType === 'both' ? 'Todos' : searchType === 'client' ? 'Clientes' : 'Proveedores'}
|
||||
{searchType === 'both'
|
||||
? 'Todos'
|
||||
: searchType === 'client'
|
||||
? 'Clientes'
|
||||
: 'Proveedores'}
|
||||
</Select.Trigger>
|
||||
<Select.Content>
|
||||
<Select.Item value="both">Todos</Select.Item>
|
||||
@@ -234,13 +257,23 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
{#if isLoading}
|
||||
<tr><td colspan="5" class="text-center py-8 text-muted-foreground">Cargando...</td></tr>
|
||||
<tr
|
||||
><td colspan="5" class="text-center py-8 text-muted-foreground">Cargando...</td
|
||||
></tr
|
||||
>
|
||||
{:else if items.length === 0}
|
||||
<tr><td colspan="5" class="text-center py-8 text-muted-foreground">No se encontraron registros</td></tr>
|
||||
<tr
|
||||
><td colspan="5" class="text-center py-8 text-muted-foreground"
|
||||
>No se encontraron registros</td
|
||||
></tr
|
||||
>
|
||||
{:else}
|
||||
{#each items as item (item.id)}
|
||||
<tr
|
||||
class="border-b cursor-pointer transition-colors hover:bg-muted/50 {selectedItem?.id === item.id ? 'bg-muted' : ''}"
|
||||
<tr
|
||||
class="border-b cursor-pointer transition-colors hover:bg-muted/50 {selectedItem?.id ===
|
||||
item.id
|
||||
? 'bg-muted'
|
||||
: ''}"
|
||||
onclick={() => selectItem(item)}
|
||||
>
|
||||
<td class="px-3 py-2 font-mono text-xs text-muted-foreground">{item.id}</td>
|
||||
@@ -248,15 +281,28 @@
|
||||
<td class="px-3 py-2">{item.name}</td>
|
||||
<td class="px-3 py-2">
|
||||
{#if item.client_or_provider === 'client'}
|
||||
<span class="inline-flex items-center rounded-full bg-blue-100 px-2 py-0.5 text-xs font-medium text-blue-700">Cliente</span>
|
||||
<span
|
||||
class="inline-flex items-center rounded-full bg-blue-100 px-2 py-0.5 text-xs font-medium text-blue-700"
|
||||
>Cliente</span
|
||||
>
|
||||
{:else if item.client_or_provider === 'provider'}
|
||||
<span class="inline-flex items-center rounded-full bg-purple-100 px-2 py-0.5 text-xs font-medium text-purple-700">Proveedor</span>
|
||||
<span
|
||||
class="inline-flex items-center rounded-full bg-purple-100 px-2 py-0.5 text-xs font-medium text-purple-700"
|
||||
>Proveedor</span
|
||||
>
|
||||
{:else}
|
||||
<span class="inline-flex items-center rounded-full bg-gray-100 px-2 py-0.5 text-xs font-medium text-gray-700">Ambos</span>
|
||||
<span
|
||||
class="inline-flex items-center rounded-full bg-gray-100 px-2 py-0.5 text-xs font-medium text-gray-700"
|
||||
>Ambos</span
|
||||
>
|
||||
{/if}
|
||||
</td>
|
||||
<td class="px-3 py-2">
|
||||
<span class="inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium {item.is_active ? 'bg-green-100 text-green-700' : 'bg-red-100 text-red-700'}">
|
||||
<span
|
||||
class="inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium {item.is_active
|
||||
? 'bg-green-100 text-green-700'
|
||||
: 'bg-red-100 text-red-700'}"
|
||||
>
|
||||
{item.is_active ? 'Activo' : 'Inactivo'}
|
||||
</span>
|
||||
</td>
|
||||
@@ -266,113 +312,140 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!-- Simple Pagination Controls -->
|
||||
<div class="p-2 border-t flex justify-end gap-2">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
disabled={currentPage === 1 || isLoading}
|
||||
onclick={() => loadItems(currentPage - 1)}
|
||||
>
|
||||
Anterior
|
||||
</Button>
|
||||
<span class="flex items-center text-xs text-muted-foreground px-2">
|
||||
Página {currentPage} de {Math.ceil(totalItems / pageSize)}
|
||||
</span>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
disabled={items.length < pageSize || isLoading}
|
||||
onclick={() => loadItems(currentPage + 1)}
|
||||
>
|
||||
Siguiente
|
||||
</Button>
|
||||
</div>
|
||||
<!-- Simple Pagination Controls -->
|
||||
<div class="p-2 border-t flex justify-end gap-2">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
disabled={currentPage === 1 || isLoading}
|
||||
onclick={() => loadItems(currentPage - 1)}
|
||||
>
|
||||
Anterior
|
||||
</Button>
|
||||
<span class="flex items-center text-xs text-muted-foreground px-2">
|
||||
Página {currentPage} de {Math.ceil(totalItems / pageSize)}
|
||||
</span>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
disabled={items.length < pageSize || isLoading}
|
||||
onclick={() => loadItems(currentPage + 1)}
|
||||
>
|
||||
Siguiente
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Right Panel: Details -->
|
||||
<div class="w-96 flex-none flex flex-col border rounded-xl bg-muted/30 shadow-sm overflow-hidden">
|
||||
<div
|
||||
class="w-96 flex-none flex flex-col border rounded-xl bg-muted/30 shadow-sm overflow-hidden"
|
||||
>
|
||||
<div class="p-4 border-b bg-card">
|
||||
<p class="text-[10px] uppercase tracking-widest opacity-80 text-muted-foreground">Detalles del Registro</p>
|
||||
<h2 class="text-xl font-black font-mono tracking-tighter truncate" title={selectedItem?.name || ''}>
|
||||
<p class="text-[10px] uppercase tracking-widest opacity-80 text-muted-foreground">
|
||||
Detalles del Registro
|
||||
</p>
|
||||
<h2
|
||||
class="text-xl font-black font-mono tracking-tighter truncate"
|
||||
title={selectedItem?.name || ''}
|
||||
>
|
||||
{selectedItem?.name || '---'}
|
||||
</h2>
|
||||
<div class="flex items-center gap-2 mt-1">
|
||||
<span class="text-xs font-mono text-muted-foreground">{selectedItem?.rfc || ''}</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 mt-1">
|
||||
<span class="text-xs font-mono text-muted-foreground">{selectedItem?.rfc || ''}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex-1 overflow-auto p-5 space-y-6 bg-card">
|
||||
{#if selectedItem}
|
||||
<div class="grid grid-cols-1 gap-4">
|
||||
<div class="space-y-1">
|
||||
<Label class="text-[10px] uppercase text-muted-foreground font-bold flex items-center gap-1">
|
||||
<Users size={10} /> Tipo
|
||||
</Label>
|
||||
<p class="text-sm font-medium capitalize">{selectedItem.client_or_provider}</p>
|
||||
</div>
|
||||
|
||||
{#if selectedItem.address}
|
||||
<div class="pt-4 border-t space-y-3">
|
||||
<Label class="text-[10px] uppercase text-muted-foreground font-bold flex items-center gap-1">
|
||||
<MapPin size={10} /> Dirección
|
||||
</Label>
|
||||
<div class="text-sm space-y-1">
|
||||
<p>{selectedItem.address.streets || ''} {selectedItem.address.exterior_number || ''} {selectedItem.address.interior_number ? 'Int ' + selectedItem.address.interior_number : ''}</p>
|
||||
<p>{selectedItem.address.neighborhood || ''}</p>
|
||||
<p>{selectedItem.address.city || ''}, {selectedItem.address.state || ''}</p>
|
||||
<p>{selectedItem.address.postal_code || ''}, {selectedItem.address.country || ''}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pt-4 border-t space-y-3">
|
||||
<Label class="text-[10px] uppercase text-muted-foreground font-bold flex items-center gap-1">
|
||||
<Hash size={10} /> Contacto
|
||||
</Label>
|
||||
{#if selectedItem.address.email}
|
||||
<div class="flex items-center gap-2 text-sm">
|
||||
<Mail size={14} class="text-muted-foreground" />
|
||||
<span>{selectedItem.address.email}</span>
|
||||
</div>
|
||||
{/if}
|
||||
{#if selectedItem.address.phone}
|
||||
<div class="flex items-center gap-2 text-sm">
|
||||
<Phone size={14} class="text-muted-foreground" />
|
||||
<span>{selectedItem.address.phone}</span>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{:else}
|
||||
<div class="p-4 rounded-md bg-yellow-50 dark:bg-yellow-900/10 border border-yellow-200 dark:border-yellow-900">
|
||||
<p class="text-xs text-yellow-600 dark:text-yellow-400">Sin dirección registrada</p>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="space-y-1">
|
||||
<Label
|
||||
class="text-[10px] uppercase text-muted-foreground font-bold flex items-center gap-1"
|
||||
>
|
||||
<Users size={10} /> Tipo
|
||||
</Label>
|
||||
<p class="text-sm font-medium capitalize">{selectedItem.client_or_provider}</p>
|
||||
</div>
|
||||
|
||||
{#if selectedItem.programs}
|
||||
<div class="pt-4 border-t space-y-3">
|
||||
<Label class="text-[10px] uppercase text-muted-foreground font-bold flex items-center gap-1">
|
||||
<Building2 size={10} /> Programas
|
||||
</Label>
|
||||
<div class="grid grid-cols-2 gap-2 text-sm">
|
||||
<div>
|
||||
<span class="text-xs text-muted-foreground block">Programa</span>
|
||||
<span class="font-medium">{selectedItem.programs.program || '-'}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-xs text-muted-foreground block">Número</span>
|
||||
<span class="font-medium">{selectedItem.programs.program_number || '-'}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-xs text-muted-foreground block">TAX ID</span>
|
||||
<span class="font-medium">{selectedItem.programs.tax_id || '-'}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{#if selectedItem.address}
|
||||
<div class="pt-4 border-t space-y-3">
|
||||
<Label
|
||||
class="text-[10px] uppercase text-muted-foreground font-bold flex items-center gap-1"
|
||||
>
|
||||
<MapPin size={10} /> Dirección
|
||||
</Label>
|
||||
<div class="text-sm space-y-1">
|
||||
<p>
|
||||
{selectedItem.address.streets || ''}
|
||||
{selectedItem.address.exterior_number || ''}
|
||||
{selectedItem.address.interior_number
|
||||
? 'Int ' + selectedItem.address.interior_number
|
||||
: ''}
|
||||
</p>
|
||||
<p>{selectedItem.address.neighborhood || ''}</p>
|
||||
<p>{selectedItem.address.city || ''}, {selectedItem.address.state || ''}</p>
|
||||
<p>
|
||||
{selectedItem.address.postal_code || ''}, {selectedItem.address.country || ''}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pt-4 border-t space-y-3">
|
||||
<Label
|
||||
class="text-[10px] uppercase text-muted-foreground font-bold flex items-center gap-1"
|
||||
>
|
||||
<Hash size={10} /> Contacto
|
||||
</Label>
|
||||
{#if selectedItem.address.email}
|
||||
<div class="flex items-center gap-2 text-sm">
|
||||
<Mail size={14} class="text-muted-foreground" />
|
||||
<span>{selectedItem.address.email}</span>
|
||||
</div>
|
||||
{/if}
|
||||
{#if selectedItem.address.phone}
|
||||
<div class="flex items-center gap-2 text-sm">
|
||||
<Phone size={14} class="text-muted-foreground" />
|
||||
<span>{selectedItem.address.phone}</span>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{:else}
|
||||
<div
|
||||
class="p-4 rounded-md bg-yellow-50 dark:bg-yellow-900/10 border border-yellow-200 dark:border-yellow-900"
|
||||
>
|
||||
<p class="text-xs text-yellow-600 dark:text-yellow-400">Sin dirección registrada</p>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if selectedItem.programs}
|
||||
<div class="pt-4 border-t space-y-3">
|
||||
<Label
|
||||
class="text-[10px] uppercase text-muted-foreground font-bold flex items-center gap-1"
|
||||
>
|
||||
<Building2 size={10} /> Programas
|
||||
</Label>
|
||||
<div class="grid grid-cols-2 gap-2 text-sm">
|
||||
<div>
|
||||
<span class="text-xs text-muted-foreground block">Programa</span>
|
||||
<span class="font-medium">{selectedItem.programs.program || '-'}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-xs text-muted-foreground block">Número</span>
|
||||
<span class="font-medium">{selectedItem.programs.program_number || '-'}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-xs text-muted-foreground block">TAX ID</span>
|
||||
<span class="font-medium">{selectedItem.programs.tax_id || '-'}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{:else}
|
||||
<div class="flex flex-col items-center justify-center h-full text-center text-muted-foreground opacity-50">
|
||||
<div
|
||||
class="flex flex-col items-center justify-center h-full text-center text-muted-foreground opacity-50"
|
||||
>
|
||||
<Building2 class="h-12 w-12 mb-3" />
|
||||
<p class="text-sm">Selecciona un registro</p>
|
||||
</div>
|
||||
@@ -383,7 +456,9 @@
|
||||
</div>
|
||||
|
||||
<!-- Sticky Footer Actions -->
|
||||
<div class="fixed bottom-0 left-0 right-0 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/80 border-t shadow-lg z-[5] group-has-data-[state=collapsed]/sidebar-wrapper:ml-[calc(var(--sidebar-width-icon))] ml-[calc(var(--sidebar-width))]">
|
||||
<div
|
||||
class="fixed bottom-0 left-0 right-0 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/80 border-t shadow-lg z-[5] group-has-data-[state=collapsed]/sidebar-wrapper:ml-[calc(var(--sidebar-width-icon))] ml-[calc(var(--sidebar-width))]"
|
||||
>
|
||||
<div class="px-4 py-4 max-w-[1400px] mx-auto">
|
||||
<div class="flex justify-end gap-2">
|
||||
<Button size="sm" href="/dashboard/clients_and_providers/edit">
|
||||
@@ -393,7 +468,13 @@
|
||||
<Button variant="outline" size="sm" onclick={handleEdit} disabled={!selectedItem}>
|
||||
Editar
|
||||
</Button>
|
||||
<Button variant="outline" size="sm" onclick={handleDelete} disabled={!selectedItem} class="text-destructive hover:text-destructive">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onclick={handleDelete}
|
||||
disabled={!selectedItem}
|
||||
class="text-destructive hover:text-destructive"
|
||||
>
|
||||
Borrar
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user