Compare commits

...

2 Commits

Author SHA1 Message Date
957a92aad9 . 2025-04-16 13:34:34 +02:00
b6cb56daff Carga dinámica 2025-04-16 11:29:47 +02:00
14 changed files with 744 additions and 695 deletions

View File

@ -1,26 +1,34 @@
import { Suspense, lazy } from "react";
import { Navigate, Outlet, RouterProvider, createBrowserRouter } from "react-router-dom";
import {
DealerLayout,
DealersList,
ErrorPage,
LoginPageWithLanguageSelector,
LogoutPage,
QuoteCreate,
QuoteEdit,
SettingsEditor,
SettingsLayout,
} from "./app";
import { CatalogLayout, CatalogList } from "./app/catalog";
import { DashboardPage } from "./app/dashboard";
import { QuotesLayout } from "./app/quotes";
import { QuotesList } from "./app/quotes/list";
import { ProtectedRoute } from "./components";
import { LoadingOverlay, ProtectedRoute } from "./components";
// Lazy load components
const DealerLayout = lazy(() => import("./app").then((m) => ({ default: m.DealerLayout })));
const DealersList = lazy(() => import("./app").then((m) => ({ default: m.DealersList })));
const ErrorPage = lazy(() => import("./app").then((m) => ({ default: m.ErrorPage })));
const LoginPageWithLanguageSelector = lazy(() =>
import("./app").then((m) => ({ default: m.LoginPageWithLanguageSelector }))
);
const LogoutPage = lazy(() => import("./app").then((m) => ({ default: m.LogoutPage })));
const QuoteCreate = lazy(() => import("./app").then((m) => ({ default: m.QuoteCreate })));
const QuoteEdit = lazy(() => import("./app").then((m) => ({ default: m.QuoteEdit })));
const SettingsEditor = lazy(() => import("./app").then((m) => ({ default: m.SettingsEditor })));
const SettingsLayout = lazy(() => import("./app").then((m) => ({ default: m.SettingsLayout })));
const CatalogLayout = lazy(() => import("./app").then((m) => ({ default: m.CatalogLayout })));
const CatalogList = lazy(() => import("./app").then((m) => ({ default: m.CatalogList })));
const DashboardPage = lazy(() => import("./app").then((m) => ({ default: m.DashboardPage })));
const QuotesLayout = lazy(() => import("./app").then((m) => ({ default: m.QuotesLayout })));
const QuotesList = lazy(() => import("./app").then((m) => ({ default: m.QuotesList })));
export const Routes = () => {
const routesForErrors = [
{
path: "*",
Component: ErrorPage,
Element: (
<Suspense fallback={<LoadingOverlay />}>
<ErrorPage />
</Suspense>
),
},
];
@ -38,71 +46,105 @@ export const Routes = () => {
path: "/home",
element: (
<ProtectedRoute>
<DashboardPage />
<Suspense fallback={<LoadingOverlay />}>
<DashboardPage />
</Suspense>
</ProtectedRoute>
),
},
{
path: "/catalog",
element: (
<CatalogLayout>
<Outlet />
</CatalogLayout>
<Suspense fallback={<LoadingOverlay />}>
<CatalogLayout>
<Outlet />
</CatalogLayout>
</Suspense>
),
children: [
{
index: true,
element: <CatalogList />,
element: (
<Suspense fallback={<LoadingOverlay />}>
<CatalogList />
</Suspense>
),
},
],
},
{
path: "/dealers",
element: (
<DealerLayout>
<Outlet />
</DealerLayout>
<Suspense fallback={<LoadingOverlay />}>
<DealerLayout>
<Outlet />
</DealerLayout>
</Suspense>
),
children: [
{
index: true,
element: <DealersList />,
element: (
<Suspense fallback={<LoadingOverlay />}>
<DealersList />
</Suspense>
),
},
],
},
{
path: "/quotes",
element: (
<QuotesLayout>
<Outlet />
</QuotesLayout>
<Suspense fallback={<LoadingOverlay />}>
<QuotesLayout>
<Outlet />
</QuotesLayout>
</Suspense>
),
children: [
{
index: true,
element: <QuotesList />,
element: (
<Suspense fallback={<LoadingOverlay />}>
<QuotesList />
</Suspense>
),
},
{
path: "add",
element: <QuoteCreate />,
element: (
<Suspense fallback={<LoadingOverlay />}>
<QuoteCreate />
</Suspense>
),
},
{
path: "edit/:id",
element: <QuoteEdit />,
element: (
<Suspense fallback={<LoadingOverlay />}>
<QuoteEdit />
</Suspense>
),
},
],
},
{
path: "/settings",
element: (
<SettingsLayout>
<Outlet />
</SettingsLayout>
<Suspense fallback={<LoadingOverlay />}>
<SettingsLayout>
<Outlet />
</SettingsLayout>
</Suspense>
),
children: [
{
index: true,
element: <SettingsEditor />,
element: (
<Suspense fallback={<LoadingOverlay />}>
<SettingsEditor />
</Suspense>
),
},
],
},
@ -116,7 +158,11 @@ export const Routes = () => {
const routesForNotAuthenticatedOnly = [
{
path: "/login",
Component: LoginPageWithLanguageSelector,
element: (
<Suspense fallback={<LoadingOverlay />}>
<LoginPageWithLanguageSelector />
</Suspense>
),
},
];

View File

@ -117,10 +117,11 @@ export function CatalogDataTableFilter<TData>({
<Tooltip>
<TooltipTrigger asChild>
<Button
variant='outline'
variant='default'
size='icon'
disabled={!inputValue}
onClick={addFilterTerm}
className='w-8 h-8 p-0 hover:bg-muted'
className='w-8 h-8 p-0 transition-all'
>
<PlusIcon className='w-4 h-4' />
<span className='sr-only'>{t("common.filter.button_add_term")}</span>

View File

@ -72,17 +72,14 @@ export const QuoteItemsSortableDataTableToolbar = ({ table }: { table: Table<any
<div className='flex space-x-2'>
<Tooltip>
<TooltipTrigger asChild>
<AppendEmptyRowButton
variant='ghost'
onClick={() => table.options.meta?.appendItem()}
/>
<AppendEmptyRowButton variant='link' onClick={() => table.options.meta?.appendItem()} />
</TooltipTrigger>
<TooltipContent>{t("common.append_empty_row_tooltip")}</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger asChild>
<AppendCatalogArticleRowButton
variant='ghost'
variant='link'
onClick={() => {
if (table.options.meta && table.options.meta.pickCatalogArticle) {
table.options.meta?.pickCatalogArticle();
@ -95,7 +92,7 @@ export const QuoteItemsSortableDataTableToolbar = ({ table }: { table: Table<any
<Tooltip>
<TooltipTrigger asChild>
<AppendBlockRowButton
variant='ghost'
variant='link'
onClick={() => {
if (table.options.meta && table.options.meta.pickBlock) {
table.options.meta?.pickBlock();

View File

@ -100,32 +100,32 @@ export const QuoteEdit = () => {
id_article: "",
description: "",
quantity: {
amount: undefined,
amount: null,
scale: 2,
},
unit_price: {
amount: undefined,
amount: null,
scale: 2,
currency_code: "",
currency_code: quoteCurrency.code,
},
subtotal_price: {
amount: undefined,
amount: null,
scale: 2,
currency_code: "",
currency_code: quoteCurrency.code,
},
discount: {
amount: undefined,
amount: null,
scale: 2,
},
total_price: {
amount: undefined,
amount: null,
scale: 2,
currency_code: "",
currency_code: quoteCurrency.code,
},
},
],
}),
[]
[quoteCurrency.code]
);
const { useOne, useUpdate } = useQuotes();

View File

@ -3,10 +3,10 @@ import { PlusIcon } from "lucide-react";
export const SimpleEmptyState = ({
title = "Esto está muy vacío",
subtitle = "Empieza dando de alta un item",
buttonText = "Nuevo item",
subtitle = "Empieza solicitando la carga del catálogo",
buttonText = "Solicitar carga del catálogo",
onButtonClick = () => {},
actions = undefined,
actions = () => <></>,
}) => {
return (
<div className='text-center'>

View File

@ -1,6 +1,7 @@
{
"translation": {
"common": {
"loading": "Loading...",
"required": "required",
"cancel": "Cancel",
"no": "No",

View File

@ -1,6 +1,7 @@
{
"translation": {
"common": {
"loading": "Cargando...",
"required": "obligatorio",
"cancel": "Cancelar",
"no": "No",

315
dist/client/assets/index-BLcuj4sR.js vendored Normal file

File diff suppressed because one or more lines are too long

323
dist/client/assets/index-C4qjCyTZ.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1
dist/client/assets/index-DtTssDoC.css vendored Normal file

File diff suppressed because one or more lines are too long

1
dist/client/assets/index-enIG-PHa.css vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
<!doctype html><html><head><meta charset="UTF-8"/><meta name="robots" content="noindex, nofollow"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><meta name="viewport" content="width=device-width,initial-scale=1"/><link href="https://fonts.upset.dev/css2?family=Poppins&display=swap" rel="stylesheet"/><title>Presupuestador Uecko</title><script type="module" crossorigin src="/assets/index-Dma5RbLy.js"></script><link rel="stylesheet" crossorigin href="/assets/index-CRnRspMf.css"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="uecko"></div></body></html>
<!doctype html><html><head><meta charset="UTF-8"/><meta name="robots" content="noindex, nofollow"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><meta name="viewport" content="width=device-width,initial-scale=1"/><link href="https://fonts.upset.dev/css2?family=Poppins&display=swap" rel="stylesheet"/><title>Presupuestador Uecko</title><script type="module" crossorigin src="/assets/index-C4qjCyTZ.js"></script><link rel="stylesheet" crossorigin href="/assets/index-enIG-PHa.css"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="uecko"></div></body></html>