Clientes y Facturas de cliente
This commit is contained in:
parent
e337331650
commit
c69a7cd142
@ -6,43 +6,39 @@ import type { ReactNode } from "react";
|
|||||||
|
|
||||||
|
|
||||||
interface PageHeaderProps {
|
interface PageHeaderProps {
|
||||||
/** Icono que aparece a la izquierda del título */
|
backIcon?: ReactNode;
|
||||||
icon?: ReactNode;
|
|
||||||
/** Contenido del título (texto plano o nodo complejo) */
|
|
||||||
title: ReactNode;
|
title: ReactNode;
|
||||||
/** Descripción secundaria debajo del título */
|
|
||||||
description?: ReactNode;
|
description?: ReactNode;
|
||||||
/** Estado opcional (ej. "draft", "paid") */
|
|
||||||
status?: string;
|
status?: string;
|
||||||
/** Contenido del lado derecho (botones, menús, etc.) */
|
|
||||||
rightSlot?: ReactNode;
|
rightSlot?: ReactNode;
|
||||||
|
|
||||||
className?: string;
|
className?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function PageHeader({ icon, title, description, status, rightSlot, className }: PageHeaderProps) {
|
export function PageHeader({ backIcon, title, description, rightSlot, className }: PageHeaderProps) {
|
||||||
return (
|
return (
|
||||||
<div className={cn("py-4", className)}>
|
<div className={cn("pt-4 pb-6 bg-background flex items-center justify-between", className)}>
|
||||||
<div className='flex items-center justify-between'>
|
{/* Lado izquierdo */}
|
||||||
{/* Lado izquierdo */}
|
<div className='flex items-center gap-4'>
|
||||||
<div className='flex items-center gap-4'>
|
{backIcon && (
|
||||||
<Button variant="ghost" size="icon" className="cursor-pointer" onClick={() => window.history.back()}>
|
<Button
|
||||||
<ChevronLeftIcon className="size-5" />
|
variant='ghost'
|
||||||
|
size='icon'
|
||||||
|
className='cursor-pointer'
|
||||||
|
onClick={() => window.history.back()}
|
||||||
|
>
|
||||||
|
<ChevronLeftIcon className='size-5' />
|
||||||
</Button>
|
</Button>
|
||||||
{icon && <div className='shrink-0'>{icon}</div>}
|
)}
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div className='flex items-center gap-3'>
|
<h2 className='text-2xl font-semibold text-foreground'>{title}</h2>
|
||||||
<h1 className='text-xl font-semibold text-foreground'>{title}</h1>
|
{description && <p className='text-base text-muted-foreground'>{description}</p>}
|
||||||
</div>
|
|
||||||
{description && <p className='text-sm text-muted-foreground'>{description}</p>}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Lado derecho parametrizable */}
|
|
||||||
{rightSlot && <div>{rightSlot}</div>}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Lado derecho parametrizable */}
|
||||||
|
{rightSlot && <>{rightSlot}</>}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,7 +34,7 @@
|
|||||||
"title": "Customer invoices",
|
"title": "Customer invoices",
|
||||||
"description": "Manage your customer invoices",
|
"description": "Manage your customer invoices",
|
||||||
"list": {
|
"list": {
|
||||||
"title": "Customer invoice list",
|
"title": "Customer invoices",
|
||||||
"description": "List all customer invoices",
|
"description": "List all customer invoices",
|
||||||
"grid_columns": {
|
"grid_columns": {
|
||||||
"invoice_number": "Inv. number",
|
"invoice_number": "Inv. number",
|
||||||
|
|||||||
@ -33,7 +33,7 @@
|
|||||||
"title": "Facturas de clientes",
|
"title": "Facturas de clientes",
|
||||||
"description": "Gestiona tus facturas de clientes",
|
"description": "Gestiona tus facturas de clientes",
|
||||||
"list": {
|
"list": {
|
||||||
"title": "Listado de facturas de clientes",
|
"title": "Facturas de clientes",
|
||||||
"description": "Lista todas las facturas de clientes",
|
"description": "Lista todas las facturas de clientes",
|
||||||
"grid_columns": {
|
"grid_columns": {
|
||||||
"invoice_number": "Nº factura",
|
"invoice_number": "Nº factura",
|
||||||
|
|||||||
@ -81,30 +81,24 @@ export const InvoiceListPage = () => {
|
|||||||
<AppHeader>
|
<AppHeader>
|
||||||
<PageHeader
|
<PageHeader
|
||||||
title={t("pages.list.title")}
|
title={t("pages.list.title")}
|
||||||
|
description={t("pages.list.description")}
|
||||||
rightSlot={
|
rightSlot={
|
||||||
<></>}
|
<div className='flex items-center space-x-2'>
|
||||||
|
<Button
|
||||||
|
onClick={() => navigate("/customer-invoices/create")}
|
||||||
|
variant={'default'}
|
||||||
|
aria-label={t("pages.create.title")}
|
||||||
|
className='cursor-pointer'
|
||||||
|
>
|
||||||
|
<PlusIcon className="mr-2 h-4 w-4" aria-hidden />
|
||||||
|
{t("pages.create.title")}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</AppHeader>
|
</AppHeader>
|
||||||
<AppContent>
|
<AppContent>
|
||||||
<div className='flex items-center justify-between space-y-6'>
|
|
||||||
<div>
|
|
||||||
<h2 className='text-2xl font-bold tracking-tight'>{t("pages.list.title")}</h2>
|
|
||||||
<p className='text-muted-foreground'>{t("pages.list.description")}</p>
|
|
||||||
</div>
|
|
||||||
<div className='flex items-center space-x-2'>
|
|
||||||
<Button
|
|
||||||
onClick={() => navigate("/customer-invoices/create")}
|
|
||||||
variant={'default'}
|
|
||||||
aria-label={t("pages.create.title")}
|
|
||||||
className='cursor-pointer'
|
|
||||||
>
|
|
||||||
<PlusIcon className="mr-2 h-4 w-4" aria-hidden />
|
|
||||||
{t("pages.create.title")}
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className='flex flex-col w-full h-full py-3'>
|
<div className='flex flex-col w-full h-full py-3'>
|
||||||
<div className={"flex-1"}>
|
<div className={"flex-1"}>
|
||||||
<InvoicesListGrid
|
<InvoicesListGrid
|
||||||
|
|||||||
@ -84,7 +84,9 @@ export const InvoiceUpdateComp = ({
|
|||||||
<UnsavedChangesProvider isDirty={form.formState.isDirty}>
|
<UnsavedChangesProvider isDirty={form.formState.isDirty}>
|
||||||
<AppHeader>
|
<AppHeader>
|
||||||
<PageHeader
|
<PageHeader
|
||||||
title={`${t("pages.edit.title")} ${invoiceData.invoice_number}`}
|
backIcon
|
||||||
|
title={`${t("pages.edit.title")} #${invoiceData.invoice_number}`}
|
||||||
|
description={t("pages.edit.description")}
|
||||||
rightSlot={
|
rightSlot={
|
||||||
<UpdateCommitButtonGroup
|
<UpdateCommitButtonGroup
|
||||||
isLoading={isPending}
|
isLoading={isPending}
|
||||||
@ -93,9 +95,6 @@ export const InvoiceUpdateComp = ({
|
|||||||
cancel={{ to: "/customer-invoices/list" }}
|
cancel={{ to: "/customer-invoices/list" }}
|
||||||
onBack={() => navigate(-1)}
|
onBack={() => navigate(-1)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</AppHeader>
|
</AppHeader>
|
||||||
@ -106,7 +105,7 @@ export const InvoiceUpdateComp = ({
|
|||||||
formId="invoice-update-form"
|
formId="invoice-update-form"
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
onError={handleError}
|
onError={handleError}
|
||||||
className="max-w-full"
|
className="bg-white rounded-xl border shadow-xl max-w-full"
|
||||||
/>
|
/>
|
||||||
</FormProvider>
|
</FormProvider>
|
||||||
</AppContent>
|
</AppContent>
|
||||||
|
|||||||
@ -9,7 +9,7 @@ interface InvoiceUpdateFormProps {
|
|||||||
formId: string;
|
formId: string;
|
||||||
onSubmit: (data: InvoiceFormData) => void;
|
onSubmit: (data: InvoiceFormData) => void;
|
||||||
onError: (errors: FieldErrors<InvoiceFormData>) => void;
|
onError: (errors: FieldErrors<InvoiceFormData>) => void;
|
||||||
className: string;
|
className?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const InvoiceUpdateForm = ({
|
export const InvoiceUpdateForm = ({
|
||||||
@ -22,7 +22,7 @@ export const InvoiceUpdateForm = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<form noValidate id={formId} onSubmit={form.handleSubmit(onSubmit, onError)} >
|
<form noValidate id={formId} onSubmit={form.handleSubmit(onSubmit, onError)} >
|
||||||
<section className={cn("bg-white rounded-xl border shadow-xl space-y-6", className)}>
|
<section className={cn("p-6 space-y-6", className)}>
|
||||||
<div className="w-full p-6 bg-transparent grid grid-cols-1 lg:grid-cols-3 gap-6">
|
<div className="w-full p-6 bg-transparent grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||||||
<InvoiceRecipient className="flex flex-col" />
|
<InvoiceRecipient className="flex flex-col" />
|
||||||
<InvoiceBasicInfoFields className="flex flex-col lg:col-span-2" />
|
<InvoiceBasicInfoFields className="flex flex-col lg:col-span-2" />
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { FormDebug } from "@erp/core/components";
|
import { FormDebug } from "@erp/core/components";
|
||||||
import { FieldErrors, useFormContext } from "react-hook-form";
|
import { FieldErrors, useFormContext } from "react-hook-form";
|
||||||
|
|
||||||
|
import { cn } from '@repo/shadcn-ui/lib/utils';
|
||||||
import { CustomerFormData } from "../../schemas";
|
import { CustomerFormData } from "../../schemas";
|
||||||
import { CustomerAdditionalConfigFields } from "./customer-additional-config-fields";
|
import { CustomerAdditionalConfigFields } from "./customer-additional-config-fields";
|
||||||
import { CustomerAddressFields } from "./customer-address-fields";
|
import { CustomerAddressFields } from "./customer-address-fields";
|
||||||
@ -11,24 +12,27 @@ interface CustomerFormProps {
|
|||||||
formId: string;
|
formId: string;
|
||||||
onSubmit: (data: CustomerFormData) => void;
|
onSubmit: (data: CustomerFormData) => void;
|
||||||
onError: (errors: FieldErrors<CustomerFormData>) => void;
|
onError: (errors: FieldErrors<CustomerFormData>) => void;
|
||||||
|
className?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const CustomerEditForm = ({ formId, onSubmit, onError }: CustomerFormProps) => {
|
export const CustomerEditForm = ({ formId, onSubmit, onError, className }: CustomerFormProps) => {
|
||||||
const form = useFormContext<CustomerFormData>();
|
const form = useFormContext<CustomerFormData>();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form id={formId} onSubmit={form.handleSubmit(onSubmit, onError)}>
|
<form id={formId} onSubmit={form.handleSubmit(onSubmit, onError)}>
|
||||||
<div className='xl:flex xl:flex-row-reverse xl:items-start'>
|
<section className={cn("p-6", className)}>
|
||||||
<div className='w-full xl:w-6/12'>
|
<div className='xl:flex xl:flex-row-reverse xl:items-start'>
|
||||||
<FormDebug />
|
<div className='w-full xl:w-6/12'>
|
||||||
|
<FormDebug />
|
||||||
|
</div>
|
||||||
|
<div className='w-full xl:grow space-y-6'>
|
||||||
|
<CustomerBasicInfoFields />
|
||||||
|
<CustomerContactFields />
|
||||||
|
<CustomerAddressFields />
|
||||||
|
<CustomerAdditionalConfigFields />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className='w-full xl:grow space-y-6'>
|
</section>
|
||||||
<CustomerBasicInfoFields />
|
|
||||||
<CustomerContactFields />
|
|
||||||
<CustomerAddressFields />
|
|
||||||
<CustomerAdditionalConfigFields />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { PageHeader } from '@erp/core/components';
|
import { PageHeader } from '@erp/core/components';
|
||||||
import { AppBreadcrumb, AppContent, AppHeader, BackHistoryButton, useDebounce } from "@repo/rdx-ui/components";
|
import { AppContent, AppHeader, BackHistoryButton, useDebounce } from "@repo/rdx-ui/components";
|
||||||
import { Button } from "@repo/shadcn-ui/components";
|
import { Button } from "@repo/shadcn-ui/components";
|
||||||
import { PlusIcon } from "lucide-react";
|
import { PlusIcon } from "lucide-react";
|
||||||
import { useMemo, useState } from 'react';
|
import { useMemo, useState } from 'react';
|
||||||
@ -72,33 +72,25 @@ export const CustomersListPage = () => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<AppHeader>
|
<AppHeader>
|
||||||
<AppBreadcrumb />
|
|
||||||
<PageHeader
|
<PageHeader
|
||||||
title={t("pages.list.title")}
|
title={t("pages.list.title")}
|
||||||
|
description={t("pages.list.description")}
|
||||||
rightSlot={
|
rightSlot={
|
||||||
<></>}
|
<div className='flex items-center space-x-2'>
|
||||||
|
<Button
|
||||||
|
onClick={() => navigate("/customers/create")}
|
||||||
|
variant={'default'}
|
||||||
|
aria-label={t("pages.create.title")}
|
||||||
|
className='cursor-pointer'
|
||||||
|
>
|
||||||
|
<PlusIcon className="mr-2 h-4 w-4" aria-hidden />
|
||||||
|
{t("pages.create.title")}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</AppHeader>
|
</AppHeader>
|
||||||
<AppContent>
|
<AppContent>
|
||||||
<div className='flex items-center justify-between space-y-6'>
|
|
||||||
<div>
|
|
||||||
<h2 className='text-2xl font-bold tracking-tight'>{t("pages.list.title")}</h2>
|
|
||||||
<p className='text-muted-foreground'>{t("pages.list.description")}</p>
|
|
||||||
</div>
|
|
||||||
<div className='flex items-center space-x-2'>
|
|
||||||
<Button
|
|
||||||
onClick={() => navigate("/customer-invoices/create")}
|
|
||||||
variant={'default'}
|
|
||||||
aria-label={t("pages.create.title")}
|
|
||||||
className='cursor-pointer'
|
|
||||||
>
|
|
||||||
<PlusIcon className="mr-2 h-4 w-4" aria-hidden />
|
|
||||||
{t("pages.create.title")}
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className='flex flex-col w-full h-full py-3'>
|
<div className='flex flex-col w-full h-full py-3'>
|
||||||
<div className={"flex-1"}>
|
<div className={"flex-1"}>
|
||||||
<CustomersListGrid
|
<CustomersListGrid
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
import { AppBreadcrumb, AppContent, BackHistoryButton } from "@repo/rdx-ui/components";
|
import { AppContent, AppHeader, BackHistoryButton } from "@repo/rdx-ui/components";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
import { formHasAnyDirty, pickFormDirtyValues } from "@erp/core/client";
|
import { formHasAnyDirty, pickFormDirtyValues } from "@erp/core/client";
|
||||||
|
import { PageHeader } from '@erp/core/components';
|
||||||
import {
|
import {
|
||||||
UnsavedChangesProvider,
|
UnsavedChangesProvider,
|
||||||
UpdateCommitButtonGroup,
|
UpdateCommitButtonGroup,
|
||||||
@ -92,7 +93,7 @@ export const CustomerUpdatePage = () => {
|
|||||||
if (isLoadError) {
|
if (isLoadError) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<AppBreadcrumb />
|
|
||||||
<AppContent>
|
<AppContent>
|
||||||
<ErrorAlert
|
<ErrorAlert
|
||||||
title={t("pages.update.loadErrorTitle", "No se pudo cargar el cliente")}
|
title={t("pages.update.loadErrorTitle", "No se pudo cargar el cliente")}
|
||||||
@ -113,7 +114,7 @@ export const CustomerUpdatePage = () => {
|
|||||||
if (!customerData)
|
if (!customerData)
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<AppBreadcrumb />
|
|
||||||
<AppContent>
|
<AppContent>
|
||||||
<NotFoundCard
|
<NotFoundCard
|
||||||
title={t("pages.update.notFoundTitle", "Cliente no encontrado")}
|
title={t("pages.update.notFoundTitle", "Cliente no encontrado")}
|
||||||
@ -124,19 +125,13 @@ export const CustomerUpdatePage = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<UnsavedChangesProvider isDirty={form.formState.isDirty}>
|
||||||
<AppBreadcrumb />
|
<AppHeader>
|
||||||
<AppContent>
|
<PageHeader
|
||||||
<UnsavedChangesProvider isDirty={form.formState.isDirty}>
|
backIcon
|
||||||
<div className='flex items-center justify-between space-y-6'>
|
title={t("pages.update.title")}
|
||||||
<div className='space-y-2'>
|
description={t("pages.update.description")}
|
||||||
<h2 className='text-2xl font-bold tracking-tight text-balance scroll-m-2'>
|
rightSlot={
|
||||||
{t("pages.update.title")}
|
|
||||||
</h2>
|
|
||||||
<p className='text-muted-foreground scroll-m-20 tracking-tight text-balance'>
|
|
||||||
{t("pages.update.description")}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<UpdateCommitButtonGroup
|
<UpdateCommitButtonGroup
|
||||||
isLoading={isUpdating}
|
isLoading={isUpdating}
|
||||||
disabled={isUpdating}
|
disabled={isUpdating}
|
||||||
@ -151,27 +146,31 @@ export const CustomerUpdatePage = () => {
|
|||||||
onBack={() => handleBack()}
|
onBack={() => handleBack()}
|
||||||
onReset={() => handleReset()}
|
onReset={() => handleReset()}
|
||||||
/>
|
/>
|
||||||
</div>
|
}
|
||||||
{/* Alerta de error de actualización (si ha fallado el último intento) */}
|
/>
|
||||||
{isUpdateError && (
|
</AppHeader>
|
||||||
<ErrorAlert
|
<AppContent>
|
||||||
title={t("pages.update.errorTitle", "No se pudo guardar los cambios")}
|
{/* Alerta de error de actualización (si ha fallado el último intento) */}
|
||||||
message={
|
{isUpdateError && (
|
||||||
(updateError as Error)?.message ??
|
<ErrorAlert
|
||||||
t("pages.update.errorMsg", "Revisa los datos e inténtalo de nuevo.")
|
title={t("pages.update.errorTitle", "No se pudo guardar los cambios")}
|
||||||
}
|
message={
|
||||||
/>
|
(updateError as Error)?.message ??
|
||||||
)}
|
t("pages.update.errorMsg", "Revisa los datos e inténtalo de nuevo.")
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<FormProvider {...form}>
|
||||||
|
<CustomerEditForm
|
||||||
|
formId={"customer-update-form"} // para que el botón del header pueda hacer submit
|
||||||
|
onSubmit={handleSubmit}
|
||||||
|
onError={handleError}
|
||||||
|
className="bg-white rounded-xl border shadow-xl max-w-7xl mx-auto"
|
||||||
|
/>
|
||||||
|
</FormProvider>
|
||||||
|
|
||||||
<FormProvider {...form}>
|
|
||||||
<CustomerEditForm
|
|
||||||
formId={"customer-update-form"} // para que el botón del header pueda hacer submit
|
|
||||||
onSubmit={handleSubmit}
|
|
||||||
onError={handleError}
|
|
||||||
/>
|
|
||||||
</FormProvider>
|
|
||||||
</UnsavedChangesProvider>
|
|
||||||
</AppContent>
|
</AppContent>
|
||||||
</>
|
</UnsavedChangesProvider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
import { AppContent, BackHistoryButton } from "@repo/rdx-ui/components";
|
import { AppContent, AppHeader, BackHistoryButton } from "@repo/rdx-ui/components";
|
||||||
import { Button, Card, CardContent, CardHeader, CardTitle } from "@repo/shadcn-ui/components";
|
import { Button, Card, CardContent, CardHeader, CardTitle } from "@repo/shadcn-ui/components";
|
||||||
import {
|
import {
|
||||||
Banknote,
|
Banknote,
|
||||||
Building2,
|
|
||||||
EditIcon,
|
EditIcon,
|
||||||
FileText,
|
FileText,
|
||||||
Globe,
|
Globe,
|
||||||
@ -11,11 +10,11 @@ import {
|
|||||||
MapPin,
|
MapPin,
|
||||||
MoreVertical,
|
MoreVertical,
|
||||||
Phone,
|
Phone,
|
||||||
Smartphone,
|
Smartphone
|
||||||
User,
|
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
|
import { PageHeader } from '@erp/core/components';
|
||||||
import { useUrlParamId } from "@erp/core/hooks";
|
import { useUrlParamId } from "@erp/core/hooks";
|
||||||
import { Badge } from "@repo/shadcn-ui/components";
|
import { Badge } from "@repo/shadcn-ui/components";
|
||||||
import { CustomerEditorSkeleton, ErrorAlert } from "../../components";
|
import { CustomerEditorSkeleton, ErrorAlert } from "../../components";
|
||||||
@ -61,28 +60,17 @@ export const CustomerViewPage = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<AppContent>
|
<AppHeader>
|
||||||
<div className='space-y-6 max-w-4xl'>
|
<PageHeader
|
||||||
{/* Header */}
|
backIcon
|
||||||
<div className='flex items-start justify-between'>
|
title={(<div className="flex flex-wrap items-center gap-2">{customer?.name} {customer?.trade_name && <span className="text-muted-foreground">({customer.trade_name})</span>}</div>)}
|
||||||
<div className='flex items-start gap-4'>
|
description={<div className='mt-2 flex items-center gap-3'>
|
||||||
<div className='flex h-16 w-16 items-center justify-center rounded-lg'>
|
<Badge variant='secondary' className='font-mono'>
|
||||||
{customer?.is_company ? (
|
{customer?.tin}
|
||||||
<Building2 className='size-8 text-primary' />
|
</Badge>
|
||||||
) : (
|
<Badge variant='outline'>{customer?.is_company ? "Empresa" : "Persona"}</Badge>
|
||||||
<User className='size-8 text-primary' />
|
</div>}
|
||||||
)}
|
rightSlot={
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<h1 className='text-3xl font-bold text-foreground'>{customer?.name}</h1>
|
|
||||||
<div className='mt-2 flex items-center gap-3'>
|
|
||||||
<Badge variant='secondary' className='font-mono'>
|
|
||||||
{customer?.reference}
|
|
||||||
</Badge>
|
|
||||||
<Badge variant='outline'>{customer?.is_company ? "Empresa" : "Persona"}</Badge>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className='flex gap-2'>
|
<div className='flex gap-2'>
|
||||||
<Button variant='outline' size='icon' onClick={() => navigate("/customers/list")}>
|
<Button variant='outline' size='icon' onClick={() => navigate("/customers/list")}>
|
||||||
<MoreVertical className='h-4 w-4' />
|
<MoreVertical className='h-4 w-4' />
|
||||||
@ -92,248 +80,249 @@ export const CustomerViewPage = () => {
|
|||||||
Editar
|
Editar
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
}
|
||||||
|
/>
|
||||||
|
</AppHeader>
|
||||||
|
<AppContent>
|
||||||
|
{/* Main Content Grid */}
|
||||||
|
<div className='grid gap-6 md:grid-cols-2'>
|
||||||
|
{/* Información Básica */}
|
||||||
|
<Card>
|
||||||
|
<CardHeader>
|
||||||
|
<CardTitle className='flex items-center gap-2 text-lg'>
|
||||||
|
<FileText className='size-5 text-primary' />
|
||||||
|
Información Básica
|
||||||
|
</CardTitle>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent className='space-y-4'>
|
||||||
|
<div>
|
||||||
|
<dt className='text-sm font-medium text-muted-foreground'>Nombre</dt>
|
||||||
|
<dd className='mt-1 text-base text-foreground'>{customer?.name}</dd>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<dt className='text-sm font-medium text-muted-foreground'>Referencia</dt>
|
||||||
|
<dd className='mt-1 font-mono text-base text-foreground'>
|
||||||
|
{customer?.reference}
|
||||||
|
</dd>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<dt className='text-sm font-medium text-muted-foreground'>Registro Legal</dt>
|
||||||
|
<dd className='mt-1 text-base text-foreground'>{customer?.legal_record}</dd>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<dt className='text-sm font-medium text-muted-foreground'>
|
||||||
|
Impuestos por Defecto
|
||||||
|
</dt>
|
||||||
|
<dd className='mt-1'>
|
||||||
|
{customer?.default_taxes.map((tax) => (<Badge key={tax} variant={"secondary"}>{tax}</Badge>))}
|
||||||
|
</dd>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
|
||||||
{/* Main Content Grid */}
|
{/* Dirección */}
|
||||||
<div className='grid gap-6 md:grid-cols-2'>
|
<Card>
|
||||||
{/* Información Básica */}
|
<CardHeader>
|
||||||
<Card>
|
<CardTitle className='flex items-center gap-2 text-lg'>
|
||||||
<CardHeader>
|
<MapPin className='size-5 text-primary' />
|
||||||
<CardTitle className='flex items-center gap-2 text-lg'>
|
Dirección
|
||||||
<FileText className='size-5 text-primary' />
|
</CardTitle>
|
||||||
Información Básica
|
</CardHeader>
|
||||||
</CardTitle>
|
<CardContent className='space-y-4'>
|
||||||
</CardHeader>
|
<div>
|
||||||
<CardContent className='space-y-4'>
|
<dt className='text-sm font-medium text-muted-foreground'>Calle</dt>
|
||||||
|
<dd className='mt-1 text-base text-foreground'>
|
||||||
|
{customer?.street}
|
||||||
|
{customer?.street2 && (
|
||||||
|
<>
|
||||||
|
<br />
|
||||||
|
{customer?.street2}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</dd>
|
||||||
|
</div>
|
||||||
|
<div className='grid grid-cols-2 gap-4'>
|
||||||
<div>
|
<div>
|
||||||
<dt className='text-sm font-medium text-muted-foreground'>Nombre</dt>
|
<dt className='text-sm font-medium text-muted-foreground'>Ciudad</dt>
|
||||||
<dd className='mt-1 text-base text-foreground'>{customer?.name}</dd>
|
<dd className='mt-1 text-base text-foreground'>{customer?.city}</dd>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<dt className='text-sm font-medium text-muted-foreground'>Referencia</dt>
|
<dt className='text-sm font-medium text-muted-foreground'>Código Postal</dt>
|
||||||
<dd className='mt-1 font-mono text-base text-foreground'>
|
<dd className='mt-1 text-base text-foreground'>{customer?.postal_code}</dd>
|
||||||
{customer?.reference}
|
</div>
|
||||||
</dd>
|
</div>
|
||||||
|
<div className='grid grid-cols-2 gap-4'>
|
||||||
|
<div>
|
||||||
|
<dt className='text-sm font-medium text-muted-foreground'>Provincia</dt>
|
||||||
|
<dd className='mt-1 text-base text-foreground'>{customer?.province}</dd>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<dt className='text-sm font-medium text-muted-foreground'>Registro Legal</dt>
|
<dt className='text-sm font-medium text-muted-foreground'>País</dt>
|
||||||
<dd className='mt-1 text-base text-foreground'>{customer?.legalRecord}</dd>
|
<dd className='mt-1 text-base text-foreground'>{customer?.country}</dd>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
</div>
|
||||||
<dt className='text-sm font-medium text-muted-foreground'>
|
</CardContent>
|
||||||
Impuestos por Defecto
|
</Card>
|
||||||
</dt>
|
|
||||||
<dd className='mt-1'>
|
|
||||||
<Badge className='bg-blue-600 hover:bg-blue-700'>{customer?.defaultTax}</Badge>
|
|
||||||
</dd>
|
|
||||||
</div>
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
|
|
||||||
{/* Dirección */}
|
{/* Información de Contacto */}
|
||||||
<Card>
|
<Card className='md:col-span-2'>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className='flex items-center gap-2 text-lg'>
|
<CardTitle className='flex items-center gap-2 text-lg'>
|
||||||
<MapPin className='size-5 text-primary' />
|
<Mail className='size-5 text-primary' />
|
||||||
Dirección
|
Información de Contacto
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className='space-y-4'>
|
<CardContent>
|
||||||
<div>
|
<div className='grid gap-6 md:grid-cols-2'>
|
||||||
<dt className='text-sm font-medium text-muted-foreground'>Calle</dt>
|
{/* Contacto Principal */}
|
||||||
<dd className='mt-1 text-base text-foreground'>
|
<div className='space-y-4'>
|
||||||
{customer?.street1}
|
<h3 className='font-semibold text-foreground'>Contacto Principal</h3>
|
||||||
{customer?.street2 && (
|
{customer?.email_primary && (
|
||||||
<>
|
<div className='flex items-start gap-3'>
|
||||||
<br />
|
<Mail className='mt-0.5 h-4 w-4 text-muted-foreground' />
|
||||||
{customer?.street2}
|
<div className='flex-1'>
|
||||||
</>
|
<dt className='text-sm font-medium text-muted-foreground'>Email</dt>
|
||||||
)}
|
<dd className='mt-1 text-base text-foreground'>
|
||||||
</dd>
|
{customer?.email_primary}
|
||||||
</div>
|
</dd>
|
||||||
<div className='grid grid-cols-2 gap-4'>
|
|
||||||
<div>
|
|
||||||
<dt className='text-sm font-medium text-muted-foreground'>Ciudad</dt>
|
|
||||||
<dd className='mt-1 text-base text-foreground'>{customer?.city}</dd>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<dt className='text-sm font-medium text-muted-foreground'>Código Postal</dt>
|
|
||||||
<dd className='mt-1 text-base text-foreground'>{customer?.postal_code}</dd>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className='grid grid-cols-2 gap-4'>
|
|
||||||
<div>
|
|
||||||
<dt className='text-sm font-medium text-muted-foreground'>Provincia</dt>
|
|
||||||
<dd className='mt-1 text-base text-foreground'>{customer?.province}</dd>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<dt className='text-sm font-medium text-muted-foreground'>País</dt>
|
|
||||||
<dd className='mt-1 text-base text-foreground'>{customer?.country}</dd>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
|
|
||||||
{/* Información de Contacto */}
|
|
||||||
<Card className='md:col-span-2'>
|
|
||||||
<CardHeader>
|
|
||||||
<CardTitle className='flex items-center gap-2 text-lg'>
|
|
||||||
<Mail className='size-5 text-primary' />
|
|
||||||
Información de Contacto
|
|
||||||
</CardTitle>
|
|
||||||
</CardHeader>
|
|
||||||
<CardContent>
|
|
||||||
<div className='grid gap-6 md:grid-cols-2'>
|
|
||||||
{/* Contacto Principal */}
|
|
||||||
<div className='space-y-4'>
|
|
||||||
<h3 className='font-semibold text-foreground'>Contacto Principal</h3>
|
|
||||||
{customer?.email_primary && (
|
|
||||||
<div className='flex items-start gap-3'>
|
|
||||||
<Mail className='mt-0.5 h-4 w-4 text-muted-foreground' />
|
|
||||||
<div className='flex-1'>
|
|
||||||
<dt className='text-sm font-medium text-muted-foreground'>Email</dt>
|
|
||||||
<dd className='mt-1 text-base text-foreground'>
|
|
||||||
{customer?.email_primary}
|
|
||||||
</dd>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
</div>
|
||||||
{customer?.mobile_primary && (
|
)}
|
||||||
<div className='flex items-start gap-3'>
|
{customer?.mobile_primary && (
|
||||||
<Smartphone className='mt-0.5 h-4 w-4 text-muted-foreground' />
|
<div className='flex items-start gap-3'>
|
||||||
<div className='flex-1'>
|
<Smartphone className='mt-0.5 h-4 w-4 text-muted-foreground' />
|
||||||
<dt className='text-sm font-medium text-muted-foreground'>Móvil</dt>
|
<div className='flex-1'>
|
||||||
<dd className='mt-1 text-base text-foreground'>
|
<dt className='text-sm font-medium text-muted-foreground'>Móvil</dt>
|
||||||
{customer?.mobile_primary}
|
<dd className='mt-1 text-base text-foreground'>
|
||||||
</dd>
|
{customer?.mobile_primary}
|
||||||
</div>
|
</dd>
|
||||||
</div>
|
</div>
|
||||||
)}
|
</div>
|
||||||
{customer?.phone_primary && (
|
)}
|
||||||
<div className='flex items-start gap-3'>
|
{customer?.phone_primary && (
|
||||||
<Phone className='mt-0.5 h-4 w-4 text-muted-foreground' />
|
<div className='flex items-start gap-3'>
|
||||||
<div className='flex-1'>
|
<Phone className='mt-0.5 h-4 w-4 text-muted-foreground' />
|
||||||
<dt className='text-sm font-medium text-muted-foreground'>Teléfono</dt>
|
<div className='flex-1'>
|
||||||
<dd className='mt-1 text-base text-foreground'>
|
<dt className='text-sm font-medium text-muted-foreground'>Teléfono</dt>
|
||||||
{customer?.phone_primary}
|
<dd className='mt-1 text-base text-foreground'>
|
||||||
</dd>
|
{customer?.phone_primary}
|
||||||
</div>
|
</dd>
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Contacto Secundario */}
|
|
||||||
<div className='space-y-4'>
|
|
||||||
<h3 className='font-semibold text-foreground'>Contacto Secundario</h3>
|
|
||||||
{customer?.email_secondary && (
|
|
||||||
<div className='flex items-start gap-3'>
|
|
||||||
<Mail className='mt-0.5 h-4 w-4 text-muted-foreground' />
|
|
||||||
<div className='flex-1'>
|
|
||||||
<dt className='text-sm font-medium text-muted-foreground'>Email</dt>
|
|
||||||
<dd className='mt-1 text-base text-foreground'>
|
|
||||||
{customer?.email_secondary}
|
|
||||||
</dd>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{customer?.mobile_secondary && (
|
|
||||||
<div className='flex items-start gap-3'>
|
|
||||||
<Smartphone className='mt-0.5 h-4 w-4 text-muted-foreground' />
|
|
||||||
<div className='flex-1'>
|
|
||||||
<dt className='text-sm font-medium text-muted-foreground'>Móvil</dt>
|
|
||||||
<dd className='mt-1 text-base text-foreground'>
|
|
||||||
{customer?.mobile_secondary}
|
|
||||||
</dd>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{customer?.phone_secondary && (
|
|
||||||
<div className='flex items-start gap-3'>
|
|
||||||
<Phone className='mt-0.5 h-4 w-4 text-muted-foreground' />
|
|
||||||
<div className='flex-1'>
|
|
||||||
<dt className='text-sm font-medium text-muted-foreground'>Teléfono</dt>
|
|
||||||
<dd className='mt-1 text-base text-foreground'>
|
|
||||||
{customer?.phone_secondary}
|
|
||||||
</dd>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Otros Contactos */}
|
|
||||||
{(customer?.website || customer?.fax) && (
|
|
||||||
<div className='space-y-4 md:col-span-2'>
|
|
||||||
<h3 className='font-semibold text-foreground'>Otros</h3>
|
|
||||||
<div className='grid gap-4 md:grid-cols-2'>
|
|
||||||
{customer?.website && (
|
|
||||||
<div className='flex items-start gap-3'>
|
|
||||||
<Globe className='mt-0.5 h-4 w-4 text-muted-foreground' />
|
|
||||||
<div className='flex-1'>
|
|
||||||
<dt className='text-sm font-medium text-muted-foreground'>
|
|
||||||
Sitio Web
|
|
||||||
</dt>
|
|
||||||
<dd className='mt-1 text-base text-primary hover:underline'>
|
|
||||||
<a
|
|
||||||
href={customer?.website}
|
|
||||||
target='_blank'
|
|
||||||
rel='noopener noreferrer'
|
|
||||||
>
|
|
||||||
{customer?.website}
|
|
||||||
</a>
|
|
||||||
</dd>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{customer?.fax && (
|
|
||||||
<div className='flex items-start gap-3'>
|
|
||||||
<Phone className='mt-0.5 h-4 w-4 text-muted-foreground' />
|
|
||||||
<div className='flex-1'>
|
|
||||||
<dt className='text-sm font-medium text-muted-foreground'>Fax</dt>
|
|
||||||
<dd className='mt-1 text-base text-foreground'>{customer?.fax}</dd>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
|
|
||||||
{/* Preferencias */}
|
{/* Contacto Secundario */}
|
||||||
<Card className='md:col-span-2'>
|
<div className='space-y-4'>
|
||||||
<CardHeader>
|
<h3 className='font-semibold text-foreground'>Contacto Secundario</h3>
|
||||||
<CardTitle className='flex items-center gap-2 text-lg'>
|
{customer?.email_secondary && (
|
||||||
<Languages className='size-5 text-primary' />
|
<div className='flex items-start gap-3'>
|
||||||
Preferencias
|
<Mail className='mt-0.5 h-4 w-4 text-muted-foreground' />
|
||||||
</CardTitle>
|
<div className='flex-1'>
|
||||||
</CardHeader>
|
<dt className='text-sm font-medium text-muted-foreground'>Email</dt>
|
||||||
<CardContent>
|
<dd className='mt-1 text-base text-foreground'>
|
||||||
<div className='grid gap-6 md:grid-cols-2'>
|
{customer?.email_secondary}
|
||||||
<div className='flex items-start gap-3'>
|
</dd>
|
||||||
<Languages className='mt-0.5 h-4 w-4 text-muted-foreground' />
|
</div>
|
||||||
<div className='flex-1'>
|
</div>
|
||||||
<dt className='text-sm font-medium text-muted-foreground'>
|
)}
|
||||||
Idioma Preferido
|
{customer?.mobile_secondary && (
|
||||||
</dt>
|
<div className='flex items-start gap-3'>
|
||||||
<dd className='mt-1 text-base text-foreground'>{customer?.language_code}</dd>
|
<Smartphone className='mt-0.5 h-4 w-4 text-muted-foreground' />
|
||||||
|
<div className='flex-1'>
|
||||||
|
<dt className='text-sm font-medium text-muted-foreground'>Móvil</dt>
|
||||||
|
<dd className='mt-1 text-base text-foreground'>
|
||||||
|
{customer?.mobile_secondary}
|
||||||
|
</dd>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{customer?.phone_secondary && (
|
||||||
|
<div className='flex items-start gap-3'>
|
||||||
|
<Phone className='mt-0.5 h-4 w-4 text-muted-foreground' />
|
||||||
|
<div className='flex-1'>
|
||||||
|
<dt className='text-sm font-medium text-muted-foreground'>Teléfono</dt>
|
||||||
|
<dd className='mt-1 text-base text-foreground'>
|
||||||
|
{customer?.phone_secondary}
|
||||||
|
</dd>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Otros Contactos */}
|
||||||
|
{(customer?.website || customer?.fax) && (
|
||||||
|
<div className='space-y-4 md:col-span-2'>
|
||||||
|
<h3 className='font-semibold text-foreground'>Otros</h3>
|
||||||
|
<div className='grid gap-4 md:grid-cols-2'>
|
||||||
|
{customer?.website && (
|
||||||
|
<div className='flex items-start gap-3'>
|
||||||
|
<Globe className='mt-0.5 h-4 w-4 text-muted-foreground' />
|
||||||
|
<div className='flex-1'>
|
||||||
|
<dt className='text-sm font-medium text-muted-foreground'>
|
||||||
|
Sitio Web
|
||||||
|
</dt>
|
||||||
|
<dd className='mt-1 text-base text-primary hover:underline'>
|
||||||
|
<a
|
||||||
|
href={customer?.website}
|
||||||
|
target='_blank'
|
||||||
|
rel='noopener noreferrer'
|
||||||
|
>
|
||||||
|
{customer?.website}
|
||||||
|
</a>
|
||||||
|
</dd>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{customer?.fax && (
|
||||||
|
<div className='flex items-start gap-3'>
|
||||||
|
<Phone className='mt-0.5 h-4 w-4 text-muted-foreground' />
|
||||||
|
<div className='flex-1'>
|
||||||
|
<dt className='text-sm font-medium text-muted-foreground'>Fax</dt>
|
||||||
|
<dd className='mt-1 text-base text-foreground'>{customer?.fax}</dd>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className='flex items-start gap-3'>
|
)}
|
||||||
<Banknote className='mt-0.5 h-4 w-4 text-muted-foreground' />
|
</div>
|
||||||
<div className='flex-1'>
|
</CardContent>
|
||||||
<dt className='text-sm font-medium text-muted-foreground'>
|
</Card>
|
||||||
Moneda Preferida
|
|
||||||
</dt>
|
{/* Preferencias */}
|
||||||
<dd className='mt-1 text-base text-foreground'>{customer?.currency_code}</dd>
|
<Card className='md:col-span-2'>
|
||||||
</div>
|
<CardHeader>
|
||||||
|
<CardTitle className='flex items-center gap-2 text-lg'>
|
||||||
|
<Languages className='size-5 text-primary' />
|
||||||
|
Preferencias
|
||||||
|
</CardTitle>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
|
<div className='grid gap-6 md:grid-cols-2'>
|
||||||
|
<div className='flex items-start gap-3'>
|
||||||
|
<Languages className='mt-0.5 h-4 w-4 text-muted-foreground' />
|
||||||
|
<div className='flex-1'>
|
||||||
|
<dt className='text-sm font-medium text-muted-foreground'>
|
||||||
|
Idioma Preferido
|
||||||
|
</dt>
|
||||||
|
<dd className='mt-1 text-base text-foreground'>{customer?.language_code}</dd>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</CardContent>
|
<div className='flex items-start gap-3'>
|
||||||
</Card>
|
<Banknote className='mt-0.5 h-4 w-4 text-muted-foreground' />
|
||||||
</div>
|
<div className='flex-1'>
|
||||||
|
<dt className='text-sm font-medium text-muted-foreground'>
|
||||||
|
Moneda Preferida
|
||||||
|
</dt>
|
||||||
|
<dd className='mt-1 text-base text-foreground'>{customer?.currency_code}</dd>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
</AppContent>
|
</AppContent >
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -7,7 +7,7 @@ export const AppHeader = ({
|
|||||||
...props
|
...props
|
||||||
}: PropsWithChildren<{ className?: string }>) => {
|
}: PropsWithChildren<{ className?: string }>) => {
|
||||||
return (
|
return (
|
||||||
<div className={cn("app-header bg-background gap-4 px-6 pt-0 border-b bg-card", className)} {...props}>
|
<div className={cn("app-header gap-4 px-6 pt-0 border-b bg-background", className)} {...props}>
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -14,7 +14,7 @@ export const AppLayout = () => {
|
|||||||
>
|
>
|
||||||
<AppSidebar variant='inset' />
|
<AppSidebar variant='inset' />
|
||||||
{/* Aquí está el MAIN */}
|
{/* Aquí está el MAIN */}
|
||||||
<SidebarInset className='app-main bg-background'>
|
<SidebarInset className='app-main'>
|
||||||
<Outlet />
|
<Outlet />
|
||||||
</SidebarInset>
|
</SidebarInset>
|
||||||
</SidebarProvider>
|
</SidebarProvider>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user