Compare commits
No commits in common. "51adb8d2b01e6f0dfb917f882231e1cc6adb9eab" and "366f90d403456d5e17d949bb359f5df0c03db96b" have entirely different histories.
51adb8d2b0
...
366f90d403
@ -40,7 +40,7 @@ export function PageHeader({
|
|||||||
<h2 className="h-8 text-xl font-semibold text-foreground sm:truncate sm:tracking-tight">
|
<h2 className="h-8 text-xl font-semibold text-foreground sm:truncate sm:tracking-tight">
|
||||||
{title}
|
{title}
|
||||||
</h2>
|
</h2>
|
||||||
{description && <div className="text-sm text-muted-foreground">{description}</div>}
|
{description && <div className="text-sm text-primary">{description}</div>}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -21,21 +21,13 @@
|
|||||||
"description": "Manage your customers",
|
"description": "Manage your customers",
|
||||||
"list": {
|
"list": {
|
||||||
"title": "Customer list",
|
"title": "Customer list",
|
||||||
"description": "Manage your customers and their contact information",
|
"description": "List all customers",
|
||||||
"grid_columns": {
|
"grid_columns": {
|
||||||
"customer": "Customer",
|
"customer": "Customer",
|
||||||
"status": "Status",
|
"status": "Status",
|
||||||
"contact": "Contact",
|
"contact": "Contact",
|
||||||
"address": "Address",
|
"address": "Address",
|
||||||
"actions": "Actions"
|
"actions": "Actions"
|
||||||
},
|
|
||||||
"actions": {
|
|
||||||
"more": "More",
|
|
||||||
"view": "View",
|
|
||||||
"edit": "Edit customer",
|
|
||||||
"delete": "Delete customer",
|
|
||||||
"visit_website": "Visit website",
|
|
||||||
"copy_email": "Copy email"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"create": {
|
"create": {
|
||||||
@ -200,9 +192,6 @@
|
|||||||
"no_entities_found": "No results found for \"{{search}}\"",
|
"no_entities_found": "No results found for \"{{search}}\"",
|
||||||
"select_or_create": "Select an item from the list or create a new one.",
|
"select_or_create": "Select an item from the list or create a new one.",
|
||||||
"create_label": "Create new item"
|
"create_label": "Create new item"
|
||||||
},
|
|
||||||
"address_cell": {
|
|
||||||
"open_in_google_maps": "Open address in Google Maps"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -21,21 +21,13 @@
|
|||||||
"description": "Gestiona tus clientes",
|
"description": "Gestiona tus clientes",
|
||||||
"list": {
|
"list": {
|
||||||
"title": "Lista de clientes",
|
"title": "Lista de clientes",
|
||||||
"description": "Gestiona la información de tus clientes y sus datos de contacto",
|
"description": "Lista todos los clientes",
|
||||||
"grid_columns": {
|
"grid_columns": {
|
||||||
"customer": "Cliente",
|
"customer": "Cliente",
|
||||||
"status": "Estado",
|
"status": "Estado",
|
||||||
"contact": "Contacto",
|
"contact": "Contacto",
|
||||||
"address": "Dirección",
|
"address": "Dirección",
|
||||||
"actions": "Acciones"
|
"actions": "Acciones"
|
||||||
},
|
|
||||||
"actions": {
|
|
||||||
"more": "Más",
|
|
||||||
"view": "Ver",
|
|
||||||
"edit": "Editar cliente",
|
|
||||||
"delete": "Eliminar cliente",
|
|
||||||
"visit_website": "Visitar sitio web",
|
|
||||||
"copy_email": "Copiar email"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"create": {
|
"create": {
|
||||||
@ -61,8 +53,8 @@
|
|||||||
"customer_type": {
|
"customer_type": {
|
||||||
"label": "Este cliente es...",
|
"label": "Este cliente es...",
|
||||||
"description": "Seleccione el tipo de cliente",
|
"description": "Seleccione el tipo de cliente",
|
||||||
"company": "Empresa",
|
"company": "una empresa",
|
||||||
"individual": "Particular"
|
"individual": "una persona"
|
||||||
},
|
},
|
||||||
"name": {
|
"name": {
|
||||||
"label": "Nombre",
|
"label": "Nombre",
|
||||||
@ -202,9 +194,6 @@
|
|||||||
"no_entities_found": "No se encontraron resultados para \"{{search}}\"",
|
"no_entities_found": "No se encontraron resultados para \"{{search}}\"",
|
||||||
"select_or_create": "Seleccione un elemento de la lista o cree uno nuevo.",
|
"select_or_create": "Seleccione un elemento de la lista o cree uno nuevo.",
|
||||||
"create_label": "Crear nuevo elemento"
|
"create_label": "Crear nuevo elemento"
|
||||||
},
|
|
||||||
"address_cell": {
|
|
||||||
"open_in_google_maps": "Abrir dirección en Google Maps"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -40,7 +40,7 @@ export function useCustomersGridColumns(
|
|||||||
<DataTableColumnHeader
|
<DataTableColumnHeader
|
||||||
className="text-left"
|
className="text-left"
|
||||||
column={column}
|
column={column}
|
||||||
title={t("pages.list.grid_columns.customer")}
|
title={t("pages.customers.list.gridColumns.customer")}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
accessorFn: (row) => row.name,
|
accessorFn: (row) => row.name,
|
||||||
@ -51,11 +51,6 @@ export function useCustomersGridColumns(
|
|||||||
const customer = row.original;
|
const customer = row.original;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button
|
|
||||||
className="flex items-start gap-3 text-left transition-colors hover:opacity-80 cursor-pointer"
|
|
||||||
onClick={onViewClick ? () => onViewClick(customer) : undefined}
|
|
||||||
type="button"
|
|
||||||
>
|
|
||||||
<div className="flex items-start gap-3">
|
<div className="flex items-start gap-3">
|
||||||
<Avatar className="size-10 border-2 border-background shadow-sm">
|
<Avatar className="size-10 border-2 border-background shadow-sm">
|
||||||
<AvatarFallback
|
<AvatarFallback
|
||||||
@ -71,9 +66,7 @@ export function useCustomersGridColumns(
|
|||||||
|
|
||||||
<div className="flex flex-col gap-1">
|
<div className="flex flex-col gap-1">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<span className="font-medium text-foreground hover:underline">
|
<span className="font-medium text-foreground">{customer.name}</span>
|
||||||
{customer.name}
|
|
||||||
</span>
|
|
||||||
{customer.trade_name && (
|
{customer.trade_name && (
|
||||||
<span className="text-muted-foreground">({customer.trade_name})</span>
|
<span className="text-muted-foreground">({customer.trade_name})</span>
|
||||||
)}
|
)}
|
||||||
@ -85,19 +78,18 @@ export function useCustomersGridColumns(
|
|||||||
{customer.is_company ? (
|
{customer.is_company ? (
|
||||||
<>
|
<>
|
||||||
<Building2Icon className="size-3" />
|
<Building2Icon className="size-3" />
|
||||||
{t("form_fields.customer_type.company")}
|
{t("pages.customers.list.customerKind.company")}
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<UserIcon className="size-3" />
|
<UserIcon className="size-3" />
|
||||||
{t("form_fields.customer_type.individual")}
|
{t("pages.customers.list.customerKind.individual")}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</Badge>
|
</Badge>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -107,12 +99,11 @@ export function useCustomersGridColumns(
|
|||||||
<DataTableColumnHeader
|
<DataTableColumnHeader
|
||||||
className="text-left"
|
className="text-left"
|
||||||
column={column}
|
column={column}
|
||||||
title={t("pages.list.grid_columns.contact")}
|
title={t("pages.customers.list.gridColumns.contact")}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
accessorFn: (row) =>
|
accessorFn: (row) =>
|
||||||
`${row.email_primary} ${row.phone_primary} ${row.mobile_primary} ${row.website}`,
|
`${row.email_primary} ${row.phone_primary} ${row.mobile_primary} ${row.website}`,
|
||||||
enableSorting: false,
|
|
||||||
size: 140,
|
size: 140,
|
||||||
minSize: 120,
|
minSize: 120,
|
||||||
cell: ({ row }) => <ContactCell customer={row.original} />,
|
cell: ({ row }) => <ContactCell customer={row.original} />,
|
||||||
@ -123,12 +114,11 @@ export function useCustomersGridColumns(
|
|||||||
<DataTableColumnHeader
|
<DataTableColumnHeader
|
||||||
className="text-left"
|
className="text-left"
|
||||||
column={column}
|
column={column}
|
||||||
title={t("pages.list.grid_columns.address")}
|
title={t("pages.customers.list.gridColumns.address")}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
accessorFn: (row) =>
|
accessorFn: (row) =>
|
||||||
`${row.street} ${row.street2} ${row.city} ${row.postal_code} ${row.province} ${row.country}`,
|
`${row.street} ${row.street2} ${row.city} ${row.postal_code} ${row.province} ${row.country}`,
|
||||||
enableSorting: false,
|
|
||||||
size: 140,
|
size: 140,
|
||||||
minSize: 120,
|
minSize: 120,
|
||||||
cell: ({ row }) => <AddressCell customer={row.original} />,
|
cell: ({ row }) => <AddressCell customer={row.original} />,
|
||||||
@ -139,7 +129,7 @@ export function useCustomersGridColumns(
|
|||||||
<DataTableColumnHeader
|
<DataTableColumnHeader
|
||||||
className="text-right"
|
className="text-right"
|
||||||
column={column}
|
column={column}
|
||||||
title={t("pages.list.grid_columns.actions")}
|
title={t("pages.customers.list.gridColumns.actions")}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
size: 64,
|
size: 64,
|
||||||
@ -154,7 +144,7 @@ export function useCustomersGridColumns(
|
|||||||
<div className="flex justify-end">
|
<div className="flex justify-end">
|
||||||
<div className="flex items-center gap-1">
|
<div className="flex items-center gap-1">
|
||||||
<Button
|
<Button
|
||||||
aria-label={t("pages.list.actions.view")}
|
aria-label={t("pages.customers.list.actions.view")}
|
||||||
onClick={() => onViewClick?.(customer)}
|
onClick={() => onViewClick?.(customer)}
|
||||||
size="icon"
|
size="icon"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
@ -164,22 +154,26 @@ export function useCustomersGridColumns(
|
|||||||
|
|
||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
<DropdownMenuTrigger asChild>
|
<DropdownMenuTrigger asChild>
|
||||||
<Button aria-label={t("pages.list.actions.more")} size="icon" variant="ghost">
|
<Button
|
||||||
|
aria-label={t("pages.customers.list.actions.more")}
|
||||||
|
size="icon"
|
||||||
|
variant="ghost"
|
||||||
|
>
|
||||||
<MoreHorizontalIcon className="size-4" />
|
<MoreHorizontalIcon className="size-4" />
|
||||||
</Button>
|
</Button>
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
|
|
||||||
<DropdownMenuContent align="end">
|
<DropdownMenuContent align="end">
|
||||||
<DropdownMenuLabel>{t("pages.list.grid_columns.actions")}</DropdownMenuLabel>
|
<DropdownMenuLabel>{t("pages.customers.list.actions.label")}</DropdownMenuLabel>
|
||||||
|
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
|
|
||||||
<DropdownMenuItem onClick={() => onViewClick?.(customer)}>
|
<DropdownMenuItem onClick={() => onViewClick?.(customer)}>
|
||||||
{t("pages.list.actions.view")}
|
{t("pages.customers.list.actions.open")}
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
|
|
||||||
<DropdownMenuItem onClick={() => onEditClick?.(customer)}>
|
<DropdownMenuItem onClick={() => onEditClick?.(customer)}>
|
||||||
{t("pages.list.actions.edit")}
|
{t("pages.customers.list.actions.edit")}
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
|
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
@ -190,14 +184,14 @@ export function useCustomersGridColumns(
|
|||||||
window.open(safeHTTPUrl(website), "_blank", "noopener,noreferrer")
|
window.open(safeHTTPUrl(website), "_blank", "noopener,noreferrer")
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{t("pages.list.actions.visit_website")}
|
{t("pages.customers.list.actions.visitWebsite")}
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
|
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
disabled={!email_primary}
|
disabled={!email_primary}
|
||||||
onClick={() => navigator.clipboard.writeText(email_primary)}
|
onClick={() => navigator.clipboard.writeText(email_primary)}
|
||||||
>
|
>
|
||||||
{t("pages.list.actions.copy_email")}
|
{t("pages.customers.list.actions.copyEmail")}
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
|
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
@ -206,7 +200,7 @@ export function useCustomersGridColumns(
|
|||||||
className="text-destructive"
|
className="text-destructive"
|
||||||
onClick={() => onDeleteClick?.(customer)}
|
onClick={() => onDeleteClick?.(customer)}
|
||||||
>
|
>
|
||||||
{t("pages.list.actions.delete")}
|
{t("pages.customers.list.actions.delete")}
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
</DropdownMenuContent>
|
</DropdownMenuContent>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
|
|||||||
@ -1,28 +1,12 @@
|
|||||||
|
import type { CustomerListRow } from "@erp/customers/web/shared";
|
||||||
import { MapPinIcon } from "lucide-react";
|
import { MapPinIcon } from "lucide-react";
|
||||||
|
|
||||||
import { useTranslation } from "../../../i18n";
|
|
||||||
import type { CustomerListRow } from "../../../shared";
|
|
||||||
|
|
||||||
const getGoogleMapsUrl = (customer: CustomerListRow) => {
|
|
||||||
const fullAddress = `${customer.street}, ${customer.postal_code} ${customer.city}, ${customer.province}, ${customer.country}`;
|
|
||||||
return `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(fullAddress)}`;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const AddressCell = ({ customer }: { customer: CustomerListRow }) => {
|
export const AddressCell = ({ customer }: { customer: CustomerListRow }) => {
|
||||||
const { t } = useTranslation();
|
|
||||||
const line1 = [customer.street, customer.street2].filter(Boolean).join(", ");
|
const line1 = [customer.street, customer.street2].filter(Boolean).join(", ");
|
||||||
const line2 = [customer.postal_code, customer.city].filter(Boolean).join(" ");
|
const line2 = [customer.postal_code, customer.city].filter(Boolean).join(" ");
|
||||||
const line3 = [customer.province, customer.country].filter(Boolean).join(", ");
|
const line3 = [customer.province, customer.country].filter(Boolean).join(", ");
|
||||||
return (
|
return (
|
||||||
<address className="not-italic flex items-start gap-2 text-muted-foreground hover:text-primary transition-colors">
|
<address className="not-italic flex items-start gap-2 text-muted-foreground">
|
||||||
<a
|
|
||||||
aria-label={t("components.address_cell.open_in_google_maps")}
|
|
||||||
className="group/address flex items-start gap-2 rounded-md p-1 -m-1 transition-colors hover:bg-muted"
|
|
||||||
href={getGoogleMapsUrl(customer)}
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
target="_blank"
|
|
||||||
title={t("components.address_cell.open_in_google_maps")}
|
|
||||||
>
|
|
||||||
<MapPinIcon className="mt-0.5 size-3.5" />
|
<MapPinIcon className="mt-0.5 size-3.5" />
|
||||||
<div className="text-sm">
|
<div className="text-sm">
|
||||||
<p>{line1}</p>
|
<p>{line1}</p>
|
||||||
@ -30,7 +14,6 @@ export const AddressCell = ({ customer }: { customer: CustomerListRow }) => {
|
|||||||
{line2} · {line3}
|
{line2} · {line3}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
|
||||||
</address>
|
</address>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import { MailIcon, PhoneIcon } from "lucide-react";
|
|||||||
|
|
||||||
export const ContactCell = ({ customer }: { customer: CustomerListRow }) => (
|
export const ContactCell = ({ customer }: { customer: CustomerListRow }) => (
|
||||||
<div className="flex flex-col gap-1.5 text-sm text-muted-foreground transition-colors ">
|
<div className="flex flex-col gap-1.5 text-sm text-muted-foreground transition-colors ">
|
||||||
{customer.email_primary && (
|
|
||||||
<a
|
<a
|
||||||
className="flex items-center gap-2 hover:text-foreground"
|
className="flex items-center gap-2 hover:text-foreground"
|
||||||
href={`mailto:${customer.email_primary}`}
|
href={`mailto:${customer.email_primary}`}
|
||||||
@ -11,8 +10,6 @@ export const ContactCell = ({ customer }: { customer: CustomerListRow }) => (
|
|||||||
<MailIcon className="size-3.5" />
|
<MailIcon className="size-3.5" />
|
||||||
{customer.email_primary}
|
{customer.email_primary}
|
||||||
</a>
|
</a>
|
||||||
)}
|
|
||||||
|
|
||||||
{customer.email_secondary && (
|
{customer.email_secondary && (
|
||||||
<a
|
<a
|
||||||
className="flex items-center gap-2 hover:text-foreground"
|
className="flex items-center gap-2 hover:text-foreground"
|
||||||
@ -22,7 +19,7 @@ export const ContactCell = ({ customer }: { customer: CustomerListRow }) => (
|
|||||||
{customer.email_secondary}
|
{customer.email_secondary}
|
||||||
</a>
|
</a>
|
||||||
)}
|
)}
|
||||||
{customer.phone_primary && (
|
{customer.phone_primary ? (
|
||||||
<a
|
<a
|
||||||
className="flex items-center gap-2 hover:text-foreground"
|
className="flex items-center gap-2 hover:text-foreground"
|
||||||
href={`tel:${customer.phone_primary}`}
|
href={`tel:${customer.phone_primary}`}
|
||||||
@ -30,6 +27,10 @@ export const ContactCell = ({ customer }: { customer: CustomerListRow }) => (
|
|||||||
<PhoneIcon className="size-3.5" />
|
<PhoneIcon className="size-3.5" />
|
||||||
{customer.phone_primary}
|
{customer.phone_primary}
|
||||||
</a>
|
</a>
|
||||||
|
) : (
|
||||||
|
<span className="flex items-center gap-2 text-muted-foreground/50">
|
||||||
|
<PhoneIcon className="size-3.5" />-
|
||||||
|
</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -25,8 +25,8 @@ export const ListCustomersPage = () => {
|
|||||||
return (
|
return (
|
||||||
<AppContent>
|
<AppContent>
|
||||||
<ErrorAlert
|
<ErrorAlert
|
||||||
message={(listCtrl.error as Error)?.message || t("pages.list.loadErrorMessage")}
|
message={(listCtrl.error as Error)?.message || t("pages.customers.list.loadErrorMessage")}
|
||||||
title={t("pages.list.loadErrorTitle")}
|
title={t("pages.customers.list.loadErrorTitle")}
|
||||||
/>
|
/>
|
||||||
<BackHistoryButton />
|
<BackHistoryButton />
|
||||||
</AppContent>
|
</AppContent>
|
||||||
@ -37,17 +37,17 @@ export const ListCustomersPage = () => {
|
|||||||
<>
|
<>
|
||||||
<AppHeader>
|
<AppHeader>
|
||||||
<PageHeader
|
<PageHeader
|
||||||
description={t("pages.list.description")}
|
description={t("pages.customers.list.description")}
|
||||||
rightSlot={
|
rightSlot={
|
||||||
<Button
|
<Button
|
||||||
aria-label={t("pages.create.title")}
|
aria-label={t("pages.customers.create.title")}
|
||||||
onClick={() => navigate("/customers/create")}
|
onClick={() => navigate("/customers/create")}
|
||||||
>
|
>
|
||||||
<PlusIcon aria-hidden className="mr-2 size-4" />
|
<PlusIcon aria-hidden className="mr-2 size-4" />
|
||||||
{t("pages.create.title")}
|
{t("pages.customers.create.title")}
|
||||||
</Button>
|
</Button>
|
||||||
}
|
}
|
||||||
title={t("pages.list.title")}
|
title={t("pages.customers.list.title")}
|
||||||
/>
|
/>
|
||||||
</AppHeader>
|
</AppHeader>
|
||||||
<AppContent>
|
<AppContent>
|
||||||
|
|||||||
@ -25,7 +25,7 @@ export function DataTableColumnHeader<TData, TValue>({
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
if (!column.getCanSort()) {
|
if (!column.getCanSort()) {
|
||||||
return <div className={cn("text-foreground text-[0.8rem]", className)}>{title}</div>;
|
return <div className={cn("text-foreground", className)}>{title}</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -94,7 +94,7 @@ export function DataTablePagination<TData>({
|
|||||||
<SelectValue placeholder={String(pageSize)} />
|
<SelectValue placeholder={String(pageSize)} />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
{[5, 10, 20, 25, 30, 40, 50].map((size) => (
|
{[10, 20, 25, 30, 40, 50].map((size) => (
|
||||||
<SelectItem key={size} value={String(size)}>
|
<SelectItem key={size} value={String(size)}>
|
||||||
{size}
|
{size}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import {
|
|||||||
DropdownMenuTrigger,
|
DropdownMenuTrigger,
|
||||||
} from "@repo/shadcn-ui/components";
|
} from "@repo/shadcn-ui/components";
|
||||||
import type { Column, Table } from "@tanstack/react-table";
|
import type { Column, Table } from "@tanstack/react-table";
|
||||||
import { Settings2Icon } from "lucide-react";
|
import { SettingsIcon } from "lucide-react";
|
||||||
|
|
||||||
import { useTranslation } from "../../locales/i18n.ts";
|
import { useTranslation } from "../../locales/i18n.ts";
|
||||||
|
|
||||||
@ -19,13 +19,8 @@ export function DataTableViewOptions<TData>({ table }: { table: Table<TData> })
|
|||||||
return (
|
return (
|
||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
<DropdownMenuTrigger asChild>
|
<DropdownMenuTrigger asChild>
|
||||||
<Button
|
<Button className="ml-auto hidden h-8 lg:flex" size={"sm"} type="button" variant="ghost">
|
||||||
className="ml-auto hidden h-8 lg:flex gap-2 items"
|
<SettingsIcon />
|
||||||
size="sm"
|
|
||||||
type="button"
|
|
||||||
variant="outline"
|
|
||||||
>
|
|
||||||
<Settings2Icon />
|
|
||||||
{t("components.datatable_view_options.columns_button")}
|
{t("components.datatable_view_options.columns_button")}
|
||||||
</Button>
|
</Button>
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
|
|||||||
@ -8,10 +8,7 @@ export const AppContent = ({
|
|||||||
}: PropsWithChildren<{ className?: string }>) => {
|
}: PropsWithChildren<{ className?: string }>) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn("app-content flex flex-1 flex-col gap-4 p-4 pt-6 min-h-screen", className)}
|
||||||
"app-content flex flex-1 flex-col gap-4 p-4 pt-6 min-h-screen bg-muted/20",
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
|||||||
@ -15,7 +15,7 @@ export const AppLayout = () => {
|
|||||||
>
|
>
|
||||||
<AppSidebar variant="inset" />
|
<AppSidebar variant="inset" />
|
||||||
{/* Aquí está el MAIN */}
|
{/* Aquí está el MAIN */}
|
||||||
<SidebarInset className="app-main">
|
<SidebarInset className="app-main bg-muted">
|
||||||
<Outlet />
|
<Outlet />
|
||||||
</SidebarInset>
|
</SidebarInset>
|
||||||
</SidebarProvider>
|
</SidebarProvider>
|
||||||
|
|||||||
@ -40,8 +40,7 @@
|
|||||||
"typescript": "^5.6.0"
|
"typescript": "^5.6.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fontsource-variable/geist": "^5.2.8",
|
"@fontsource-variable/inter": "^5.2.8",
|
||||||
"@fontsource-variable/geist-mono": "^5.2.7",
|
|
||||||
"@hookform/resolvers": "^5.2.2",
|
"@hookform/resolvers": "^5.2.2",
|
||||||
"add": "^2.0.6",
|
"add": "^2.0.6",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
@import "tailwindcss";
|
@import "tailwindcss";
|
||||||
@import "tw-animate-css";
|
@import "tw-animate-css";
|
||||||
|
@import "@fontsource-variable/inter";
|
||||||
@import "@fontsource-variable/geist";
|
|
||||||
@import "@fontsource-variable/geist-mono";
|
|
||||||
|
|
||||||
@custom-variant dark (&:is(.dark *));
|
@custom-variant dark (&:is(.dark *));
|
||||||
|
|
||||||
@ -100,8 +98,7 @@
|
|||||||
|
|
||||||
@layer utilities {
|
@layer utilities {
|
||||||
body {
|
body {
|
||||||
font-family: var(--font-sans);
|
font-family: "Inter", ui-sans-serif, sans-serif, system-ui;
|
||||||
font-variant-ligatures: none;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,8 +111,7 @@
|
|||||||
**/
|
**/
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--font-sans: "Geist Variable", ui-sans-serif, sans-serif, system-ui;
|
--font-sans: "Inter", ui-sans-serif, sans-serif, system-ui;
|
||||||
--font-mono: "Geist Mono Variable", ui-monospace, monospace;
|
|
||||||
|
|
||||||
--background: oklch(1 0 0);
|
--background: oklch(1 0 0);
|
||||||
--foreground: oklch(0.145 0 0);
|
--foreground: oklch(0.145 0 0);
|
||||||
@ -149,7 +145,7 @@
|
|||||||
--sidebar-border: oklch(0.6427 0.1407 253.94);
|
--sidebar-border: oklch(0.6427 0.1407 253.94);
|
||||||
--sidebar-ring: oklch(1 0 0);
|
--sidebar-ring: oklch(1 0 0);
|
||||||
|
|
||||||
--radius: 0.25rem;
|
--radius: 0.625rem;
|
||||||
--shadow-x: 0;
|
--shadow-x: 0;
|
||||||
--shadow-y: 1px;
|
--shadow-y: 1px;
|
||||||
--shadow-blur: 3px;
|
--shadow-blur: 3px;
|
||||||
|
|||||||
@ -995,12 +995,9 @@ importers:
|
|||||||
|
|
||||||
packages/shadcn-ui:
|
packages/shadcn-ui:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@fontsource-variable/geist':
|
'@fontsource-variable/inter':
|
||||||
specifier: ^5.2.8
|
specifier: ^5.2.8
|
||||||
version: 5.2.8
|
version: 5.2.8
|
||||||
'@fontsource-variable/geist-mono':
|
|
||||||
specifier: ^5.2.7
|
|
||||||
version: 5.2.7
|
|
||||||
'@hookform/resolvers':
|
'@hookform/resolvers':
|
||||||
specifier: ^5.2.2
|
specifier: ^5.2.2
|
||||||
version: 5.2.2(react-hook-form@7.66.0(react@19.2.0))
|
version: 5.2.2(react-hook-form@7.66.0(react@19.2.0))
|
||||||
@ -1683,11 +1680,8 @@ packages:
|
|||||||
'@floating-ui/utils@0.2.10':
|
'@floating-ui/utils@0.2.10':
|
||||||
resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==}
|
resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==}
|
||||||
|
|
||||||
'@fontsource-variable/geist-mono@5.2.7':
|
'@fontsource-variable/inter@5.2.8':
|
||||||
resolution: {integrity: sha512-ZKlZ5sjtalb2TwXKs400mAGDlt/+2ENLNySPx0wTz3bP3mWARCsUW+rpxzZc7e05d2qGch70pItt3K4qttbIYA==}
|
resolution: {integrity: sha512-kOfP2D+ykbcX/P3IFnokOhVRNoTozo5/JxhAIVYLpea/UBmCQ/YWPBfWIDuBImXX/15KH+eKh4xpEUyS2sQQGQ==}
|
||||||
|
|
||||||
'@fontsource-variable/geist@5.2.8':
|
|
||||||
resolution: {integrity: sha512-cJ6m9e+8MQ5dCYJsLylfZrgBh6KkG4bOLckB35Tr9J/EqdkEM6QllH5PxqP1dhTvFup+HtMRPuz9xOjxXJggxw==}
|
|
||||||
|
|
||||||
'@hapi/hoek@9.3.0':
|
'@hapi/hoek@9.3.0':
|
||||||
resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==}
|
resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==}
|
||||||
@ -7724,9 +7718,7 @@ snapshots:
|
|||||||
|
|
||||||
'@floating-ui/utils@0.2.10': {}
|
'@floating-ui/utils@0.2.10': {}
|
||||||
|
|
||||||
'@fontsource-variable/geist-mono@5.2.7': {}
|
'@fontsource-variable/inter@5.2.8': {}
|
||||||
|
|
||||||
'@fontsource-variable/geist@5.2.8': {}
|
|
||||||
|
|
||||||
'@hapi/hoek@9.3.0': {}
|
'@hapi/hoek@9.3.0': {}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user