.
This commit is contained in:
parent
14d3771de2
commit
6ec26a2e05
@ -300,7 +300,7 @@ export const QuoteEdit = () => {
|
|||||||
|
|
||||||
<Tabs
|
<Tabs
|
||||||
defaultValue='items'
|
defaultValue='items'
|
||||||
className='space-y-4'
|
className='hidden space-y-4 '
|
||||||
value={activeTab}
|
value={activeTab}
|
||||||
onValueChange={setActiveTab}
|
onValueChange={setActiveTab}
|
||||||
>
|
>
|
||||||
|
|||||||
@ -14,29 +14,10 @@ export const QuotesLayout = ({ children }: PropsWithChildren) => {
|
|||||||
<Layout>
|
<Layout>
|
||||||
<LayoutHeader />
|
<LayoutHeader />
|
||||||
<LayoutContent>
|
<LayoutContent>
|
||||||
{" "}
|
<Outlet />
|
||||||
<div className={`layout ${isEditing ? "editing" : ""}`}>
|
|
||||||
<div className='quotes-list'>
|
|
||||||
<Outlet />
|
|
||||||
</div>
|
|
||||||
{isEditing && (
|
|
||||||
<div className='quotes-editor'>
|
|
||||||
<Outlet />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</LayoutContent>
|
</LayoutContent>
|
||||||
</Layout>
|
</Layout>
|
||||||
</QuotesProvider>
|
</QuotesProvider>
|
||||||
</ProtectedRoute>
|
</ProtectedRoute>
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
|
||||||
<QuotesProvider>
|
|
||||||
<Layout>
|
|
||||||
<LayoutHeader />
|
|
||||||
<LayoutContent>{children}</LayoutContent>
|
|
||||||
</Layout>
|
|
||||||
</QuotesProvider>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -2,10 +2,23 @@ import { DataTableProvider } from "@/lib/hooks";
|
|||||||
import { Trans } from "react-i18next";
|
import { Trans } from "react-i18next";
|
||||||
import { QuotesDataTable } from "./components";
|
import { QuotesDataTable } from "./components";
|
||||||
|
|
||||||
import { Button, Tabs, TabsContent, TabsList, TabsTrigger, Toggle } from "@/ui";
|
import {
|
||||||
|
Button,
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogDescription,
|
||||||
|
DialogHeader,
|
||||||
|
DialogTitle,
|
||||||
|
DialogTrigger,
|
||||||
|
Tabs,
|
||||||
|
TabsContent,
|
||||||
|
TabsList,
|
||||||
|
TabsTrigger,
|
||||||
|
Toggle,
|
||||||
|
} from "@/ui";
|
||||||
import { useToggle } from "@wojtekmaj/react-hooks";
|
import { useToggle } from "@wojtekmaj/react-hooks";
|
||||||
import { t } from "i18next";
|
import { t } from "i18next";
|
||||||
import { EyeIcon, EyeOffIcon, PlusIcon } from "lucide-react";
|
import { EyeIcon, EyeOffIcon, HelpCircleIcon, PlusIcon } from "lucide-react";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
export const QuotesList = () => {
|
export const QuotesList = () => {
|
||||||
@ -33,7 +46,56 @@ export const QuotesList = () => {
|
|||||||
|
|
||||||
<Tabs defaultValue='all'>
|
<Tabs defaultValue='all'>
|
||||||
<div className='flex items-center'>
|
<div className='flex items-center'>
|
||||||
<span className='mr-4 font-medium'>Status</span>
|
<div className='flex items-center justify-center mr-4 font-medium'>
|
||||||
|
<Trans i18nKey='quotes.list.columns.status' />
|
||||||
|
<Dialog>
|
||||||
|
<DialogTrigger asChild>
|
||||||
|
<Button variant='ghost' size='icon' className='w-4 h-4 p-0 ml-1'>
|
||||||
|
<HelpCircleIcon className='w-4 h-4 ml-1 text-muted-foreground' />
|
||||||
|
</Button>
|
||||||
|
</DialogTrigger>
|
||||||
|
<DialogContent className='sm:max-w-[425px]'>
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle>Ayuda sobre el Estado de Cotizaciones</DialogTitle>
|
||||||
|
<DialogDescription>
|
||||||
|
El estado de una cotización indica su posición actual en el proceso de negocio.
|
||||||
|
</DialogDescription>
|
||||||
|
</DialogHeader>
|
||||||
|
<div className='grid gap-4 py-4'>
|
||||||
|
<p>Los estados posibles son:</p>
|
||||||
|
<ul className='pl-6 space-y-2 list-disc'>
|
||||||
|
<li>
|
||||||
|
<strong>Borrador:</strong> La cotización está en proceso de creación o
|
||||||
|
edición.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Preparado:</strong> La cotización está lista para ser enviada al
|
||||||
|
cliente.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Entregado:</strong> La cotización ha sido enviada al cliente.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Aceptado:</strong> El cliente ha aprobado la cotización.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Rechazado:</strong> El cliente no ha aceptado la cotización.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Arcivado:</strong> La cotización ha sido guardada para referencia
|
||||||
|
futura y ya no está activa.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
Utiliza estos estados para hacer un seguimiento eficiente de tus cotizaciones y
|
||||||
|
optimizar tu proceso de ventas. El estado <strong>Archivado</strong> es útil
|
||||||
|
para mantener un historial de cotizaciones pasadas sin que interfieran con las
|
||||||
|
cotizaciones activas.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
</div>
|
||||||
<TabsList>
|
<TabsList>
|
||||||
<TabsTrigger value='all'>
|
<TabsTrigger value='all'>
|
||||||
<Trans i18nKey='quotes.list.tabs.all' />
|
<Trans i18nKey='quotes.list.tabs.all' />
|
||||||
|
|||||||
@ -48,6 +48,14 @@ app.use(
|
|||||||
// secure apps by setting various HTTP headers
|
// secure apps by setting various HTTP headers
|
||||||
app.use(helmet());
|
app.use(helmet());
|
||||||
|
|
||||||
|
// Middleware global para desactivar la caché en todas las rutas
|
||||||
|
app.use((req, res, next) => {
|
||||||
|
res.setHeader("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0");
|
||||||
|
res.setHeader("Pragma", "no-cache");
|
||||||
|
res.setHeader("Expires", "0");
|
||||||
|
next(); // Continúa con la siguiente función middleware o la ruta
|
||||||
|
});
|
||||||
|
|
||||||
// request logging. dev: console | production: file
|
// request logging. dev: console | production: file
|
||||||
//app.use(morgan('common'));
|
//app.use(morgan('common'));
|
||||||
app.use(morgan("dev"));
|
app.use(morgan("dev"));
|
||||||
|
|||||||
@ -8,7 +8,7 @@ const createCatalogTableIfNotExists = async (sequelize: Sequelize) => {
|
|||||||
try {
|
try {
|
||||||
// Consulta para verificar si la tabla existe
|
// Consulta para verificar si la tabla existe
|
||||||
const checkTableQuery = `
|
const checkTableQuery = `
|
||||||
SELECT COUNT(*)
|
SELECT COUNT(*) as count
|
||||||
FROM information_schema.tables
|
FROM information_schema.tables
|
||||||
WHERE table_schema = DATABASE()
|
WHERE table_schema = DATABASE()
|
||||||
AND table_name = 'catalog';`;
|
AND table_name = 'catalog';`;
|
||||||
@ -56,7 +56,7 @@ const createCatalogTranslationsTableIfNotExists = async (sequelize: Sequelize) =
|
|||||||
try {
|
try {
|
||||||
// Consulta para verificar si la tabla existe
|
// Consulta para verificar si la tabla existe
|
||||||
const checkTableQuery = `
|
const checkTableQuery = `
|
||||||
SELECT COUNT(*)
|
SELECT COUNT(*) as count
|
||||||
FROM information_schema.tables
|
FROM information_schema.tables
|
||||||
WHERE table_schema = DATABASE()
|
WHERE table_schema = DATABASE()
|
||||||
AND table_name = 'catalog_translations';
|
AND table_name = 'catalog_translations';
|
||||||
@ -104,7 +104,7 @@ const createVCatalogViewIfNotExists = async (sequelize: Sequelize) => {
|
|||||||
try {
|
try {
|
||||||
// Consulta para verificar si la tabla existe
|
// Consulta para verificar si la tabla existe
|
||||||
const checkViewQuery = `
|
const checkViewQuery = `
|
||||||
SELECT COUNT(*)
|
SELECT COUNT(*) as count
|
||||||
FROM information_schema.views
|
FROM information_schema.views
|
||||||
WHERE table_schema = DATABASE()
|
WHERE table_schema = DATABASE()
|
||||||
AND table_name = 'v_catalog';
|
AND table_name = 'v_catalog';
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user