Compare commits
13 Commits
202521f225
...
556a8a2848
| Author | SHA1 | Date |
|---|---|---|
|
|
556a8a2848 | |
|
|
77058335a3 | |
|
|
3b7faaae03 | |
|
|
2018f925cc | |
|
|
bfa3be924a | |
|
|
31dc8c9478 | |
|
|
7406a5d855 | |
|
|
dce24eb54b | |
|
|
c5f3ea74d4 | |
|
|
3f21087779 | |
|
|
d52c64c102 | |
|
|
da9758d875 | |
|
|
f8b1b795a3 |
|
|
@ -35,5 +35,5 @@ yarn-error.log*
|
||||||
!.yarn/versions
|
!.yarn/versions
|
||||||
.pnp.*
|
.pnp.*
|
||||||
|
|
||||||
yarn.lock
|
/yarn.lock
|
||||||
package-lock.json
|
package-lock.json
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
"draft-js": "0.11.7",
|
"draft-js": "0.11.7",
|
||||||
"draftjs-to-html": "0.9.1",
|
"draftjs-to-html": "0.9.1",
|
||||||
"firebase": "10.7.1",
|
"firebase": "10.7.1",
|
||||||
|
"formik": "^2.4.5",
|
||||||
"framer-motion": "10.18.0",
|
"framer-motion": "10.18.0",
|
||||||
"history": "5.3.0",
|
"history": "5.3.0",
|
||||||
"i18next": "23.7.16",
|
"i18next": "23.7.16",
|
||||||
|
|
@ -56,7 +57,9 @@
|
||||||
"stylis": "4.3.1",
|
"stylis": "4.3.1",
|
||||||
"stylis-plugin-rtl": "2.1.1",
|
"stylis-plugin-rtl": "2.1.1",
|
||||||
"type-fest": "4.9.0",
|
"type-fest": "4.9.0",
|
||||||
|
"uuid": "^9.0.1",
|
||||||
"web-vitals": "3.5.1",
|
"web-vitals": "3.5.1",
|
||||||
|
"yup": "^1.3.3",
|
||||||
"zod": "3.22.4"
|
"zod": "3.22.4"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
|
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
|
|
@ -32,7 +32,7 @@ function FuseLoading(props: FuseLoadingProps) {
|
||||||
className="-mb-16 text-13 font-medium sm:text-20"
|
className="-mb-16 text-13 font-medium sm:text-20"
|
||||||
color="text.secondary"
|
color="text.secondary"
|
||||||
>
|
>
|
||||||
Loading
|
Cargando
|
||||||
</Typography>
|
</Typography>
|
||||||
<Box
|
<Box
|
||||||
id="spinner"
|
id="spinner"
|
||||||
|
|
|
||||||
|
|
@ -171,7 +171,8 @@ export const defaultThemeOptions = {
|
||||||
MuiDialog: {
|
MuiDialog: {
|
||||||
styleOverrides: {
|
styleOverrides: {
|
||||||
paper: {
|
paper: {
|
||||||
borderRadius: 16
|
borderRadius: 10,
|
||||||
|
padding: 5
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -32751,8 +32751,8 @@
|
||||||
"password": "admin",
|
"password": "admin",
|
||||||
"role": "admin",
|
"role": "admin",
|
||||||
"data": {
|
"data": {
|
||||||
"displayName": "Abbott Keitch",
|
"displayName": "Andres Alvarez",
|
||||||
"photoURL": "assets/images/avatars/brian-hughes.jpg",
|
"photoURL": "assets/images/avatars/user.jpg",
|
||||||
"email": "admin@qsoftec.com",
|
"email": "admin@qsoftec.com",
|
||||||
"settings": {
|
"settings": {
|
||||||
"layout": {},
|
"layout": {},
|
||||||
|
|
|
||||||
|
|
@ -31,9 +31,20 @@ export type SignInPayload = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export type SignUpPayload = {
|
export type SignUpPayload = {
|
||||||
displayName: string;
|
usuUsuario: string;
|
||||||
|
usuNombre: string;
|
||||||
|
detCodigo: number;
|
||||||
|
empIdentificacion: string;
|
||||||
|
empRazonSocial: string;
|
||||||
|
empNombreComercial: string;
|
||||||
|
empContacto: string;
|
||||||
|
empDireccion: string;
|
||||||
|
empMail: string;
|
||||||
|
empCodContribuyente: string;
|
||||||
|
empDescripcion: string;
|
||||||
|
empLlevaContabilidad: string;
|
||||||
password: string;
|
password: string;
|
||||||
email: string;
|
passwordConfirm: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type AuthContext = {
|
type AuthContext = {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
|
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
||||||
import { useState, useEffect, useCallback } from 'react';
|
import { useState, useEffect, useCallback } from 'react';
|
||||||
import axios, { AxiosError, AxiosResponse } from 'axios';
|
import axios, { AxiosError, AxiosResponse } from 'axios';
|
||||||
import jwtDecode, { JwtPayload } from 'jwt-decode';
|
import jwtDecode, { JwtPayload } from 'jwt-decode';
|
||||||
import _ from '@lodash';
|
import _ from '@lodash';
|
||||||
import { PartialDeep } from 'type-fest';
|
import { PartialDeep } from 'type-fest';
|
||||||
|
import { loginIn } from 'src/app/services/user.service';
|
||||||
|
|
||||||
const defaultAuthConfig = {
|
const defaultAuthConfig = {
|
||||||
tokenStorageKey: 'jwt_access_token',
|
tokenStorageKey: 'jwt_access_token',
|
||||||
|
|
@ -47,6 +49,10 @@ export type JwtAuth<User, SignInPayload, SignUpPayload> = {
|
||||||
setIsLoading: (isLoading: boolean) => void;
|
setIsLoading: (isLoading: boolean) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type UserLogin = {
|
||||||
|
user: string;
|
||||||
|
password: string;
|
||||||
|
};
|
||||||
/**
|
/**
|
||||||
* useJwtAuth hook
|
* useJwtAuth hook
|
||||||
* Description: This hook handles the authentication flow using JWT
|
* Description: This hook handles the authentication flow using JWT
|
||||||
|
|
@ -94,7 +100,7 @@ const useJwtAuth = <User, SignInPayload, SignUpPayload>(
|
||||||
/**
|
/**
|
||||||
* Handle sign-in success
|
* Handle sign-in success
|
||||||
*/
|
*/
|
||||||
const handleSignInSuccess = useCallback((userData: User, accessToken: string) => {
|
const handleSignInSuccess = useCallback((userData: User, accessToken) => {
|
||||||
setSession(accessToken);
|
setSession(accessToken);
|
||||||
|
|
||||||
setIsAuthenticated(true);
|
setIsAuthenticated(true);
|
||||||
|
|
@ -215,9 +221,18 @@ const useJwtAuth = <User, SignInPayload, SignUpPayload>(
|
||||||
/**
|
/**
|
||||||
* Sign in
|
* Sign in
|
||||||
*/
|
*/
|
||||||
const signIn = async (credentials: SignInPayload) => {
|
const signIn = async (credentials: UserLogin) => {
|
||||||
const response = axios.post(authConfig.signInUrl, credentials);
|
const response = axios.post(authConfig.signInUrl, credentials);
|
||||||
|
/* const {error, bodyOut} = await loginIn(credentials.email, credentials.password);
|
||||||
|
|
||||||
|
if(error.codigo === '0'){
|
||||||
|
const userData = bodyOut.data[0];
|
||||||
|
|
||||||
|
handleSignInSuccess(userData);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return bodyOut.data[0]; */
|
||||||
response.then(
|
response.then(
|
||||||
(res: AxiosResponse<{ user: User; access_token: string }>) => {
|
(res: AxiosResponse<{ user: User; access_token: string }>) => {
|
||||||
const userData = res?.data?.user;
|
const userData = res?.data?.user;
|
||||||
|
|
@ -236,7 +251,7 @@ const useJwtAuth = <User, SignInPayload, SignUpPayload>(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
return response;
|
// return response;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||||
|
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||||
|
import { v4 as uuidV4 } from 'uuid';
|
||||||
|
|
||||||
|
interface Header {
|
||||||
|
dispositivo: string;
|
||||||
|
canal: string | null;
|
||||||
|
medio: string | null;
|
||||||
|
aplicacion: string;
|
||||||
|
tipoTransaccion: string | null;
|
||||||
|
usuario: string | number;
|
||||||
|
uuid: string;
|
||||||
|
fechaHora: string | null;
|
||||||
|
idioma: string | null;
|
||||||
|
empresa: string | null;
|
||||||
|
geolocalizacion: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface User {
|
||||||
|
usercode: string | number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const user: User = JSON.parse(localStorage.getItem('user'));
|
||||||
|
|
||||||
|
const headerIn: Header = {
|
||||||
|
dispositivo: 'WeLaptop',
|
||||||
|
canal: null,
|
||||||
|
medio: null,
|
||||||
|
aplicacion: 'SINCOARV2',
|
||||||
|
tipoTransaccion: null,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||||
|
usuario: user ? user.usercode : 'user',
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||||
|
uuid: uuidV4(),
|
||||||
|
fechaHora: null,
|
||||||
|
idioma: null,
|
||||||
|
empresa: null,
|
||||||
|
geolocalizacion: null
|
||||||
|
};
|
||||||
|
|
||||||
|
const url = 'http://services.qsoftec.com:18080/inventario-rs-services-1.0-SNAPSHOT/servicios'; // test
|
||||||
|
// let url = 'https://tramitesarmas.ccffaa.mil.ec/sincoar/servicios' //produccion
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
api: url,
|
||||||
|
headerIn
|
||||||
|
};
|
||||||
|
|
||||||
|
export default config;
|
||||||
|
|
@ -2,7 +2,8 @@ const locale = {
|
||||||
APPLICATIONS: 'Applications',
|
APPLICATIONS: 'Applications',
|
||||||
EXAMPLE: 'Example',
|
EXAMPLE: 'Example',
|
||||||
DASHBOARD: 'Tablero',
|
DASHBOARD: 'Tablero',
|
||||||
INVOICE: 'Factura'
|
INVOICE: 'Factura',
|
||||||
|
PRODUCT: 'Producto'
|
||||||
};
|
};
|
||||||
|
|
||||||
export default locale;
|
export default locale;
|
||||||
|
|
|
||||||
|
|
@ -14,18 +14,10 @@ i18next.addResourceBundle('es', 'navigation', es);
|
||||||
* The navigationConfig object is an array of navigation items for the Fuse application.
|
* The navigationConfig object is an array of navigation items for the Fuse application.
|
||||||
*/
|
*/
|
||||||
const navigationConfig: FuseNavItemType[] = [
|
const navigationConfig: FuseNavItemType[] = [
|
||||||
{
|
|
||||||
id: 'example-component',
|
|
||||||
title: 'Example',
|
|
||||||
translate: 'EXAMPLE',
|
|
||||||
type: 'item',
|
|
||||||
icon: 'heroicons-outline:star',
|
|
||||||
url: 'example'
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: 'dashboard-component',
|
id: 'dashboard-component',
|
||||||
title: 'Tablero',
|
title: 'Dashboard',
|
||||||
translate: 'TABLERO',
|
translate: 'DASHBOARD',
|
||||||
type: 'item',
|
type: 'item',
|
||||||
icon: 'heroicons-outline:star',
|
icon: 'heroicons-outline:star',
|
||||||
url: 'dashboards/project'
|
url: 'dashboards/project'
|
||||||
|
|
@ -37,8 +29,35 @@ const navigationConfig: FuseNavItemType[] = [
|
||||||
type: 'item',
|
type: 'item',
|
||||||
icon: 'heroicons-outline:document-text',
|
icon: 'heroicons-outline:document-text',
|
||||||
url: 'invoice/list'
|
url: 'invoice/list'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'producto-component',
|
||||||
|
title: 'Producto',
|
||||||
|
translate: 'PRODUCT',
|
||||||
|
type: 'item',
|
||||||
|
icon: 'heroicons-outline:clipboard-check',
|
||||||
|
url: 'product/list'
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
id: 'cliente-component',
|
||||||
|
title: 'Cliente',
|
||||||
|
translate: 'Cliente',
|
||||||
|
type: 'item',
|
||||||
|
icon: 'heroicons-outline:user',
|
||||||
|
url: 'client/list'
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
id: 'firma-component',
|
||||||
|
title: 'signature',
|
||||||
|
translate: 'Firma',
|
||||||
|
type: 'item',
|
||||||
|
icon: 'heroicons-outline:pencil',
|
||||||
|
url: 'signature/form'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
export default navigationConfig;
|
export default navigationConfig;
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,22 @@ import SignInConfig from '../main/sign-in/SignInConfig';
|
||||||
import SignUpConfig from '../main/sign-up/SignUpConfig';
|
import SignUpConfig from '../main/sign-up/SignUpConfig';
|
||||||
import SignOutConfig from '../main/sign-out/SignOutConfig';
|
import SignOutConfig from '../main/sign-out/SignOutConfig';
|
||||||
import Error404Page from '../main/404/Error404Page';
|
import Error404Page from '../main/404/Error404Page';
|
||||||
import ExampleConfig from '../main/example/ExampleConfig';
|
|
||||||
import ProjectDashboardAppConfig from '../main/dashboard/project/ProjectDashboardAppConfig';
|
import ProjectDashboardAppConfig from '../main/dashboard/project/ProjectDashboardAppConfig';
|
||||||
|
import ProductoConfigs from '../main/producto/ProductoConfig';
|
||||||
import InvoiceConfigs from '../main/invoice/InvoiceConfig';
|
import InvoiceConfigs from '../main/invoice/InvoiceConfig';
|
||||||
|
import ClientConfig from '../main/client/ClientConfig';
|
||||||
|
import firmaConfigs from '../main/firmaElectronica/FirmaConfig';
|
||||||
|
|
||||||
const routeConfigs: FuseRouteConfigsType = [ExampleConfig, SignOutConfig, SignInConfig, SignUpConfig, ProjectDashboardAppConfig, ...InvoiceConfigs];
|
const routeConfigs: FuseRouteConfigsType = [
|
||||||
|
SignOutConfig,
|
||||||
|
SignInConfig,
|
||||||
|
SignUpConfig,
|
||||||
|
ProjectDashboardAppConfig,
|
||||||
|
...ProductoConfigs,
|
||||||
|
...InvoiceConfigs,
|
||||||
|
...ClientConfig,
|
||||||
|
...firmaConfigs
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The routes of the application.
|
* The routes of the application.
|
||||||
|
|
@ -21,7 +31,7 @@ const routes: FuseRoutesType = [
|
||||||
...FuseUtils.generateRoutesFromConfigs(routeConfigs, settingsConfig.defaultAuth),
|
...FuseUtils.generateRoutesFromConfigs(routeConfigs, settingsConfig.defaultAuth),
|
||||||
{
|
{
|
||||||
path: '/',
|
path: '/',
|
||||||
element: <Navigate to="/example" />,
|
element: <Navigate to="/dashboards/project" />,
|
||||||
auth: settingsConfig.defaultAuth
|
auth: settingsConfig.defaultAuth
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,8 @@ function Error404Page() {
|
||||||
>
|
>
|
||||||
<Box
|
<Box
|
||||||
component="svg"
|
component="svg"
|
||||||
width="100%"
|
width="80%"
|
||||||
height="100%"
|
height="80%"
|
||||||
viewBox="0 0 1075 585"
|
viewBox="0 0 1075 585"
|
||||||
fill="none"
|
fill="none"
|
||||||
preserveAspectRatio="xMidYMax slice"
|
preserveAspectRatio="xMidYMax slice"
|
||||||
|
|
@ -243,7 +243,7 @@ function Error404Page() {
|
||||||
color="text.secondary"
|
color="text.secondary"
|
||||||
className="mt-8 text-center text-lg font-medium tracking-tight md:text-xl"
|
className="mt-8 text-center text-lg font-medium tracking-tight md:text-xl"
|
||||||
>
|
>
|
||||||
The page you requested could not be found.
|
La página a la que se quiere acceder no existe.
|
||||||
</Typography>
|
</Typography>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
<Link
|
<Link
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
import DemoContent from '@fuse/core/DemoContent';
|
||||||
|
import FusePageSimple from '@fuse/core/FusePageSimple';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { styled } from '@mui/material/styles';
|
||||||
|
import ClientRender from './ClientRender';
|
||||||
|
|
||||||
|
|
||||||
|
const Root = styled(FusePageSimple)(({ theme }) => ({
|
||||||
|
'& .FusePageSimple-header': {
|
||||||
|
backgroundColor: theme.palette.background.paper,
|
||||||
|
borderBottomWidth: 1,
|
||||||
|
borderStyle: 'solid',
|
||||||
|
borderColor: theme.palette.divider
|
||||||
|
},
|
||||||
|
'& .FusePageSimple-content': {},
|
||||||
|
'& .FusePageSimple-sidebarHeader': {},
|
||||||
|
'& .FusePageSimple-sidebarContent': {}
|
||||||
|
}));
|
||||||
|
|
||||||
|
function Client() {
|
||||||
|
const { t } = useTranslation('clients');
|
||||||
|
|
||||||
|
return(
|
||||||
|
<Root
|
||||||
|
header={
|
||||||
|
<div className='p-24'>
|
||||||
|
<h4>{t('CLIENTES')}</h4>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
content={
|
||||||
|
<ClientRender></ClientRender>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Client;
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
import { FuseRouteConfigsType } from "@fuse/utils/FuseUtils";
|
||||||
|
import DetalleClienteConfig from "./detalleCliente/DetalleClienteConfig";
|
||||||
|
import FormularioClienteConfig from "./formularioCliente/FormularioClienteConfig";
|
||||||
|
|
||||||
|
const clientConfigs: FuseRouteConfigsType = [
|
||||||
|
DetalleClienteConfig,
|
||||||
|
FormularioClienteConfig
|
||||||
|
]
|
||||||
|
|
||||||
|
export default clientConfigs;
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
import DetalleCliente from "./detalleCliente/DetalleCliente"
|
||||||
|
|
||||||
|
const ClientRender = () => {
|
||||||
|
return (
|
||||||
|
<div className="w-full p-12 pt-16 sm:pt-24 lg:ltr:pr-0 lg:rtl:pl-0">
|
||||||
|
<DetalleCliente></DetalleCliente>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ClientRender;
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
import ListDetalleClienteRender from './DetalleClienteRender'
|
||||||
|
|
||||||
|
const DetalleCliente = () => {
|
||||||
|
return (
|
||||||
|
<ListDetalleClienteRender/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DetalleCliente;
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
import {lazy} from 'react';
|
||||||
|
|
||||||
|
const Cliente = lazy(() => import('./DetalleCliente'));
|
||||||
|
|
||||||
|
const DetalleClienteConfig = {
|
||||||
|
settings: {
|
||||||
|
layout: {
|
||||||
|
config: {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
path: 'client/list',
|
||||||
|
element: <Cliente/>
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DetalleClienteConfig;
|
||||||
|
|
@ -0,0 +1,185 @@
|
||||||
|
import FusePageSimple from '@fuse/core/FusePageSimple';
|
||||||
|
import FuseSvgIcon from '@fuse/core/FuseSvgIcon';
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
IconButton,
|
||||||
|
Paper,
|
||||||
|
Table,
|
||||||
|
TableBody,
|
||||||
|
TableCell,
|
||||||
|
TableHead,
|
||||||
|
TablePagination,
|
||||||
|
TableRow,
|
||||||
|
Typography,
|
||||||
|
styled
|
||||||
|
} from "@mui/material";
|
||||||
|
import clsx from 'clsx';
|
||||||
|
import { format } from 'date-fns';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
import ResponsiveDialog from 'src/components/widgets/DialogDelete';
|
||||||
|
|
||||||
|
const Root = styled(FusePageSimple)(({ theme }) => ({
|
||||||
|
'& .FusePageSimple-header': {
|
||||||
|
backgroundColor: theme.palette.background.paper,
|
||||||
|
boxShadow: `inset 0 0 0 1px ${theme.palette.divider}`
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
function ListDetalleClienteRender() {
|
||||||
|
const { t } = useTranslation('clients');
|
||||||
|
const columns = [
|
||||||
|
'id',
|
||||||
|
'Nombre Comercial',
|
||||||
|
'Razon Social',
|
||||||
|
'Identificación',
|
||||||
|
'Teléfono',
|
||||||
|
'Correo Electrónico',
|
||||||
|
'Acciones',
|
||||||
|
];
|
||||||
|
|
||||||
|
const rows = [
|
||||||
|
{
|
||||||
|
id: 111,
|
||||||
|
nombreComercial:'Susana Noroña',
|
||||||
|
razonSocial: 'Susana Noroña',
|
||||||
|
identificacion: '1720336948',
|
||||||
|
telefono: '0984294253',
|
||||||
|
correo: 'cammmmm@test.com',
|
||||||
|
action:true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 555,
|
||||||
|
nombreComercial:'Camila Morales',
|
||||||
|
razonSocial: 'Camila Morales',
|
||||||
|
identificacion: '1720336948',
|
||||||
|
telefono: '0984294253',
|
||||||
|
correo: 'cammmmm@test.com',
|
||||||
|
action:true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 777,
|
||||||
|
nombreComercial:'Cristian Hernandez',
|
||||||
|
razonSocial: 'Cristian Hernandez',
|
||||||
|
identificacion: '1720336948',
|
||||||
|
telefono: '0984294253',
|
||||||
|
correo: 'cammmmm@test.com',
|
||||||
|
action:true,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Root
|
||||||
|
header={
|
||||||
|
<div className="p-24">
|
||||||
|
<h4>{t('CLIENTES')}</h4>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
content={
|
||||||
|
<Paper className="flex flex-col flex-auto p-24 shadow rounded-2 overflow-hidden m-10">
|
||||||
|
|
||||||
|
<div className="flex md:flex-row justify-between flex-col">
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<Typography className="mr-16 text-lg font-medium tracking-tight leading-6 truncate">
|
||||||
|
{t('Detalle de clientes')}
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<Button
|
||||||
|
size='small'
|
||||||
|
variant='contained'
|
||||||
|
color='secondary'
|
||||||
|
component={Link}
|
||||||
|
to={'/client/form'}
|
||||||
|
startIcon={
|
||||||
|
<FuseSvgIcon
|
||||||
|
className='text-48 text-white'
|
||||||
|
size={24}
|
||||||
|
color='action'
|
||||||
|
>
|
||||||
|
heroicons-outline:plus
|
||||||
|
</FuseSvgIcon>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Registrar Cliente
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="table-responsive mt-24">
|
||||||
|
<Table className='simple w-full min-w-full h-full'>
|
||||||
|
<TableHead>
|
||||||
|
<TableRow>
|
||||||
|
{columns.map((column, index) => (
|
||||||
|
<TableCell key={index}>
|
||||||
|
<Typography
|
||||||
|
color="text.secondary"
|
||||||
|
className="font-semibold text-12 whitespace-nowrap"
|
||||||
|
>
|
||||||
|
{column}
|
||||||
|
</Typography>
|
||||||
|
</TableCell>
|
||||||
|
))}
|
||||||
|
</TableRow>
|
||||||
|
</TableHead>
|
||||||
|
|
||||||
|
<TableBody>
|
||||||
|
{rows.map((row, index) => (
|
||||||
|
<TableRow key={index}>
|
||||||
|
{Object.entries(row).map(([key, value]) => {
|
||||||
|
switch (key) {
|
||||||
|
case 'action': {
|
||||||
|
return (
|
||||||
|
<TableCell
|
||||||
|
key={key}
|
||||||
|
component='th'
|
||||||
|
scope='row'
|
||||||
|
className='text-center'
|
||||||
|
>
|
||||||
|
<div className='flex items-center justify-left'>
|
||||||
|
<Typography>{value}</Typography>
|
||||||
|
<IconButton size='small' color='inherit'>
|
||||||
|
<FuseSvgIcon>
|
||||||
|
heroicons-outline:pencil-alt
|
||||||
|
</FuseSvgIcon>
|
||||||
|
</IconButton>
|
||||||
|
|
||||||
|
<ResponsiveDialog></ResponsiveDialog>
|
||||||
|
</div>
|
||||||
|
</TableCell>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return (
|
||||||
|
<TableCell key={key} component='th' scope='row'>
|
||||||
|
<Typography>{value}</Typography>
|
||||||
|
</TableCell>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})}
|
||||||
|
</TableRow>
|
||||||
|
))}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</Paper>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ListDetalleClienteRender;
|
||||||
|
|
||||||
|
|
@ -0,0 +1,73 @@
|
||||||
|
export interface Client{
|
||||||
|
nombreComercial: string;
|
||||||
|
razonSocial: string;
|
||||||
|
identificacion: string;
|
||||||
|
direccion: string;
|
||||||
|
telefono: string;
|
||||||
|
correoElectronico: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* const FormularioClienteRender = () => {
|
||||||
|
return (
|
||||||
|
<Card className="m-20 p-24">
|
||||||
|
<CardHeader title="Registro cliente" className="text-16 font-bold" />
|
||||||
|
<Divider />
|
||||||
|
|
||||||
|
<Formik
|
||||||
|
initialValues={{
|
||||||
|
nombreComercial: "",
|
||||||
|
razonSocial: "",
|
||||||
|
identificacion: "",
|
||||||
|
direccion: "",
|
||||||
|
telefono: "",
|
||||||
|
correoElectronico: "",
|
||||||
|
}}
|
||||||
|
validationSchema={validationSchema}
|
||||||
|
onSubmit={(values, { setSubmitting }) => {
|
||||||
|
// Aquí manejas la lógica de envío del formulario
|
||||||
|
console.log(values);
|
||||||
|
setSubmitting(false);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{({ isSubmitting }) => (
|
||||||
|
<Form>
|
||||||
|
<CardContent className="flex">
|
||||||
|
<Grid className="grid grid-cols-1 sm:grid-cols-6 gap-10 w-full min-w-0">
|
||||||
|
<Field
|
||||||
|
as={TextField}
|
||||||
|
className="sm:col-span-3 lg:col-span-3 mt-20"
|
||||||
|
required
|
||||||
|
label="Nombre Comercial"
|
||||||
|
id="nombreComercial"
|
||||||
|
name="nombreComercial"
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
size="small"
|
||||||
|
/>
|
||||||
|
<ErrorMessage
|
||||||
|
name="nombreComercial"
|
||||||
|
component="div"
|
||||||
|
className="text-red-500"
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Agrega el resto de los campos y sus mensajes de error aquí */}
|
||||||
|
|
||||||
|
{/* <Button
|
||||||
|
className="w-320"
|
||||||
|
variant="contained"
|
||||||
|
size="small"
|
||||||
|
color="secondary"
|
||||||
|
type="submit"
|
||||||
|
disabled={isSubmitting}
|
||||||
|
>
|
||||||
|
Guardar
|
||||||
|
</Button>
|
||||||
|
</Grid>
|
||||||
|
</CardContent>
|
||||||
|
</Form>
|
||||||
|
)}
|
||||||
|
</Formik>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
*/}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
import React from 'react'
|
||||||
|
import FormularioClienteRender from './FormularioClienteRender'
|
||||||
|
|
||||||
|
const FormularioCliente = () => {
|
||||||
|
return (
|
||||||
|
<FormularioClienteRender/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default FormularioCliente
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
import {lazy} from 'react';
|
||||||
|
|
||||||
|
const FormularioCliente = lazy(() => import('./FormularioCliente'));
|
||||||
|
|
||||||
|
const FormularioClienteConfig = {
|
||||||
|
settings: {
|
||||||
|
layout: {
|
||||||
|
config: {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
path: 'client/form',
|
||||||
|
element: <FormularioCliente/>
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FormularioClienteConfig;
|
||||||
|
|
@ -0,0 +1,188 @@
|
||||||
|
import FusePageSimple from "@fuse/core/FusePageSimple";
|
||||||
|
import {
|
||||||
|
Autocomplete,
|
||||||
|
Card,
|
||||||
|
CardActions,
|
||||||
|
CardContent,
|
||||||
|
CardHeader,
|
||||||
|
Divider,
|
||||||
|
TextField,
|
||||||
|
styled,
|
||||||
|
Button,
|
||||||
|
Grid,
|
||||||
|
} from "@mui/material";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { Formik, Form, Field, ErrorMessage } from "formik";
|
||||||
|
import * as Yup from "yup";
|
||||||
|
|
||||||
|
|
||||||
|
const FormularioClienteRender = () => {
|
||||||
|
const [datosCargados, setDatosCargados] = useState(false);
|
||||||
|
|
||||||
|
const validationSchema = Yup.object().shape({
|
||||||
|
nombreComercial: Yup.string().required('El nombre comercial es requerido'),
|
||||||
|
razonSocial: Yup.string().required('La razón social es requerida'),
|
||||||
|
identificacion: Yup.string()
|
||||||
|
.required('La cédula o RUC es requerida')
|
||||||
|
.min(10, 'La cédula debe tener 10 digitos')
|
||||||
|
.max(13, 'El RUC debe tener 13 digitos'),
|
||||||
|
direccion: Yup.string().required('La dirección es requerida'),
|
||||||
|
telefono: Yup.string()
|
||||||
|
.required('El teléfono es requerido')
|
||||||
|
.matches(/^[0-9]{10}$/, 'El teléfono debe ser un número de 10 dígitos'),
|
||||||
|
correoElectronico: Yup.string()
|
||||||
|
.required('El correo electrónico es requerido')
|
||||||
|
.email('Ingrese un correo electrónico válido'),
|
||||||
|
})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card className="m-20 p-24">
|
||||||
|
<CardHeader title="Registro cliente" className="text-16 font-bold"/>
|
||||||
|
<Divider />
|
||||||
|
|
||||||
|
<Formik
|
||||||
|
initialValues = {{
|
||||||
|
nombreComercial: "",
|
||||||
|
razonSocial: "",
|
||||||
|
identificacion: "",
|
||||||
|
direccion:"",
|
||||||
|
telefono: "",
|
||||||
|
correoElectronico: "",
|
||||||
|
}}
|
||||||
|
|
||||||
|
validationSchema={validationSchema}
|
||||||
|
onSubmit={(values, { setSubmitting }) => {
|
||||||
|
console.log(values);
|
||||||
|
setSubmitting(false);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
|
||||||
|
{({ isSubmitting, touched, errors }) => (
|
||||||
|
<Form>
|
||||||
|
<CardContent className="flex">
|
||||||
|
<Grid className="grid grid-cols-1 sm:grid-cols-6 gap-10 w-full min-w-0">
|
||||||
|
|
||||||
|
<div className="mt-20 sm:col-span-3 lg:col-span-3">
|
||||||
|
<Field
|
||||||
|
as={TextField}
|
||||||
|
label="Nombre Comercial"
|
||||||
|
name="nombreComercial"
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
size="small"
|
||||||
|
error={touched.nombreComercial && !! errors.nombreComercial}
|
||||||
|
/>
|
||||||
|
<ErrorMessage
|
||||||
|
name="nombreComercial"
|
||||||
|
component ='div'
|
||||||
|
className="text-red-500 text-md ml-12 pt-4"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-20 sm:col-span-3 lg:col-span-3">
|
||||||
|
<Field
|
||||||
|
as={TextField}
|
||||||
|
label="Razón Social"
|
||||||
|
name="razonSocial"
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
size="small"
|
||||||
|
error={touched.razonSocial && !! errors.razonSocial}
|
||||||
|
/>
|
||||||
|
<ErrorMessage
|
||||||
|
name="razonSocial"
|
||||||
|
component ='div'
|
||||||
|
className="text-red-500 text-md ml-12 pt-4"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-10 sm:col-span-3 lg:col-span-3">
|
||||||
|
<Field
|
||||||
|
as={TextField}
|
||||||
|
label="Cédula o RUC"
|
||||||
|
name="identificacion"
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
size="small"
|
||||||
|
error={touched.identificacion && !!errors.identificacion}
|
||||||
|
/>
|
||||||
|
<ErrorMessage
|
||||||
|
name="identificacion"
|
||||||
|
component="div"
|
||||||
|
className="text-red-500 text-md ml-12 pt-4"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-10 sm:col-span-3 lg:col-span-3">
|
||||||
|
<Field
|
||||||
|
as={TextField}
|
||||||
|
label="Dirección"
|
||||||
|
name="direccion"
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
size="small"
|
||||||
|
error={touched.direccion && !!errors.direccion}
|
||||||
|
/>
|
||||||
|
<ErrorMessage
|
||||||
|
name="direccion"
|
||||||
|
component="div"
|
||||||
|
className="text-red-500 text-md ml-12 pt-4"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-10 sm:col-span-3 lg:col-span-3">
|
||||||
|
<Field
|
||||||
|
as={TextField}
|
||||||
|
label="Teléfono"
|
||||||
|
name="telefono"
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
size="small"
|
||||||
|
error={touched.telefono && !!errors.telefono}
|
||||||
|
/>
|
||||||
|
<ErrorMessage
|
||||||
|
name="telefono"
|
||||||
|
component="div"
|
||||||
|
className="text-red-500 text-md ml-12 pt-4"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-10 sm:col-span-3 lg:col-span-3">
|
||||||
|
<Field
|
||||||
|
as={TextField}
|
||||||
|
label="Correo Electronico"
|
||||||
|
name="correoElectronico"
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
size="small"
|
||||||
|
error={touched.correoElectronico && !!errors.correoElectronico}
|
||||||
|
/>
|
||||||
|
<ErrorMessage
|
||||||
|
name="correoElectronico"
|
||||||
|
component="div"
|
||||||
|
className="text-red-500 text-md ml-12 pt-4"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Grid>
|
||||||
|
</CardContent>
|
||||||
|
|
||||||
|
<CardActions className="mt-15">
|
||||||
|
<Button
|
||||||
|
className="w-320"
|
||||||
|
variant="contained"
|
||||||
|
size="small"
|
||||||
|
color="secondary"
|
||||||
|
type="submit"
|
||||||
|
disabled={isSubmitting}
|
||||||
|
>
|
||||||
|
Guardar{" "}
|
||||||
|
</Button>
|
||||||
|
</CardActions>
|
||||||
|
</Form>
|
||||||
|
)}
|
||||||
|
</Formik>
|
||||||
|
</Card>
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FormularioClienteRender;
|
||||||
|
|
@ -1,15 +1,10 @@
|
||||||
import FusePageSimple from '@fuse/core/FusePageSimple';
|
import FusePageSimple from '@fuse/core/FusePageSimple';
|
||||||
import Tab from '@mui/material/Tab';
|
|
||||||
import Tabs from '@mui/material/Tabs';
|
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import Box from '@mui/material/Box';
|
|
||||||
import { styled } from '@mui/material/styles';
|
import { styled } from '@mui/material/styles';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import FuseLoading from '@fuse/core/FuseLoading';
|
import FuseLoading from '@fuse/core/FuseLoading';
|
||||||
import ProjectDashboardAppHeader from './ProjectDashboardAppHeader';
|
import ProjectDashboardAppHeader from './ProjectDashboardAppHeader';
|
||||||
import HomeTab from './tabs/home/HomeTab';
|
import HomeTab from './tabs/home/HomeTab';
|
||||||
import TeamTab from './tabs/team/TeamTab';
|
|
||||||
import BudgetTab from './tabs/budget/BudgetTab';
|
|
||||||
import { useGetProjectDashboardWidgetsQuery } from './ProjectDashboardApi';
|
import { useGetProjectDashboardWidgetsQuery } from './ProjectDashboardApi';
|
||||||
|
|
||||||
const Root = styled(FusePageSimple)(({ theme }) => ({
|
const Root = styled(FusePageSimple)(({ theme }) => ({
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
import DemoContent from '@fuse/core/DemoContent';
|
||||||
|
import FusePageSimple from '@fuse/core/FusePageSimple';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { styled } from '@mui/material/styles';
|
||||||
|
import FirmaRender from './FirmaRender';
|
||||||
|
|
||||||
|
|
||||||
|
const Root = styled(FusePageSimple)(({ theme }) => ({
|
||||||
|
'& .FusePageSimple-header': {
|
||||||
|
backgroundColor: theme.palette.background.paper,
|
||||||
|
borderBottomWidth: 1,
|
||||||
|
borderStyle: 'solid',
|
||||||
|
borderColor: theme.palette.divider
|
||||||
|
},
|
||||||
|
'& .FusePageSimple-content': {},
|
||||||
|
'& .FusePageSimple-sidebarHeader': {},
|
||||||
|
'& .FusePageSimple-sidebarContent': {}
|
||||||
|
}));
|
||||||
|
|
||||||
|
function Firma() {
|
||||||
|
const { t } = useTranslation('signature');
|
||||||
|
|
||||||
|
return(
|
||||||
|
<Root
|
||||||
|
header={
|
||||||
|
<div className='p-24'>
|
||||||
|
<h4>{t('FIRMA ELECTRONICA')}</h4>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
content={
|
||||||
|
<FirmaRender></FirmaRender>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Firma;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
import { FuseRouteConfigsType } from "@fuse/utils/FuseUtils";
|
||||||
|
import FormularioFirmaConfig from "./formularioFirma/FormularioFirmaConfig";
|
||||||
|
|
||||||
|
const firmaConfigs: FuseRouteConfigsType = [
|
||||||
|
FormularioFirmaConfig
|
||||||
|
]
|
||||||
|
|
||||||
|
export default firmaConfigs;
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
import FormularioFirma from "./formularioFirma/FormularioFirma";
|
||||||
|
|
||||||
|
const ClientRender = () => {
|
||||||
|
return (
|
||||||
|
<div className="w-full p-12 pt-16 sm:pt-24 lg:ltr:pr-0 lg:rtl:pl-0">
|
||||||
|
<FormularioFirma></FormularioFirma>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ClientRender;
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
import React from 'react'
|
||||||
|
import FormularioFirmaRender from './FormularioFirmaRender'
|
||||||
|
|
||||||
|
const FormularioFirma = () => {
|
||||||
|
return (
|
||||||
|
<FormularioFirmaRender/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default FormularioFirma
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
import {lazy} from 'react';
|
||||||
|
|
||||||
|
const FormularioFirma = lazy(() => import('./FormularioFirma'));
|
||||||
|
|
||||||
|
const FormularioClienteConfig = {
|
||||||
|
settings: {
|
||||||
|
layout: {
|
||||||
|
config: {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
path: 'signature/form',
|
||||||
|
element: <FormularioFirma/>
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FormularioClienteConfig;
|
||||||
|
|
@ -0,0 +1,200 @@
|
||||||
|
import { useState } from "react";
|
||||||
|
import { Formik, Form, Field, ErrorMessage } from "formik";
|
||||||
|
import * as Yup from "yup";
|
||||||
|
import { Card, CardActions, CardContent, CardHeader, Button, TextField } from "@mui/material";
|
||||||
|
|
||||||
|
const FormularioClienteRender = () => {
|
||||||
|
const [file, setFile] = useState(null);
|
||||||
|
|
||||||
|
const validationSchema = Yup.object().shape({
|
||||||
|
contrasena: Yup.string()
|
||||||
|
.required("La contraseña es requerida"),
|
||||||
|
/* .min(5, 'La contraseña debe tener como mínimo 8 caracteres')
|
||||||
|
.max(10, 'La contraseña debe tener como máximo 10 caracteres')
|
||||||
|
.matches(/[0-9]/, 'La contraseña requiere al menos un número')
|
||||||
|
.matches(/[a-z]/, 'La contraseña requiere al menos una letra minuscula')
|
||||||
|
.matches(/[A-Z]/, 'La contraseña requiere al menos una letra mayuscula'), */
|
||||||
|
validarContrasena: Yup.string()
|
||||||
|
.required("La verificación de la contraseña es requerida")
|
||||||
|
.oneOf([Yup.ref('contrasena'), null], 'La contraseña debe coincidir con la anterior'),
|
||||||
|
|
||||||
|
fechaCaducacion: Yup.date()
|
||||||
|
.required("La fecha de caducación es requerida")
|
||||||
|
.min(new Date(), "La fecha de caducación debe ser posterior a la fecha actual"),
|
||||||
|
|
||||||
|
archivo: Yup.mixed()
|
||||||
|
.required("El archivo es requerido")
|
||||||
|
.test("fileFormat", "Solo se permiten archivos PDF", (value) => {
|
||||||
|
if (value) {
|
||||||
|
return value.type === "application/pdf";
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleFileDrop = (event, setFieldValue) => {
|
||||||
|
event.preventDefault();
|
||||||
|
const droppedFile = event.dataTransfer.files[0];
|
||||||
|
setFile(droppedFile);
|
||||||
|
setFieldValue("archivo", droppedFile);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleFileChange = (event, setFieldValue) => {
|
||||||
|
const selectedFile = event.currentTarget.files[0];
|
||||||
|
setFile(selectedFile);
|
||||||
|
setFieldValue("archivo", selectedFile);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="p-52 ">
|
||||||
|
<h1 className="text-center">CONFIGURACIÓN DE LA FIRMA ELECTRÓNICA</h1>
|
||||||
|
<div className="flex justify-center items-center h-full">
|
||||||
|
<Card className="p-10 text-center w-2/3">
|
||||||
|
<CardHeader title="Subir Firma" className="text-16 font-bold" />
|
||||||
|
<h5>Para poder registrar su firma electrónica deberá</h5>
|
||||||
|
<h5>ingresar la siguiente información</h5>
|
||||||
|
<CardContent className="p-10">
|
||||||
|
<Formik
|
||||||
|
initialValues={{
|
||||||
|
contrasena: "",
|
||||||
|
validarContrasena:"",
|
||||||
|
fechaCaducacion: "",
|
||||||
|
archivo: "",
|
||||||
|
}}
|
||||||
|
|
||||||
|
validationSchema={validationSchema}
|
||||||
|
|
||||||
|
onSubmit={(values, { setSubmitting }) => {
|
||||||
|
console.log(values);
|
||||||
|
setSubmitting(false);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{({ isSubmitting, touched, errors, setFieldValue }) => (
|
||||||
|
<Form>
|
||||||
|
<div className="pt-10">
|
||||||
|
<Field
|
||||||
|
as={TextField}
|
||||||
|
label="Contraseña"
|
||||||
|
name="contrasena"
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
size="small"
|
||||||
|
type="password"
|
||||||
|
error={touched.contrasena && !! errors.contrasena}
|
||||||
|
/>
|
||||||
|
<ErrorMessage
|
||||||
|
name="contrasena"
|
||||||
|
component="div"
|
||||||
|
className="text-red-500 text-md ml-12 pt-4 text-left"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="pt-14">
|
||||||
|
<Field
|
||||||
|
as={TextField}
|
||||||
|
label="Verificación Contraseña"
|
||||||
|
name="validarContrasena"
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
size="small"
|
||||||
|
type="password"
|
||||||
|
error={touched.validarContrasena && errors.validarContrasena}
|
||||||
|
/>
|
||||||
|
<ErrorMessage
|
||||||
|
name="validarContrasena"
|
||||||
|
component="div"
|
||||||
|
className="text-red-500 text-md ml-12 pt-4 text-left"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="pt-24">
|
||||||
|
<Field
|
||||||
|
as={TextField}
|
||||||
|
label="Fecha de caducidad"
|
||||||
|
name="fechaCaducacion"
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
size="small"
|
||||||
|
type="date"
|
||||||
|
error={touched.fechaCaducacion && !! errors.fechaCaducacion}
|
||||||
|
InputLabelProps={{
|
||||||
|
shrink: true,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<ErrorMessage
|
||||||
|
name="fechaCaducacion"
|
||||||
|
component="div"
|
||||||
|
className="text-red-500 text-md ml-12 pt-4 text-left"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="pt-20" onDrop={(event) => handleFileDrop(event, setFieldValue)} onDragOver={(event) => event.preventDefault()}>
|
||||||
|
<div className="w-full">
|
||||||
|
<label htmlFor="archivo" className="flex flex-col items-center justify-center w-full h-96 border-2 border-gray-300 border-dashed rounded-lg cursor-pointer bg-gray-50 dark:hover:bg-gray-800 dark:bg-gray-700 hover:bg-gray-100 dark:border-gray-600 dark:hover:border-gray-500">
|
||||||
|
<input
|
||||||
|
id="archivo"
|
||||||
|
name="archivo"
|
||||||
|
type="file"
|
||||||
|
accept=".pdf"
|
||||||
|
className="hidden"
|
||||||
|
onChange={(event) => handleFileChange(event, setFieldValue)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div className="flex flex-col items-center justify-center pt-5 pb-6 h-96">
|
||||||
|
<svg
|
||||||
|
className="w-20 h-15 mb-1 text-gray-500 dark:text-gray-400"
|
||||||
|
aria-hidden="true"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 20 16"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
strokeWidth="2"
|
||||||
|
d="M13 13h3a3 3 0 0 0 0-6h-.025A5.56 5.56 0 0 0 16 6.5 5.5 5.5 0 0 0 5.207 5.021C5.137 5.017 5.071 5 5 5a4 4 0 0 0 0 8h2.167M10 15V6m0 0L8 8m2-2 2 2"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
<p className="mb-2 text-sm text-gray-500 dark:text-gray-400 pt-8">
|
||||||
|
<span className="font-semibold">Haga clic para cargar o arrastre y suelte </span>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p className="text-s text-gray-500 dark:text-gray-400" id="file-name-display">
|
||||||
|
{file ? file.name : "Solo se permiten archivos .pdf"}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ErrorMessage
|
||||||
|
name="archivo"
|
||||||
|
component="div"
|
||||||
|
className="text-red-500 text-md ml-12 pt-4 text-left"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<CardActions className="mt-15 justify-center p-8">
|
||||||
|
<Button
|
||||||
|
className="w-full sm:w-320"
|
||||||
|
variant="contained"
|
||||||
|
size="small"
|
||||||
|
color="secondary"
|
||||||
|
type="submit"
|
||||||
|
disabled={isSubmitting}
|
||||||
|
>
|
||||||
|
{isSubmitting ? "Subiendo..." : "Subir"}
|
||||||
|
</Button>
|
||||||
|
</CardActions>
|
||||||
|
</Form>
|
||||||
|
)}
|
||||||
|
</Formik>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FormularioClienteRender;
|
||||||
|
|
@ -9,4 +9,4 @@ const invoiceConfigs: FuseRouteConfigsType = [
|
||||||
GenerateInvoiceConfig
|
GenerateInvoiceConfig
|
||||||
]
|
]
|
||||||
|
|
||||||
export default invoiceConfigs;
|
export default invoiceConfigs;
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,7 @@
|
||||||
import React from 'react'
|
import GenerateInvoiceRender from './GenerateInvoiceRender';
|
||||||
import GenerateInvoiceRender from './GenerateInvoiceRender'
|
|
||||||
|
|
||||||
const GenerateInvoice = () => {
|
function GenerateInvoice() {
|
||||||
return (
|
return <GenerateInvoiceRender />;
|
||||||
<GenerateInvoiceRender/>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default GenerateInvoice
|
export default GenerateInvoice;
|
||||||
|
|
|
||||||
|
|
@ -1,103 +1,33 @@
|
||||||
import FusePageCarded from "@fuse/core/FusePageCarded";
|
import { Card, CardActions, CardContent, CardHeader, Divider, Button } from '@mui/material';
|
||||||
import FusePageSimple from "@fuse/core/FusePageSimple";
|
import DataInvoice from './components/dataInvoice/DataInvoice';
|
||||||
import {
|
import DataClient from './components/dataClient/DataClient';
|
||||||
Autocomplete,
|
import DataTransmitter from './components/dataTransmitter/DataTransmitter';
|
||||||
Card,
|
|
||||||
CardActions,
|
|
||||||
CardContent,
|
|
||||||
CardHeader,
|
|
||||||
Divider,
|
|
||||||
TextField,
|
|
||||||
styled,
|
|
||||||
Button,
|
|
||||||
Grid,
|
|
||||||
Box,
|
|
||||||
} from "@mui/material";
|
|
||||||
import { Controller, useFormContext } from "react-hook-form";
|
|
||||||
import DataInvoice from "./components/dataInvoice/DataInvoice";
|
|
||||||
import DataClient from "./components/dataClient/DataClient";
|
|
||||||
|
|
||||||
const Root = styled(FusePageSimple)(({ theme }) => ({
|
function GenerateInvoiceRender() {
|
||||||
"& .FusePageSimple-header": {
|
return (
|
||||||
backgroundColor: theme.palette.background.paper,
|
<Card className=" m-20 p-12">
|
||||||
boxShadow: `inset 0 0 0 1px ${theme.palette.divider}`,
|
<CardHeader
|
||||||
},
|
title="Crear Factura de venta"
|
||||||
}));
|
className="text-16 font-bold "
|
||||||
|
/>
|
||||||
const GenerateInvoiceRender = () => {
|
<Divider />
|
||||||
return (
|
<CardContent>
|
||||||
<Card className=" m-20 p-24">
|
<DataTransmitter />
|
||||||
<CardHeader
|
<DataClient />
|
||||||
title="Crear Factura de venta"
|
<DataInvoice />
|
||||||
className="text-16 font-bold "
|
</CardContent>
|
||||||
/>
|
<CardActions>
|
||||||
<Divider />
|
<Button
|
||||||
<DataInvoice />
|
className="w-320 "
|
||||||
<DataClient />
|
variant="contained"
|
||||||
<CardContent>
|
size="small"
|
||||||
<Grid container spacing={2}>
|
color="primary"
|
||||||
<Grid item xs={12} md={6}>
|
>
|
||||||
<TextField
|
Guardar{' '}
|
||||||
className="mt-8 mb-16"
|
</Button>
|
||||||
required
|
</CardActions>
|
||||||
label="Name"
|
</Card>
|
||||||
autoFocus
|
);
|
||||||
id="name"
|
}
|
||||||
variant="outlined"
|
|
||||||
fullWidth
|
|
||||||
/* error={!!errors.name}
|
|
||||||
helperText={errors?.name?.message as string} */
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12} md={6}>
|
|
||||||
<TextField
|
|
||||||
className="mt-8 mb-16"
|
|
||||||
id="description"
|
|
||||||
label="Description"
|
|
||||||
type="text"
|
|
||||||
multiline
|
|
||||||
rows={5}
|
|
||||||
variant="outlined"
|
|
||||||
fullWidth
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12} md={6}>
|
|
||||||
<Autocomplete
|
|
||||||
className="mt-8 mb-16"
|
|
||||||
multiple
|
|
||||||
freeSolo
|
|
||||||
options={[]}
|
|
||||||
/* value={value }
|
|
||||||
onChange={(event, newValue) => {
|
|
||||||
onChange(newValue);
|
|
||||||
}} */
|
|
||||||
renderInput={(params) => (
|
|
||||||
<TextField
|
|
||||||
{...params}
|
|
||||||
placeholder="Select multiple categories"
|
|
||||||
label="Categories"
|
|
||||||
variant="outlined"
|
|
||||||
InputLabelProps={{
|
|
||||||
shrink: true,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</CardContent>
|
|
||||||
<CardActions>
|
|
||||||
<Button
|
|
||||||
className="w-320 "
|
|
||||||
variant="contained"
|
|
||||||
size="small"
|
|
||||||
color="primary"
|
|
||||||
>
|
|
||||||
Guardar{" "}
|
|
||||||
</Button>
|
|
||||||
</CardActions>
|
|
||||||
</Card>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default GenerateInvoiceRender;
|
export default GenerateInvoiceRender;
|
||||||
|
|
|
||||||
|
|
@ -1,69 +1,42 @@
|
||||||
import {
|
import { useState } from 'react';
|
||||||
Autocomplete,
|
import DataClientRender from './DataClientRender';
|
||||||
Box,
|
import { Client } from './DataClientInterfaz';
|
||||||
Divider,
|
|
||||||
Grid,
|
|
||||||
TextField,
|
|
||||||
Typography,
|
|
||||||
} from "@mui/material";
|
|
||||||
|
|
||||||
const DataClient = () => {
|
const clientes = [
|
||||||
return (
|
{
|
||||||
<Box className="mt-10 p-20 shadow-2 rounded-8">
|
id: 1,
|
||||||
<Typography component="h3" className="mb-7">
|
nombreComercial: 'Andres Alvarez',
|
||||||
Datos cliente
|
razonSocial: 'Andres Alvarez',
|
||||||
</Typography>
|
identificacion: '1721529788',
|
||||||
<Divider className="border-1 mb-10" />
|
direccion: 'Calle oe',
|
||||||
<Grid container spacing={2}>
|
telefono: '0988545102',
|
||||||
<Grid item xs={12} md={12}>
|
correo: 'andres@test.com'
|
||||||
<Autocomplete
|
},
|
||||||
className="mt-8 mb-16"
|
{
|
||||||
multiple
|
id: 2,
|
||||||
freeSolo
|
nombreComercial: 'Paul Ruales',
|
||||||
options={[]}
|
razonSocial: 'Paul Ruales',
|
||||||
/* value={value }
|
identificacion: '1721524123',
|
||||||
onChange={(event, newValue) => {
|
direccion: 'Calle lomisima',
|
||||||
onChange(newValue);
|
telefono: '0988544772',
|
||||||
}} */
|
correo: 'poul@test.com'
|
||||||
renderInput={(params) => (
|
}
|
||||||
<TextField
|
];
|
||||||
{...params}
|
function DataClient() {
|
||||||
placeholder="Busque el cliente"
|
const [clients, setClients] = useState<Client[]>(clientes);
|
||||||
label="Cliente"
|
const [selectClient, setSelectClient] = useState<Client | null>(null);
|
||||||
variant="outlined"
|
|
||||||
InputLabelProps={{
|
|
||||||
shrink: true,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
<Grid item md={12} >
|
|
||||||
|
|
||||||
<Divider/>
|
const handleSelectClient = (value:Client) => {
|
||||||
</Grid>
|
setSelectClient(value)
|
||||||
<Grid item md={4} xs={12}>
|
if(!clients.includes(value)) setClients([...clients, value])
|
||||||
<b>Razón Social:</b> Jonathan Andres Alvarez Flores
|
};
|
||||||
</Grid>
|
return (
|
||||||
<Grid item md={4} xs={12}>
|
<DataClientRender
|
||||||
<b>Nombre Comercial:</b> Jonathan Andres Alvarez Flores
|
client={clients}
|
||||||
</Grid>
|
handleSelectClient={handleSelectClient}
|
||||||
<Grid item md={4} xs={12}>
|
selectClient={selectClient}
|
||||||
<b>Ruc:</b> 17215785512001
|
/>
|
||||||
</Grid>
|
);
|
||||||
|
}
|
||||||
<Grid item md={4} xs={12}>
|
|
||||||
<b>Dirección:</b> Calle Oe11g y s32
|
|
||||||
</Grid>
|
|
||||||
<Grid item md={4} xs={12}>
|
|
||||||
<b>Teléfono:</b> 0988545211
|
|
||||||
</Grid>
|
|
||||||
<Grid item md={4} xs={12}>
|
|
||||||
<b>Correo:</b> admin@qsoftec.com
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default DataClient;
|
export default DataClient;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
export interface Client {
|
||||||
|
id: number;
|
||||||
|
nombreComercial: string;
|
||||||
|
razonSocial: string;
|
||||||
|
identificacion: string;
|
||||||
|
direccion: string;
|
||||||
|
telefono: string;
|
||||||
|
correo: string;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,163 @@
|
||||||
|
import { useState } from 'react';
|
||||||
|
import FuseSvgIcon from '@fuse/core/FuseSvgIcon';
|
||||||
|
import { Autocomplete, Box, Divider, Grid, TextField, Typography, Button } from '@mui/material';
|
||||||
|
import AddClient from './components/addClient/AddClient';
|
||||||
|
import { Client } from './DataClientInterfaz';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
client: Client[];
|
||||||
|
handleSelectClient: (value: Client) => void;
|
||||||
|
selectClient: Client;
|
||||||
|
}
|
||||||
|
function DataClientRender({ client, handleSelectClient, selectClient }: Props) {
|
||||||
|
const [openDialog, setOpenDialog] = useState<boolean>(false);
|
||||||
|
return (
|
||||||
|
<Box className="mt-10 p-20 shadow-2 rounded-8">
|
||||||
|
<AddClient
|
||||||
|
open={openDialog}
|
||||||
|
setOpen={setOpenDialog}
|
||||||
|
handleSelectClient={handleSelectClient}
|
||||||
|
/>
|
||||||
|
<Grid
|
||||||
|
container
|
||||||
|
spacing={2}
|
||||||
|
>
|
||||||
|
<Grid
|
||||||
|
item
|
||||||
|
xs={12}
|
||||||
|
md={10}
|
||||||
|
>
|
||||||
|
<Typography
|
||||||
|
component="h3"
|
||||||
|
className="mb-7 text-16"
|
||||||
|
>
|
||||||
|
Datos cliente
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid
|
||||||
|
item
|
||||||
|
xs={12}
|
||||||
|
md={2}
|
||||||
|
className="flex justify-end"
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
color="primary"
|
||||||
|
variant="outlined"
|
||||||
|
className="rounded-6"
|
||||||
|
size="small"
|
||||||
|
onClick={() => setOpenDialog(true)}
|
||||||
|
startIcon={
|
||||||
|
<FuseSvgIcon
|
||||||
|
className="text-48"
|
||||||
|
size={24}
|
||||||
|
color="action"
|
||||||
|
>
|
||||||
|
heroicons-outline:plus
|
||||||
|
</FuseSvgIcon>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Agregar{' '}
|
||||||
|
</Button>
|
||||||
|
</Grid>
|
||||||
|
<Grid
|
||||||
|
item
|
||||||
|
xs={12}
|
||||||
|
>
|
||||||
|
<Divider className="border-1 mb-10" />
|
||||||
|
</Grid>
|
||||||
|
<Grid
|
||||||
|
item
|
||||||
|
xs={12}
|
||||||
|
md={12}
|
||||||
|
>
|
||||||
|
<Autocomplete
|
||||||
|
className="mt-8 mb-16"
|
||||||
|
options={client}
|
||||||
|
getOptionLabel={(option) => option.razonSocial}
|
||||||
|
noOptionsText="No se encontro un resultado"
|
||||||
|
size="small"
|
||||||
|
value={selectClient}
|
||||||
|
onChange={(event, newValue) => {
|
||||||
|
handleSelectClient(newValue);
|
||||||
|
}}
|
||||||
|
renderInput={(params) => (
|
||||||
|
<TextField
|
||||||
|
{...params}
|
||||||
|
placeholder="Busque el cliente"
|
||||||
|
label="Cliente"
|
||||||
|
variant="outlined"
|
||||||
|
InputLabelProps={{
|
||||||
|
shrink: true
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
<Grid
|
||||||
|
item
|
||||||
|
md={12}
|
||||||
|
>
|
||||||
|
<Divider />
|
||||||
|
</Grid>
|
||||||
|
{selectClient ? (
|
||||||
|
<>
|
||||||
|
<Grid
|
||||||
|
item
|
||||||
|
md={4}
|
||||||
|
xs={12}
|
||||||
|
>
|
||||||
|
<b>Razón Social:</b> {selectClient.razonSocial}
|
||||||
|
</Grid>
|
||||||
|
<Grid
|
||||||
|
item
|
||||||
|
md={4}
|
||||||
|
xs={12}
|
||||||
|
>
|
||||||
|
<b>Nombre Comercial:</b> {selectClient.nombreComercial}
|
||||||
|
</Grid>
|
||||||
|
<Grid
|
||||||
|
item
|
||||||
|
md={4}
|
||||||
|
xs={12}
|
||||||
|
>
|
||||||
|
<b>Ruc:</b> {selectClient.identificacion}
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<Grid
|
||||||
|
item
|
||||||
|
md={4}
|
||||||
|
xs={12}
|
||||||
|
>
|
||||||
|
<b>Dirección:</b> {selectClient.direccion}
|
||||||
|
</Grid>
|
||||||
|
<Grid
|
||||||
|
item
|
||||||
|
md={4}
|
||||||
|
xs={12}
|
||||||
|
>
|
||||||
|
<b>Teléfono:</b> {selectClient.telefono}
|
||||||
|
</Grid>
|
||||||
|
<Grid
|
||||||
|
item
|
||||||
|
md={4}
|
||||||
|
xs={12}
|
||||||
|
>
|
||||||
|
<b>Correo:</b> {selectClient.correo}
|
||||||
|
</Grid>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<Box className="flex justify-center w-full mt-20">
|
||||||
|
<Typography
|
||||||
|
variant="subtitle2"
|
||||||
|
gutterBottom
|
||||||
|
>
|
||||||
|
Seleccione o agrege el cliente
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</Grid>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DataClientRender;
|
||||||
|
|
@ -0,0 +1,65 @@
|
||||||
|
import { useFormik } from 'formik';
|
||||||
|
import * as Yup from 'yup';
|
||||||
|
import { Client } from '../../DataClientInterfaz';
|
||||||
|
import AddClientRender from './AddClientRender';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
open: boolean;
|
||||||
|
setOpen: (open: boolean) => void;
|
||||||
|
handleSelectClient: (value: Client) => void;
|
||||||
|
}
|
||||||
|
function AddClient({ open, setOpen, handleSelectClient }: Props) {
|
||||||
|
const formik = useFormik<Client>({
|
||||||
|
initialValues: {
|
||||||
|
id: Math.floor(Math.random() * 100),
|
||||||
|
nombreComercial: '',
|
||||||
|
razonSocial: '',
|
||||||
|
identificacion: '',
|
||||||
|
direccion: '',
|
||||||
|
telefono: '',
|
||||||
|
correo: ''
|
||||||
|
},
|
||||||
|
|
||||||
|
validationSchema: Yup.object({
|
||||||
|
nombreComercial: Yup.string().required('El nombre comercial es requerido'),
|
||||||
|
razonSocial: Yup.string().required('La razón social es requerida'),
|
||||||
|
identificacion: Yup.string()
|
||||||
|
.required('La cédula o RUC es requerida')
|
||||||
|
.min(10, 'La cédula debe tener 10 digitos')
|
||||||
|
.max(13, 'El RUC debe tener 13 digitos'),
|
||||||
|
direccion: Yup.string().required('La dirección es requerida'),
|
||||||
|
telefono: Yup.string()
|
||||||
|
.required('El teléfono es requerido')
|
||||||
|
.matches(/^[0-9]{10}$/, 'El teléfono debe ser un número de 10 dígitos'),
|
||||||
|
correo: Yup.string()
|
||||||
|
.required('El correo electrónico es requerido')
|
||||||
|
.email('Ingrese un correo electrónico válido'),
|
||||||
|
}),
|
||||||
|
onSubmit: (value) => {
|
||||||
|
handleSaveClient(value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleOnChange = (event: { target: HTMLInputElement }) => {
|
||||||
|
const { name, value } = event.target;
|
||||||
|
formik.setFieldValue(name, value);
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: Guardar cliente en la base de datos y seleccionar
|
||||||
|
const handleSaveClient = (value: Client) => {
|
||||||
|
handleSelectClient(value);
|
||||||
|
formik.resetForm();
|
||||||
|
setOpen(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AddClientRender
|
||||||
|
open={open}
|
||||||
|
setOpen={setOpen}
|
||||||
|
formik={formik}
|
||||||
|
handleOnChange={handleOnChange}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AddClient;
|
||||||
|
|
@ -0,0 +1,177 @@
|
||||||
|
import { DialogActions, DialogContent, DialogTitle, Button, Grid, TextField, Dialog } from '@mui/material';
|
||||||
|
import { FormikProps } from 'formik';
|
||||||
|
import { Client } from '../../DataClientInterfaz';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
open: boolean;
|
||||||
|
setOpen: (open: boolean) => void;
|
||||||
|
formik: FormikProps<Client>;
|
||||||
|
handleOnChange: (event) => void;
|
||||||
|
}
|
||||||
|
function AddClientRender({ open, setOpen, formik, handleOnChange }: Props) {
|
||||||
|
return (
|
||||||
|
<Dialog
|
||||||
|
open={open}
|
||||||
|
scroll="body"
|
||||||
|
fullWidth
|
||||||
|
maxWidth="md"
|
||||||
|
>
|
||||||
|
<DialogTitle id="alert-dialog-title">Agregar Cliente</DialogTitle>
|
||||||
|
<DialogContent dividers>
|
||||||
|
<Grid
|
||||||
|
container
|
||||||
|
spacing={2}
|
||||||
|
>
|
||||||
|
<Grid
|
||||||
|
item
|
||||||
|
md={6}
|
||||||
|
xs={12}
|
||||||
|
>
|
||||||
|
<TextField
|
||||||
|
size="small"
|
||||||
|
label="Nombre Comercial"
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
name="nombreComercial"
|
||||||
|
value={formik.values.nombreComercial || ''}
|
||||||
|
onChange={handleOnChange}
|
||||||
|
onBlur={formik.handleBlur}
|
||||||
|
error={!!(formik.errors.nombreComercial && formik.touched.nombreComercial)}
|
||||||
|
helperText={
|
||||||
|
formik.errors.nombreComercial && formik.touched.nombreComercial
|
||||||
|
? formik.errors.nombreComercial
|
||||||
|
: false
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
<Grid
|
||||||
|
item
|
||||||
|
md={6}
|
||||||
|
xs={12}
|
||||||
|
>
|
||||||
|
<TextField
|
||||||
|
size="small"
|
||||||
|
label="Razón Social"
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
name="razonSocial"
|
||||||
|
value={formik.values.razonSocial || ''}
|
||||||
|
onChange={handleOnChange}
|
||||||
|
onBlur={formik.handleBlur}
|
||||||
|
error={!!(formik.errors.razonSocial && formik.touched.razonSocial)}
|
||||||
|
helperText={
|
||||||
|
formik.errors.razonSocial && formik.touched.razonSocial
|
||||||
|
? formik.errors.razonSocial
|
||||||
|
: false
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
<Grid
|
||||||
|
item
|
||||||
|
md={6}
|
||||||
|
xs={12}
|
||||||
|
>
|
||||||
|
<TextField
|
||||||
|
size="small"
|
||||||
|
label="Cédula o RUC"
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
name="identificacion"
|
||||||
|
value={formik.values.identificacion || ''}
|
||||||
|
onChange={handleOnChange}
|
||||||
|
onBlur={formik.handleBlur}
|
||||||
|
error={!!(formik.errors.identificacion && formik.touched.identificacion)}
|
||||||
|
helperText={
|
||||||
|
formik.errors.identificacion && formik.touched.identificacion
|
||||||
|
? formik.errors.identificacion
|
||||||
|
: false
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
<Grid
|
||||||
|
item
|
||||||
|
md={6}
|
||||||
|
xs={12}
|
||||||
|
>
|
||||||
|
<TextField
|
||||||
|
size="small"
|
||||||
|
label="Dirección"
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
name="direccion"
|
||||||
|
value={formik.values.direccion || ''}
|
||||||
|
onChange={handleOnChange}
|
||||||
|
onBlur={formik.handleBlur}
|
||||||
|
error={!!(formik.errors.direccion && formik.touched.direccion)}
|
||||||
|
helperText={
|
||||||
|
formik.errors.direccion && formik.touched.direccion ? formik.errors.direccion : false
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
<Grid
|
||||||
|
item
|
||||||
|
md={6}
|
||||||
|
xs={12}
|
||||||
|
>
|
||||||
|
<TextField
|
||||||
|
size="small"
|
||||||
|
label="Teléfono"
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
name="telefono"
|
||||||
|
value={formik.values.telefono || ''}
|
||||||
|
onChange={handleOnChange}
|
||||||
|
onBlur={formik.handleBlur}
|
||||||
|
error={!!(formik.errors.telefono && formik.touched.telefono)}
|
||||||
|
helperText={
|
||||||
|
formik.errors.telefono && formik.touched.telefono ? formik.errors.telefono : false
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
<Grid
|
||||||
|
item
|
||||||
|
md={6}
|
||||||
|
xs={12}
|
||||||
|
>
|
||||||
|
<TextField
|
||||||
|
size="small"
|
||||||
|
label="Correo electrónico"
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
name="correo"
|
||||||
|
value={formik.values.correo || ''}
|
||||||
|
onChange={handleOnChange}
|
||||||
|
onBlur={formik.handleBlur}
|
||||||
|
error={!!(formik.errors.correo && formik.touched.correo)}
|
||||||
|
helperText={formik.errors.correo && formik.touched.correo ? formik.errors.correo : false}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions className="pr-24">
|
||||||
|
<Button
|
||||||
|
onClick={() => {
|
||||||
|
formik.resetForm();
|
||||||
|
setOpen(false);
|
||||||
|
}}
|
||||||
|
color="primary"
|
||||||
|
variant="contained"
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
Cancelar
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
onClick={formik.submitForm}
|
||||||
|
color="primary"
|
||||||
|
autoFocus
|
||||||
|
variant="contained"
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
Aceptar
|
||||||
|
</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AddClientRender;
|
||||||
|
|
@ -1,35 +1,28 @@
|
||||||
import { Box, Grid, Typography, Divider } from "@mui/material";
|
import { useState } from 'react';
|
||||||
|
import DataInvoiceRender from './DataInvoiceRender';
|
||||||
|
import { ItemInvoice } from './DataInvoiceInterface';
|
||||||
|
|
||||||
const DataInvoice = () => {
|
function DataInvoice() {
|
||||||
return (
|
const [items, setItems] = useState<Array<ItemInvoice>>();
|
||||||
<Box className="mt-10 p-20 shadow-2 rounded-8">
|
|
||||||
<Typography component="h3" className="mb-7">
|
|
||||||
Datos emisor
|
|
||||||
</Typography>
|
|
||||||
<Divider className="border-1 mb-10" />
|
|
||||||
<Grid container spacing={2}>
|
|
||||||
<Grid item md={6} xs={12}>
|
|
||||||
<b>Razón Social:</b> Jonathan Andres Alvarez Flores
|
|
||||||
</Grid>
|
|
||||||
<Grid item md={6} xs={12}>
|
|
||||||
<b>Nombre Comercial:</b> Jonathan Andres Alvarez Flores
|
|
||||||
</Grid>
|
|
||||||
<Grid item md={6} xs={12}>
|
|
||||||
<b>Ruc:</b> 17215785512001
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
<Grid item md={6} xs={12}>
|
const handleAddItem = () => {
|
||||||
<b>Dirección:</b> Calle Oe11g y s32
|
const newItems: ItemInvoice = {
|
||||||
</Grid>
|
cod: '',
|
||||||
<Grid item md={6} xs={12}>
|
description: '',
|
||||||
<b>Contribuyente Especial:</b> NO
|
amount: 0,
|
||||||
</Grid>
|
iva: true,
|
||||||
<Grid item md={6} xs={12}>
|
unitValue: 1,
|
||||||
<b>Obligado Contabilidad:</b> NO
|
total: 0
|
||||||
</Grid>
|
};
|
||||||
</Grid>
|
setItems([...items, newItems]);
|
||||||
</Box>
|
};
|
||||||
);
|
|
||||||
};
|
return (
|
||||||
|
<DataInvoiceRender
|
||||||
|
handleAddItem={handleAddItem}
|
||||||
|
items={items}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export default DataInvoice;
|
export default DataInvoice;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
export interface Headers {
|
||||||
|
id: number;
|
||||||
|
name: string | Element;
|
||||||
|
style?: string | number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ItemInvoice {
|
||||||
|
cod: string;
|
||||||
|
description: string;
|
||||||
|
amount: number;
|
||||||
|
unitValue: number;
|
||||||
|
iva: boolean;
|
||||||
|
total: number;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,213 @@
|
||||||
|
import { Box, Grid, Typography, Divider, Button, TextField } from '@mui/material';
|
||||||
|
import FuseSvgIcon from '@fuse/core/FuseSvgIcon';
|
||||||
|
import TableInvoice from './components/tableInvoice/TableInvoice';
|
||||||
|
import { ItemInvoice } from './DataInvoiceInterface';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
handleAddItem: () => void;
|
||||||
|
items: ItemInvoice[];
|
||||||
|
}
|
||||||
|
function DataInvoiceRender({ handleAddItem, items }: Props) {
|
||||||
|
return (
|
||||||
|
<Box className="mt-10 p-20 shadow-2 rounded-8">
|
||||||
|
<Grid
|
||||||
|
container
|
||||||
|
spacing={2}
|
||||||
|
>
|
||||||
|
<Grid
|
||||||
|
item
|
||||||
|
xs={12}
|
||||||
|
md={10}
|
||||||
|
>
|
||||||
|
<Typography
|
||||||
|
component="h3"
|
||||||
|
className="mb-7 text-16"
|
||||||
|
>
|
||||||
|
Datos factura
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid
|
||||||
|
item
|
||||||
|
xs={12}
|
||||||
|
md={2}
|
||||||
|
className="flex justify-end"
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
color="primary"
|
||||||
|
variant="outlined"
|
||||||
|
className="rounded-6"
|
||||||
|
size="small"
|
||||||
|
onClick={handleAddItem}
|
||||||
|
startIcon={
|
||||||
|
<FuseSvgIcon
|
||||||
|
className="text-48"
|
||||||
|
size={24}
|
||||||
|
color="action"
|
||||||
|
>
|
||||||
|
heroicons-outline:plus
|
||||||
|
</FuseSvgIcon>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Agregar{' '}
|
||||||
|
</Button>
|
||||||
|
</Grid>
|
||||||
|
<Grid
|
||||||
|
item
|
||||||
|
xs={12}
|
||||||
|
>
|
||||||
|
<Divider className="border-1" />
|
||||||
|
</Grid>
|
||||||
|
<Grid
|
||||||
|
item
|
||||||
|
xs={12}
|
||||||
|
md={2}
|
||||||
|
>
|
||||||
|
<TextField
|
||||||
|
label="Serial"
|
||||||
|
size="small"
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
InputLabelProps={{
|
||||||
|
shrink: true
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
<Grid
|
||||||
|
item
|
||||||
|
xs={12}
|
||||||
|
md={2}
|
||||||
|
>
|
||||||
|
<TextField
|
||||||
|
label="Fecha factura"
|
||||||
|
size="small"
|
||||||
|
variant="outlined"
|
||||||
|
type="date"
|
||||||
|
fullWidth
|
||||||
|
InputLabelProps={{
|
||||||
|
shrink: true
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
<Grid
|
||||||
|
item
|
||||||
|
xs={12}
|
||||||
|
md={2}
|
||||||
|
>
|
||||||
|
<TextField
|
||||||
|
label="Fecha creada"
|
||||||
|
size="small"
|
||||||
|
variant="outlined"
|
||||||
|
type="date"
|
||||||
|
fullWidth
|
||||||
|
InputLabelProps={{
|
||||||
|
shrink: true
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
<Grid
|
||||||
|
container
|
||||||
|
spacing={2}
|
||||||
|
>
|
||||||
|
<Grid
|
||||||
|
item
|
||||||
|
xs={12}
|
||||||
|
>
|
||||||
|
<TableInvoice />
|
||||||
|
</Grid>
|
||||||
|
<Grid
|
||||||
|
item
|
||||||
|
xs={7}
|
||||||
|
md={9}
|
||||||
|
/>
|
||||||
|
<Grid
|
||||||
|
item
|
||||||
|
xs={2}
|
||||||
|
md={2}
|
||||||
|
>
|
||||||
|
<Typography
|
||||||
|
variant="subtitle2"
|
||||||
|
gutterBottom
|
||||||
|
>
|
||||||
|
Sub Total:
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid
|
||||||
|
item
|
||||||
|
xs={3}
|
||||||
|
md={1}
|
||||||
|
className="item"
|
||||||
|
>
|
||||||
|
<Typography
|
||||||
|
variant="subtitle2"
|
||||||
|
gutterBottom
|
||||||
|
>
|
||||||
|
$10
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid
|
||||||
|
item
|
||||||
|
xs={7}
|
||||||
|
md={9}
|
||||||
|
/>
|
||||||
|
<Grid
|
||||||
|
item
|
||||||
|
xs={2}
|
||||||
|
md={2}
|
||||||
|
>
|
||||||
|
<Typography
|
||||||
|
variant="subtitle2"
|
||||||
|
gutterBottom
|
||||||
|
>
|
||||||
|
Iva 12%:
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid
|
||||||
|
item
|
||||||
|
xs={3}
|
||||||
|
md={1}
|
||||||
|
className="item"
|
||||||
|
>
|
||||||
|
<Typography
|
||||||
|
variant="subtitle2"
|
||||||
|
gutterBottom
|
||||||
|
>
|
||||||
|
$5
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid
|
||||||
|
item
|
||||||
|
xs={7}
|
||||||
|
md={9}
|
||||||
|
/>
|
||||||
|
<Grid
|
||||||
|
item
|
||||||
|
xs={2}
|
||||||
|
md={2}
|
||||||
|
>
|
||||||
|
<Typography
|
||||||
|
variant="subtitle2"
|
||||||
|
gutterBottom
|
||||||
|
>
|
||||||
|
Total:
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid
|
||||||
|
item
|
||||||
|
xs={3}
|
||||||
|
md={1}
|
||||||
|
className="item"
|
||||||
|
>
|
||||||
|
<Typography
|
||||||
|
variant="subtitle2"
|
||||||
|
gutterBottom
|
||||||
|
>
|
||||||
|
$15
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DataInvoiceRender;
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
import { Headers } from '../../DataInvoiceInterface';
|
||||||
|
import TableInvoiceRender from './TableInvoiceRender';
|
||||||
|
|
||||||
|
function TableInvoice() {
|
||||||
|
const headers: Array<Headers> = [
|
||||||
|
{ id: 1, name: 'Código', style: 100 },
|
||||||
|
{ id: 2, name: 'Descripción', style: 400 },
|
||||||
|
{ id: 3, name: 'Cantidad', style: 130 },
|
||||||
|
{ id: 4, name: 'Valor unitario', style: 130 },
|
||||||
|
{ id: 5, name: 'Iva', style: 10 },
|
||||||
|
{ id: 6, name: 'Total', style: 130 },
|
||||||
|
{ id: 7, name: 'Acción', style: 10 }
|
||||||
|
];
|
||||||
|
return <TableInvoiceRender headers={headers} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default TableInvoice;
|
||||||
|
|
@ -0,0 +1,141 @@
|
||||||
|
import {
|
||||||
|
Table,
|
||||||
|
TableCell,
|
||||||
|
TableHead,
|
||||||
|
Typography,
|
||||||
|
TableRow,
|
||||||
|
TableBody,
|
||||||
|
TextField,
|
||||||
|
Autocomplete,
|
||||||
|
Checkbox
|
||||||
|
} from '@mui/material';
|
||||||
|
import IconButton from '@mui/material/IconButton';
|
||||||
|
import FuseSvgIcon from '@fuse/core/FuseSvgIcon';
|
||||||
|
import { Headers } from '../../DataInvoiceInterface';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
headers: Headers[];
|
||||||
|
}
|
||||||
|
function TableInvoiceRender({ headers }: Props) {
|
||||||
|
return (
|
||||||
|
<div className="table-responsive mt-24">
|
||||||
|
<Table
|
||||||
|
sx={{ minWidth: 650 }}
|
||||||
|
className="simple"
|
||||||
|
>
|
||||||
|
<TableHead>
|
||||||
|
<TableRow>
|
||||||
|
{headers.map((column) => (
|
||||||
|
<TableCell
|
||||||
|
key={column.id}
|
||||||
|
style={column.style ? { width: column.style } : {}}
|
||||||
|
>
|
||||||
|
<Typography
|
||||||
|
color="text.secondary"
|
||||||
|
className="font-semibold text-14 whitespace-nowrap"
|
||||||
|
>
|
||||||
|
{column.name}
|
||||||
|
</Typography>
|
||||||
|
</TableCell>
|
||||||
|
))}
|
||||||
|
{/* <TableCell style={{ width: 5 }}>
|
||||||
|
<IconButton>
|
||||||
|
<FuseSvgIcon>heroicons-outline:plus</FuseSvgIcon>
|
||||||
|
</IconButton>
|
||||||
|
</TableCell> */}
|
||||||
|
</TableRow>
|
||||||
|
</TableHead>
|
||||||
|
<TableBody>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell
|
||||||
|
component="th"
|
||||||
|
scope="row"
|
||||||
|
>
|
||||||
|
<TextField
|
||||||
|
variant="outlined"
|
||||||
|
size="small"
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell
|
||||||
|
component="th"
|
||||||
|
scope="row"
|
||||||
|
>
|
||||||
|
<Autocomplete
|
||||||
|
className=""
|
||||||
|
freeSolo
|
||||||
|
size="small"
|
||||||
|
options={[]}
|
||||||
|
/* value={value }
|
||||||
|
onChange={(event, newValue) => {
|
||||||
|
onChange(newValue);
|
||||||
|
}} */
|
||||||
|
renderInput={(params) => (
|
||||||
|
<TextField
|
||||||
|
{...params}
|
||||||
|
placeholder="Busque el producto"
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
InputLabelProps={{
|
||||||
|
shrink: true
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell
|
||||||
|
component="th"
|
||||||
|
scope="row"
|
||||||
|
>
|
||||||
|
<TextField
|
||||||
|
variant="outlined"
|
||||||
|
size="small"
|
||||||
|
fullWidth
|
||||||
|
type="number"
|
||||||
|
/>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell
|
||||||
|
component="th"
|
||||||
|
scope="row"
|
||||||
|
>
|
||||||
|
<TextField
|
||||||
|
variant="outlined"
|
||||||
|
size="small"
|
||||||
|
fullWidth
|
||||||
|
type="number"
|
||||||
|
/>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell
|
||||||
|
component="th"
|
||||||
|
scope="row"
|
||||||
|
className="px-0"
|
||||||
|
>
|
||||||
|
<Checkbox />
|
||||||
|
</TableCell>
|
||||||
|
<TableCell
|
||||||
|
component="th"
|
||||||
|
scope="row"
|
||||||
|
>
|
||||||
|
<TextField
|
||||||
|
variant="outlined"
|
||||||
|
size="small"
|
||||||
|
fullWidth
|
||||||
|
type="number"
|
||||||
|
/>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell
|
||||||
|
component="th"
|
||||||
|
scope="row"
|
||||||
|
>
|
||||||
|
<IconButton>
|
||||||
|
<FuseSvgIcon>heroicons-outline:trash</FuseSvgIcon>
|
||||||
|
</IconButton>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default TableInvoiceRender;
|
||||||
|
|
@ -0,0 +1,65 @@
|
||||||
|
import { Box, Grid, Typography, Divider } from '@mui/material';
|
||||||
|
|
||||||
|
function DataTransmitter() {
|
||||||
|
return (
|
||||||
|
<Box className="mt-10 p-20 shadow-2 rounded-8">
|
||||||
|
<Typography
|
||||||
|
component="h3"
|
||||||
|
className="mb-7"
|
||||||
|
>
|
||||||
|
Datos emisor
|
||||||
|
</Typography>
|
||||||
|
<Divider className="border-1 mb-10" />
|
||||||
|
<Grid
|
||||||
|
container
|
||||||
|
spacing={2}
|
||||||
|
>
|
||||||
|
<Grid
|
||||||
|
item
|
||||||
|
md={6}
|
||||||
|
xs={12}
|
||||||
|
>
|
||||||
|
<b>Razón Social:</b> Jonathan Andres Alvarez Flores
|
||||||
|
</Grid>
|
||||||
|
<Grid
|
||||||
|
item
|
||||||
|
md={6}
|
||||||
|
xs={12}
|
||||||
|
>
|
||||||
|
<b>Nombre Comercial:</b> Jonathan Andres Alvarez Flores
|
||||||
|
</Grid>
|
||||||
|
<Grid
|
||||||
|
item
|
||||||
|
md={6}
|
||||||
|
xs={12}
|
||||||
|
>
|
||||||
|
<b>Ruc:</b> 17215785512001
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<Grid
|
||||||
|
item
|
||||||
|
md={6}
|
||||||
|
xs={12}
|
||||||
|
>
|
||||||
|
<b>Dirección:</b> Calle Oe11g y s32
|
||||||
|
</Grid>
|
||||||
|
<Grid
|
||||||
|
item
|
||||||
|
md={6}
|
||||||
|
xs={12}
|
||||||
|
>
|
||||||
|
<b>Contribuyente Especial:</b> NO
|
||||||
|
</Grid>
|
||||||
|
<Grid
|
||||||
|
item
|
||||||
|
md={6}
|
||||||
|
xs={12}
|
||||||
|
>
|
||||||
|
<b>Obligado Contabilidad:</b> NO
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DataTransmitter;
|
||||||
|
|
@ -1,257 +1,265 @@
|
||||||
import FusePageSimple from "@fuse/core/FusePageSimple";
|
import FusePageSimple from '@fuse/core/FusePageSimple';
|
||||||
import FuseSvgIcon from "@fuse/core/FuseSvgIcon";
|
import FuseSvgIcon from '@fuse/core/FuseSvgIcon';
|
||||||
import {
|
import { Button, Paper, Table, TableBody, TableCell, TableHead, TableRow, Typography, styled } from '@mui/material';
|
||||||
Button,
|
import clsx from 'clsx';
|
||||||
Paper,
|
import { format } from 'date-fns';
|
||||||
Table,
|
import { useTranslation } from 'react-i18next';
|
||||||
TableBody,
|
import { Link } from 'react-router-dom';
|
||||||
TableCell,
|
|
||||||
TableHead,
|
|
||||||
TableRow,
|
|
||||||
Typography,
|
|
||||||
styled,
|
|
||||||
} from "@mui/material";
|
|
||||||
import clsx from "clsx";
|
|
||||||
import { format } from "date-fns";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import { Link } from "react-router-dom";
|
|
||||||
|
|
||||||
const Root = styled(FusePageSimple)(({ theme }) => ({
|
const Root = styled(FusePageSimple)(({ theme }) => ({
|
||||||
"& .FusePageSimple-header": {
|
'& .FusePageSimple-header': {
|
||||||
backgroundColor: theme.palette.background.paper,
|
backgroundColor: theme.palette.background.paper,
|
||||||
boxShadow: `inset 0 0 0 1px ${theme.palette.divider}`,
|
boxShadow: `inset 0 0 0 1px ${theme.palette.divider}`
|
||||||
},
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const ListInvoiceRender = () => {
|
function ListInvoiceRender() {
|
||||||
const { t } = useTranslation("invoicePage");
|
const { t } = useTranslation('invoicePage');
|
||||||
const columns = [
|
const columns = ['Número factura', 'Fecha', 'Cliente', 'Identificación', 'Valor', 'Estado', 'Acciones'];
|
||||||
"Número factura",
|
|
||||||
"Fecha",
|
|
||||||
"Cliente",
|
|
||||||
"Identificación",
|
|
||||||
"Valor",
|
|
||||||
"Estado",
|
|
||||||
"Acciones",
|
|
||||||
];
|
|
||||||
|
|
||||||
const rows = [
|
const rows = [
|
||||||
{
|
{
|
||||||
id: "528651571NT",
|
id: '528651571NT',
|
||||||
date: "2019-10-07T22:22:37.274Z",
|
date: '2019-10-07T22:22:37.274Z',
|
||||||
name: "Morgan Page",
|
name: 'Morgan Page',
|
||||||
identification: "17215896114",
|
identification: '17215896114',
|
||||||
amount: 1358.75,
|
amount: 1358.75,
|
||||||
status: "completed",
|
status: 'completed',
|
||||||
action: true,
|
action: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "421436904YT",
|
id: '421436904YT',
|
||||||
date: "2019-12-18T14:51:24.461Z",
|
date: '2019-12-18T14:51:24.461Z',
|
||||||
name: "Nita Hebert",
|
name: 'Nita Hebert',
|
||||||
identification: "17215896114",
|
identification: '17215896114',
|
||||||
amount: -1042.82,
|
amount: -1042.82,
|
||||||
status: "completed",
|
status: 'completed',
|
||||||
action: true,
|
action: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "685377421YT",
|
id: '685377421YT',
|
||||||
date: "2019-12-25T17:52:14.304Z",
|
date: '2019-12-25T17:52:14.304Z',
|
||||||
name: "Marsha Chambers",
|
name: 'Marsha Chambers',
|
||||||
identification: "17215896114",
|
identification: '17215896114',
|
||||||
amount: 1828.16,
|
amount: 1828.16,
|
||||||
status: "pending",
|
status: 'pending',
|
||||||
action: true,
|
action: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "884960091RT",
|
id: '884960091RT',
|
||||||
date: "2019-11-29T06:32:16.111Z",
|
date: '2019-11-29T06:32:16.111Z',
|
||||||
name: "Charmaine Jackson",
|
name: 'Charmaine Jackson',
|
||||||
identification: "17215896114",
|
identification: '17215896114',
|
||||||
amount: 1647.55,
|
amount: 1647.55,
|
||||||
status: "completed",
|
status: 'completed',
|
||||||
action: true,
|
action: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "361402213NT",
|
id: '361402213NT',
|
||||||
date: "2019-11-24T12:13:23.064Z",
|
date: '2019-11-24T12:13:23.064Z',
|
||||||
name: "Maura Carey",
|
name: 'Maura Carey',
|
||||||
identification: "17215896114",
|
identification: '17215896114',
|
||||||
amount: -927.43,
|
amount: -927.43,
|
||||||
status: "completed",
|
status: 'completed',
|
||||||
action: true,
|
action: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "361402213NT",
|
id: '361402213NT',
|
||||||
date: "2019-11-24T12:13:23.064Z",
|
date: '2019-11-24T12:13:23.064Z',
|
||||||
name: "Maura Carey",
|
name: 'Maura Carey',
|
||||||
identification: "17215896114",
|
identification: '17215896114',
|
||||||
amount: -927.43,
|
amount: -927.43,
|
||||||
status: "completed",
|
status: 'completed',
|
||||||
action: true,
|
action: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "361402213NT",
|
id: '361402213NT',
|
||||||
date: "2019-11-24T12:13:23.064Z",
|
date: '2019-11-24T12:13:23.064Z',
|
||||||
name: "Maura Carey",
|
name: 'Maura Carey',
|
||||||
identification: "17215896114",
|
identification: '17215896114',
|
||||||
amount: -927.43,
|
amount: -927.43,
|
||||||
status: "completed",
|
status: 'completed',
|
||||||
action: true,
|
action: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "361402213NT",
|
id: '361402213NT',
|
||||||
date: "2019-11-24T12:13:23.064Z",
|
date: '2019-11-24T12:13:23.064Z',
|
||||||
name: "Maura Carey",
|
name: 'Maura Carey',
|
||||||
identification: "17215896114",
|
identification: '17215896114',
|
||||||
amount: -927.43,
|
amount: -927.43,
|
||||||
status: "completed",
|
status: 'completed',
|
||||||
action: true,
|
action: true
|
||||||
},
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Root
|
<Root
|
||||||
header={
|
header={
|
||||||
<div className="p-24">
|
<div className="p-24">
|
||||||
<h4>{t("TITLE")}</h4>
|
<h4>{t('TITLE')}</h4>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
content={
|
content={
|
||||||
<Paper className="flex flex-col flex-auto p-24 shadow rounded-2 overflow-hidden mt-6">
|
<Paper className="flex flex-col flex-auto p-24 shadow rounded-2 overflow-hidden m-10">
|
||||||
<div className="flex md:flex-row justify-between flex-col">
|
<div className="flex md:flex-row justify-between flex-col">
|
||||||
<div>
|
<div>
|
||||||
<Typography className="mr-16 text-lg font-medium tracking-tight leading-6 truncate">
|
<Typography className="mr-16 text-lg font-medium tracking-tight leading-6 truncate">
|
||||||
{t("TITLE_TABLE")}
|
{t('TITLE_TABLE')}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography className="font-medium" color="text.secondary">
|
<Typography
|
||||||
1 pendiente, 4 completadas
|
className="font-medium"
|
||||||
</Typography>
|
color="text.secondary"
|
||||||
</div>
|
>
|
||||||
<div>
|
1 pendiente, 4 completadas
|
||||||
<Button
|
</Typography>
|
||||||
size="small"
|
</div>
|
||||||
variant="contained"
|
<div>
|
||||||
color="primary"
|
<Button
|
||||||
component={Link}
|
size="small"
|
||||||
to={'/invoice/edit'}
|
variant="contained"
|
||||||
startIcon={
|
color="primary"
|
||||||
<FuseSvgIcon
|
component={Link}
|
||||||
className="text-48 text-white"
|
to="/invoice/edit"
|
||||||
size={24}
|
startIcon={
|
||||||
color="action"
|
<FuseSvgIcon
|
||||||
>
|
className="text-48 text-white"
|
||||||
heroicons-outline:plus
|
size={24}
|
||||||
</FuseSvgIcon>
|
color="action"
|
||||||
}
|
>
|
||||||
>
|
heroicons-outline:plus
|
||||||
Nueva factura
|
</FuseSvgIcon>
|
||||||
</Button>
|
}
|
||||||
</div>
|
>
|
||||||
</div>
|
Nueva factura
|
||||||
<div className="table-responsive mt-24">
|
</Button>
|
||||||
<Table className="simple w-full min-w-full h-full">
|
</div>
|
||||||
<TableHead>
|
</div>
|
||||||
<TableRow>
|
<div className="table-responsive mt-24">
|
||||||
{columns.map((column, index) => (
|
<Table className="simple w-full min-w-full h-full">
|
||||||
<TableCell key={index}>
|
<TableHead>
|
||||||
<Typography
|
<TableRow>
|
||||||
color="text.secondary"
|
{columns.map((column, index) => (
|
||||||
className="font-semibold text-12 whitespace-nowrap"
|
<TableCell key={index}>
|
||||||
>
|
<Typography
|
||||||
{column}
|
color="text.secondary"
|
||||||
</Typography>
|
className="font-semibold text-12 whitespace-nowrap"
|
||||||
</TableCell>
|
>
|
||||||
))}
|
{column}
|
||||||
</TableRow>
|
</Typography>
|
||||||
</TableHead>
|
</TableCell>
|
||||||
|
))}
|
||||||
|
</TableRow>
|
||||||
|
</TableHead>
|
||||||
|
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{rows.map((row, index) => (
|
{rows.map((row, index) => (
|
||||||
<TableRow key={index}>
|
<TableRow key={index}>
|
||||||
{Object.entries(row).map(([key, value]) => {
|
{Object.entries(row).map(([key, value]) => {
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case "id": {
|
case 'id': {
|
||||||
return (
|
return (
|
||||||
<TableCell key={key} component="th" scope="row">
|
<TableCell
|
||||||
<Typography color="text.secondary">
|
key={key}
|
||||||
{value}
|
component="th"
|
||||||
</Typography>
|
scope="row"
|
||||||
</TableCell>
|
>
|
||||||
);
|
<Typography color="text.secondary">{value}</Typography>
|
||||||
}
|
</TableCell>
|
||||||
case "date": {
|
);
|
||||||
return (
|
}
|
||||||
<TableCell key={key} component="th" scope="row">
|
case 'date': {
|
||||||
<Typography>
|
return (
|
||||||
{
|
<TableCell
|
||||||
// @ts-ignore
|
key={key}
|
||||||
format(new Date(value), "dd/MM/yyyy")
|
component="th"
|
||||||
}
|
scope="row"
|
||||||
</Typography>
|
>
|
||||||
</TableCell>
|
<Typography>
|
||||||
);
|
{
|
||||||
}
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
case "amount": {
|
// @ts-ignore
|
||||||
return (
|
format(new Date(value), 'dd/MM/yyyy')
|
||||||
<TableCell key={key} component="th" scope="row">
|
}
|
||||||
<Typography>
|
</Typography>
|
||||||
{value.toLocaleString("en-US", {
|
</TableCell>
|
||||||
style: "currency",
|
);
|
||||||
currency: "USD",
|
}
|
||||||
})}
|
case 'amount': {
|
||||||
</Typography>
|
return (
|
||||||
</TableCell>
|
<TableCell
|
||||||
);
|
key={key}
|
||||||
}
|
component="th"
|
||||||
case "status": {
|
scope="row"
|
||||||
return (
|
>
|
||||||
<TableCell key={key} component="th" scope="row">
|
<Typography>
|
||||||
<Typography
|
{value.toLocaleString('en-US', {
|
||||||
className={clsx(
|
style: 'currency',
|
||||||
"inline-flex items-center font-bold text-10 px-10 py-2 rounded-full tracking-wide uppercase",
|
currency: 'USD'
|
||||||
value === "pending" &&
|
})}
|
||||||
"bg-red-100 text-red-800 dark:bg-red-600 dark:text-red-50",
|
</Typography>
|
||||||
value === "completed" &&
|
</TableCell>
|
||||||
"bg-green-50 text-green-800 dark:bg-green-600 dark:text-green-50"
|
);
|
||||||
)}
|
}
|
||||||
>
|
case 'status': {
|
||||||
{value}
|
return (
|
||||||
</Typography>
|
<TableCell
|
||||||
</TableCell>
|
key={key}
|
||||||
);
|
component="th"
|
||||||
}
|
scope="row"
|
||||||
case "action": {
|
>
|
||||||
return (
|
<Typography
|
||||||
<TableCell key={key} component="th" scope="row">
|
className={clsx(
|
||||||
<Button
|
'inline-flex items-center font-bold text-10 px-10 py-2 rounded-full tracking-wide uppercase',
|
||||||
size="small"
|
value === 'pending' &&
|
||||||
variant="contained"
|
'bg-red-100 text-red-800 dark:bg-red-600 dark:text-red-50',
|
||||||
color="primary"
|
value === 'completed' &&
|
||||||
>
|
'bg-green-50 text-green-800 dark:bg-green-600 dark:text-green-50'
|
||||||
Ver
|
)}
|
||||||
</Button>
|
>
|
||||||
</TableCell>
|
{value}
|
||||||
);
|
</Typography>
|
||||||
}
|
</TableCell>
|
||||||
default: {
|
);
|
||||||
return (
|
}
|
||||||
<TableCell key={key} component="th" scope="row">
|
case 'action': {
|
||||||
<Typography>{value}</Typography>
|
return (
|
||||||
</TableCell>
|
<TableCell
|
||||||
);
|
key={key}
|
||||||
}
|
component="th"
|
||||||
}
|
scope="row"
|
||||||
})}
|
>
|
||||||
</TableRow>
|
<Button
|
||||||
))}
|
size="small"
|
||||||
</TableBody>
|
variant="contained"
|
||||||
</Table>
|
color="primary"
|
||||||
</div>
|
>
|
||||||
</Paper>
|
Ver
|
||||||
}
|
</Button>
|
||||||
/>
|
</TableCell>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
default: {
|
||||||
|
return (
|
||||||
|
<TableCell
|
||||||
|
key={key}
|
||||||
|
component="th"
|
||||||
|
scope="row"
|
||||||
|
>
|
||||||
|
<Typography>{value}</Typography>
|
||||||
|
</TableCell>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})}
|
||||||
|
</TableRow>
|
||||||
|
))}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</div>
|
||||||
|
</Paper>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export default ListInvoiceRender;
|
export default ListInvoiceRender;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
import DemoContent from '@fuse/core/DemoContent';
|
||||||
|
import FusePageSimple from '@fuse/core/FusePageSimple';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { styled } from '@mui/material/styles';
|
||||||
|
import ListDetalleProductoRender from './detalleProducto/DetalleProductoRender';
|
||||||
|
import ProductoRender from './ProductoRender';
|
||||||
|
|
||||||
|
const Root = styled(FusePageSimple)(({ theme }) => ({
|
||||||
|
'& .FusePageSimple-header': {
|
||||||
|
backgroundColor: theme.palette.background.paper,
|
||||||
|
borderBottomWidth: 1,
|
||||||
|
borderStyle: 'solid',
|
||||||
|
borderColor: theme.palette.divider
|
||||||
|
},
|
||||||
|
'& .FusePageSimple-content': {},
|
||||||
|
'& .FusePageSimple-sidebarHeader': {},
|
||||||
|
'& .FusePageSimple-sidebarContent': {}
|
||||||
|
}));
|
||||||
|
|
||||||
|
function Producto() {
|
||||||
|
const { t } = useTranslation('products');
|
||||||
|
|
||||||
|
return(
|
||||||
|
<Root
|
||||||
|
header={
|
||||||
|
<div className='p-24'>
|
||||||
|
<h4>{t('PRODUCTOS')}</h4>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
content={
|
||||||
|
<ProductoRender></ProductoRender>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Producto;
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
import { FuseRouteConfigsType } from "@fuse/utils/FuseUtils";
|
||||||
|
import FormularioProductoConfig from "./formularioProducto/FormularioProductoConfig";
|
||||||
|
import DetalleProductoConfig from "./detalleProducto/DetalleProductoConfig";
|
||||||
|
|
||||||
|
const productoConfigs: FuseRouteConfigsType = [
|
||||||
|
DetalleProductoConfig,
|
||||||
|
FormularioProductoConfig
|
||||||
|
]
|
||||||
|
|
||||||
|
export default productoConfigs;
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
import BuscarProducto from "./widgets/BuscarProducto";
|
||||||
|
import ListDetalleProductoRender from "./detalleProducto/DetalleProductoRender";
|
||||||
|
import DetalleProducto from "./detalleProducto/DetalleProducto";
|
||||||
|
|
||||||
|
function ProductoRender() {
|
||||||
|
return(
|
||||||
|
<div className="w-full p-12 pt-16 sm:pt-24 lg:ltr:pr-0 lg:rtl:pl-0">
|
||||||
|
<BuscarProducto></BuscarProducto>
|
||||||
|
<DetalleProducto></DetalleProducto>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ProductoRender;
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
import ListDetalleProductoRender from "./DetalleProductoRender"
|
||||||
|
|
||||||
|
const DetalleProducto = () => {
|
||||||
|
return(
|
||||||
|
<ListDetalleProductoRender/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DetalleProducto;
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
import i18next from "i18next";
|
||||||
|
import { lazy } from 'react';
|
||||||
|
import es from '../i18n/es';
|
||||||
|
|
||||||
|
i18next.addResourceBundle('es', 'detailProduct', es);
|
||||||
|
|
||||||
|
const Producto = lazy(() => import('../Producto'));
|
||||||
|
|
||||||
|
const DetalleProductoConfig = {
|
||||||
|
settings: {
|
||||||
|
layout: {}
|
||||||
|
},
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
path: 'product/list',
|
||||||
|
element: <Producto/>
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DetalleProductoConfig;
|
||||||
|
|
@ -0,0 +1,216 @@
|
||||||
|
import * as React from "react";
|
||||||
|
import FuseSvgIcon from "@fuse/core/FuseSvgIcon";
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
IconButton,
|
||||||
|
Paper,
|
||||||
|
Table,
|
||||||
|
TableBody,
|
||||||
|
TableCell,
|
||||||
|
TableHead,
|
||||||
|
TablePagination,
|
||||||
|
TableRow,
|
||||||
|
Typography,
|
||||||
|
} from "@mui/material";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
import clsx from "clsx";
|
||||||
|
import ResponsiveDialog from "../widgets/DialogDelete";
|
||||||
|
|
||||||
|
function ListDetalleProductoRender() {
|
||||||
|
const [page, setPage] = React.useState(0);
|
||||||
|
const [rowsPerPage, setRowsPerPage] = React.useState(10);
|
||||||
|
|
||||||
|
const handleChangePage = (event: unknown, newPage: number) => {
|
||||||
|
setPage(newPage);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleChangeRowsPerPage = (
|
||||||
|
event: React.ChangeEvent<HTMLInputElement>
|
||||||
|
) => {
|
||||||
|
setRowsPerPage(+event.target.value);
|
||||||
|
setPage(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
const { t } = useTranslation("products");
|
||||||
|
const columns = [
|
||||||
|
"Código",
|
||||||
|
"Nombre",
|
||||||
|
"Descripción",
|
||||||
|
"Stock Mínimo",
|
||||||
|
"Estado",
|
||||||
|
"Acciones",
|
||||||
|
];
|
||||||
|
|
||||||
|
const rows = [
|
||||||
|
{
|
||||||
|
artCodigo: 1,
|
||||||
|
artNombre: "Servicios Profesionales",
|
||||||
|
artDescripcion: "Prestación de servicios",
|
||||||
|
artStockMinimo: 0,
|
||||||
|
artEstado: "activo",
|
||||||
|
action: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
artCodigo: 2,
|
||||||
|
artNombre: "Servicios Varios",
|
||||||
|
artDescripcion: "",
|
||||||
|
artStockMinimo: 0,
|
||||||
|
artEstado: "inactivo",
|
||||||
|
action: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
artCodigo: 3,
|
||||||
|
artNombre: "Servicios Profesionales",
|
||||||
|
artDescripcion: "Prestación de servicios",
|
||||||
|
artStockMinimo: 0,
|
||||||
|
artEstado: "activo",
|
||||||
|
action: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
artCodigo: 4,
|
||||||
|
artNombre: "Servicios Varios",
|
||||||
|
artDescripcion: "",
|
||||||
|
artStockMinimo: 0,
|
||||||
|
artEstado: "inactivo",
|
||||||
|
action: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
artCodigo: 5,
|
||||||
|
artNombre: "Servicios Profesionales",
|
||||||
|
artDescripcion: "Prestación de servicios",
|
||||||
|
artStockMinimo: 0,
|
||||||
|
artEstado: "activo",
|
||||||
|
action: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
artCodigo: 6,
|
||||||
|
artNombre: "Servicios Varios",
|
||||||
|
artDescripcion: "",
|
||||||
|
artStockMinimo: 0,
|
||||||
|
artEstado: "inactivo",
|
||||||
|
action: true,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Paper className="flex flex-col flex-auto p-24 shadow rounded-2 overflow-hidden m-10">
|
||||||
|
<div className="flex md:flex-row justify-between flex-col">
|
||||||
|
<div>
|
||||||
|
<Typography className="mr-16 text-lg font-medium tracking-tight leading-6 truncate">
|
||||||
|
{t("Detalle de productos")}
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<Button
|
||||||
|
size="small"
|
||||||
|
variant="contained"
|
||||||
|
color="secondary"
|
||||||
|
component={Link}
|
||||||
|
to={"/product/form"}
|
||||||
|
startIcon={
|
||||||
|
<FuseSvgIcon
|
||||||
|
className="text-48 text-white"
|
||||||
|
size={24}
|
||||||
|
color="action"
|
||||||
|
>
|
||||||
|
heroicons-outline:plus
|
||||||
|
</FuseSvgIcon>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Registrar Producto
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="table-responsive mt-24">
|
||||||
|
<Table className="simple w-full min-w-full h-full">
|
||||||
|
<TableHead>
|
||||||
|
<TableRow>
|
||||||
|
{columns.map((column, index) => (
|
||||||
|
<TableCell key={index}>
|
||||||
|
<Typography
|
||||||
|
color="text.secondary"
|
||||||
|
className="font-semibold text-12 whitespace-nowrap"
|
||||||
|
>
|
||||||
|
{column}
|
||||||
|
</Typography>
|
||||||
|
</TableCell>
|
||||||
|
))}
|
||||||
|
</TableRow>
|
||||||
|
</TableHead>
|
||||||
|
|
||||||
|
<TableBody>
|
||||||
|
{rows
|
||||||
|
.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
|
||||||
|
.map((row, index) => (
|
||||||
|
<TableRow key={index}>
|
||||||
|
{Object.entries(row).map(([key, value]) => {
|
||||||
|
switch (key) {
|
||||||
|
case "artEstado": {
|
||||||
|
return (
|
||||||
|
<TableCell key={key} component="th" scope="row" >
|
||||||
|
<Typography
|
||||||
|
className={clsx(
|
||||||
|
"inline-flex items-center font-bold text-10 px-10 py-2 rounded-full tracking-wide uppercase",
|
||||||
|
value === "inactivo" &&
|
||||||
|
"bg-red-100 text-red-800 dark:bg-red-600 dark:text-red-50",
|
||||||
|
value === "activo" &&
|
||||||
|
"bg-green-50 text-green-800 dark:bg-green-600 dark:text-green-50"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{value}
|
||||||
|
</Typography>
|
||||||
|
</TableCell>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
case "action": {
|
||||||
|
return (
|
||||||
|
<TableCell
|
||||||
|
key={key}
|
||||||
|
component="th"
|
||||||
|
scope="row"
|
||||||
|
className="text-center"
|
||||||
|
>
|
||||||
|
<div className="flex items-center justify-left">
|
||||||
|
<Typography>{value}</Typography>
|
||||||
|
|
||||||
|
<IconButton size="small" color="inherit">
|
||||||
|
<FuseSvgIcon>
|
||||||
|
heroicons-outline:pencil-alt
|
||||||
|
</FuseSvgIcon>
|
||||||
|
</IconButton>
|
||||||
|
|
||||||
|
<ResponsiveDialog></ResponsiveDialog>
|
||||||
|
</div>
|
||||||
|
</TableCell>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
default: {
|
||||||
|
return (
|
||||||
|
<TableCell key={key} component="th" scope="row">
|
||||||
|
<Typography>{value}</Typography>
|
||||||
|
</TableCell>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})}
|
||||||
|
</TableRow>
|
||||||
|
))}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
<TablePagination
|
||||||
|
rowsPerPageOptions={[5, 10, 25]}
|
||||||
|
component="div"
|
||||||
|
count={rows.length}
|
||||||
|
rowsPerPage={rowsPerPage}
|
||||||
|
page={page}
|
||||||
|
onPageChange={handleChangePage}
|
||||||
|
onRowsPerPageChange={handleChangeRowsPerPage}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Paper>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ListDetalleProductoRender;
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
import FormularioProductoRender from "./FormularioProductoRender"
|
||||||
|
|
||||||
|
const FormularioProducto = () => {
|
||||||
|
return(
|
||||||
|
<FormularioProductoRender/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FormularioProducto;
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
import i18next from "i18next";
|
||||||
|
import es from "../i18n/es";
|
||||||
|
import { lazy } from "react";
|
||||||
|
|
||||||
|
i18next.addResourceBundle('es', 'formProducto', es);
|
||||||
|
|
||||||
|
const FormularioProducto = lazy(() => import('./FormularioProducto'));
|
||||||
|
|
||||||
|
const FormularioProductoConfig = {
|
||||||
|
settings: {
|
||||||
|
layout: {
|
||||||
|
config: {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
path: 'product/form',
|
||||||
|
element: <FormularioProducto />,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FormularioProductoConfig;
|
||||||
|
|
@ -0,0 +1,227 @@
|
||||||
|
import FusePageSimple from "@fuse/core/FusePageSimple";
|
||||||
|
import {
|
||||||
|
Autocomplete,
|
||||||
|
Card,
|
||||||
|
CardActions,
|
||||||
|
CardContent,
|
||||||
|
CardHeader,
|
||||||
|
Divider,
|
||||||
|
TextField,
|
||||||
|
styled,
|
||||||
|
Button,
|
||||||
|
Grid,
|
||||||
|
} from "@mui/material";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { Formik, Form, Field, ErrorMessage } from "formik";
|
||||||
|
import * as Yup from "yup";
|
||||||
|
|
||||||
|
const FormularioProductoRender = () => {
|
||||||
|
const [datosCargados, setDatosCargados] = useState(false);
|
||||||
|
|
||||||
|
const validationSchema = Yup.object().shape({
|
||||||
|
codigo: Yup.string().required("El código es requerido"),
|
||||||
|
tipo: Yup.string().required("El tipo es requerido"),
|
||||||
|
nombre: Yup.string().required("El nombre es requerido"),
|
||||||
|
estado: Yup.string().required("El estado es requerido"),
|
||||||
|
stockMinimo: Yup.string().required("El stock mínimo es requerido"),
|
||||||
|
margenGanancia: Yup.string().required("El margen de ganancia es requerido"),
|
||||||
|
descripcion: Yup.string().required("La descripción es requerida"),
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card className="m-20 p-24">
|
||||||
|
<CardHeader title="Registro producto" className="text-16 font-bold " />
|
||||||
|
<Divider />
|
||||||
|
|
||||||
|
<Formik
|
||||||
|
initialValues={{
|
||||||
|
codigo: "",
|
||||||
|
tipo: "",
|
||||||
|
nombre: "",
|
||||||
|
estado: "",
|
||||||
|
stockMinimo: "",
|
||||||
|
margenGanancia: "",
|
||||||
|
descripcion: "",
|
||||||
|
}}
|
||||||
|
|
||||||
|
validationSchema={validationSchema}
|
||||||
|
onSubmit={(values, { setSubmitting }) => {
|
||||||
|
console.log(values);
|
||||||
|
setSubmitting(false);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{({ isSubmitting, touched, errors, setFieldTouched }) => (
|
||||||
|
<Form>
|
||||||
|
<CardContent className="flex">
|
||||||
|
<Grid className="grid grid-cols-1 sm:grid-cols-6 gap-10 w-full min-w-0">
|
||||||
|
|
||||||
|
<div className="mt-20 sm:col-span-3 lg:col-span-3">
|
||||||
|
<Field
|
||||||
|
as={TextField}
|
||||||
|
label="Código"
|
||||||
|
name="codigo"
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
size="small"
|
||||||
|
error={touched.codigo && !!errors.codigo}
|
||||||
|
/>
|
||||||
|
<ErrorMessage
|
||||||
|
name="codigo"
|
||||||
|
component="div"
|
||||||
|
className="text-red-500 text-md ml-12 pt-4"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-20 sm:col-span-3 lg:col-span-3">
|
||||||
|
<Autocomplete
|
||||||
|
multiple
|
||||||
|
size="small"
|
||||||
|
freeSolo
|
||||||
|
options={["Hola", "Chao"]}
|
||||||
|
onChange={() => setFieldTouched("tipo", true)}
|
||||||
|
renderInput={(params) => (
|
||||||
|
<TextField
|
||||||
|
{...params}
|
||||||
|
label="Seleccione el tipo de producto"
|
||||||
|
name="tipo"
|
||||||
|
variant="outlined"
|
||||||
|
error={touched.tipo && !!errors.tipo}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<ErrorMessage
|
||||||
|
name="tipo"
|
||||||
|
component="div"
|
||||||
|
className="text-red-500 text-md ml-12 pt-4"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-10 sm:col-span-3 lg:col-span-3">
|
||||||
|
<Field
|
||||||
|
as={TextField}
|
||||||
|
label="Nombre"
|
||||||
|
name="nombre"
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
size="small"
|
||||||
|
error={touched.nombre && !!errors.nombre}
|
||||||
|
/>
|
||||||
|
<ErrorMessage
|
||||||
|
name="nombre"
|
||||||
|
component="div"
|
||||||
|
className="text-red-500 text-md ml-12 pt-4"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-10 sm:col-span-3 lg:col-span-3">
|
||||||
|
<Autocomplete
|
||||||
|
multiple
|
||||||
|
size="small"
|
||||||
|
freeSolo
|
||||||
|
options={["Activo", "Inactivo"]}
|
||||||
|
onChange={() => setFieldTouched("estado", true)}
|
||||||
|
renderInput={(params) => (
|
||||||
|
<TextField
|
||||||
|
{...params}
|
||||||
|
label="Seleccione el estado"
|
||||||
|
name="estado"
|
||||||
|
variant="outlined"
|
||||||
|
error={touched.estado && !!errors.estado}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<ErrorMessage
|
||||||
|
name="estado"
|
||||||
|
component="div"
|
||||||
|
className="text-red-500 text-md ml-12 pt-4"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-10 sm:col-span-3 lg:col-span-3">
|
||||||
|
<Field
|
||||||
|
as={TextField}
|
||||||
|
label="Stock Mínimo"
|
||||||
|
name="stockMinimo"
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
size="small"
|
||||||
|
error={touched.stockMinimo && !!errors.stockMinimo}
|
||||||
|
/>
|
||||||
|
<ErrorMessage
|
||||||
|
name="stockMinimo"
|
||||||
|
component="div"
|
||||||
|
className="text-red-500 text-md ml-12 pt-4"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-10 sm:col-span-3 md:col-span-3">
|
||||||
|
<Field
|
||||||
|
as={TextField}
|
||||||
|
label="Margen de Ganancia"
|
||||||
|
name="margenGanancia"
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
size="small"
|
||||||
|
error={touched.margenGanancia && !!errors.margenGanancia}
|
||||||
|
/>
|
||||||
|
<ErrorMessage
|
||||||
|
name="margenGanancia"
|
||||||
|
component="div"
|
||||||
|
className="text-red-500 text-md ml-12 pt-4"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-10 sm:col-span-6 lg:col-span-6">
|
||||||
|
<Field
|
||||||
|
as={TextField}
|
||||||
|
id="descripcion"
|
||||||
|
label="Descripción"
|
||||||
|
name="descripcion"
|
||||||
|
type="text"
|
||||||
|
multiline
|
||||||
|
rows={5}
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
size="small"
|
||||||
|
error={touched.descripcion && !!errors.descripcion}
|
||||||
|
/>
|
||||||
|
<ErrorMessage
|
||||||
|
name="descripcion"
|
||||||
|
component="div"
|
||||||
|
className="text-red-500 text-md ml-12 pt-4"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
</CardContent>
|
||||||
|
|
||||||
|
<CardActions className="">
|
||||||
|
<Button
|
||||||
|
className="w-320"
|
||||||
|
variant="contained"
|
||||||
|
size="small"
|
||||||
|
color="secondary"
|
||||||
|
type="submit"
|
||||||
|
disabled={isSubmitting}
|
||||||
|
>
|
||||||
|
Guardar
|
||||||
|
</Button>
|
||||||
|
{datosCargados && (
|
||||||
|
<Button
|
||||||
|
className="w-320"
|
||||||
|
variant="contained"
|
||||||
|
size="small"
|
||||||
|
color="primary"
|
||||||
|
>
|
||||||
|
Actualizar
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</CardActions>
|
||||||
|
</Form>
|
||||||
|
)}
|
||||||
|
</Formik>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FormularioProductoRender;
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
const locale = {
|
||||||
|
TITLE: 'Producto'
|
||||||
|
};
|
||||||
|
|
||||||
|
export default locale;
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import { styled, alpha } from '@mui/material/styles';
|
||||||
|
import Box from '@mui/material/Box';
|
||||||
|
import Toolbar from '@mui/material/Toolbar';
|
||||||
|
import IconButton from '@mui/material/IconButton';
|
||||||
|
import Typography from '@mui/material/Typography';
|
||||||
|
import InputBase from '@mui/material/InputBase';
|
||||||
|
import FuseSvgIcon from '@fuse/core/FuseSvgIcon';
|
||||||
|
import FuseSearch from '@fuse/core/FuseSearch';
|
||||||
|
import { Card } from '@mui/material';
|
||||||
|
import { color } from '@mui/system';
|
||||||
|
|
||||||
|
const Search = styled('div')(({ theme }) => ({
|
||||||
|
position: 'relative',
|
||||||
|
borderRadius: theme.shape.borderRadius,
|
||||||
|
backgroundColor: alpha(theme.palette.common.black, 0.06),
|
||||||
|
'&:hover': {
|
||||||
|
/* backgroundColor: alpha(theme.palette.common.white, 0.25), */
|
||||||
|
},
|
||||||
|
width: '100%',
|
||||||
|
[theme.breakpoints.up('sm')]: {
|
||||||
|
/* marginLeft: theme.spacing(), */
|
||||||
|
width: 'auto',
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
const SearchIconWrapper = styled('div')(({ theme }) => ({
|
||||||
|
padding: theme.spacing(0, 2),
|
||||||
|
height: '100%',
|
||||||
|
position: 'absolute',
|
||||||
|
pointerEvents: 'none',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
}));
|
||||||
|
|
||||||
|
const StyledInputBase = styled(InputBase)(({ theme }) => ({
|
||||||
|
color: 'inherit',
|
||||||
|
width: '100%',
|
||||||
|
'& .MuiInputBase-input': {
|
||||||
|
padding: theme.spacing(1, 1, 1, 0),
|
||||||
|
// vertical padding + font size from searchIcon
|
||||||
|
paddingLeft: `calc(1em + ${theme.spacing(4)})`,
|
||||||
|
transition: theme.transitions.create('width'),
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
function BuscarProducto() {
|
||||||
|
return (
|
||||||
|
<Box sx={{ flexGrow: 1 }}>
|
||||||
|
<div
|
||||||
|
className='bg-white'>
|
||||||
|
<Typography className="text-lg font-medium tracking-tight leading-6 truncate"
|
||||||
|
paddingTop={1}
|
||||||
|
paddingLeft={3}
|
||||||
|
>
|
||||||
|
{("Buscar producto")}
|
||||||
|
</Typography>
|
||||||
|
<Toolbar>
|
||||||
|
<Search>
|
||||||
|
<SearchIconWrapper>
|
||||||
|
<FuseSvgIcon
|
||||||
|
className="text-48 text-black"
|
||||||
|
size={24}
|
||||||
|
color="action"
|
||||||
|
>
|
||||||
|
heroicons-outline:search
|
||||||
|
</FuseSvgIcon>
|
||||||
|
</SearchIconWrapper>
|
||||||
|
<StyledInputBase
|
||||||
|
placeholder="Buscar Producto"
|
||||||
|
inputProps={{ 'aria-label': 'search' }}
|
||||||
|
/>
|
||||||
|
</Search>
|
||||||
|
</Toolbar>
|
||||||
|
</div>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default BuscarProducto;
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
import FuseSvgIcon from "@fuse/core/FuseSvgIcon";
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
useMediaQuery,
|
||||||
|
useTheme,
|
||||||
|
Dialog,
|
||||||
|
DialogTitle,
|
||||||
|
DialogContent,
|
||||||
|
DialogContentText,
|
||||||
|
DialogActions,
|
||||||
|
IconButton,
|
||||||
|
} from "@mui/material";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
function ResponsiveDialog() {
|
||||||
|
const [open, setOpen] = React.useState(false);
|
||||||
|
const theme = useTheme();
|
||||||
|
const fullScreen = useMediaQuery(theme.breakpoints.down("sm"));
|
||||||
|
|
||||||
|
const handleClickOpen = () => {
|
||||||
|
setOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
setOpen(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<IconButton size="small" color="default"
|
||||||
|
onClick={handleClickOpen}>
|
||||||
|
<FuseSvgIcon>heroicons-outline:trash</FuseSvgIcon>
|
||||||
|
</IconButton>
|
||||||
|
<Dialog
|
||||||
|
fullScreen={fullScreen}
|
||||||
|
open={open}
|
||||||
|
onClose={handleClose}
|
||||||
|
aria-labelledby="responsive-dialog-title"
|
||||||
|
>
|
||||||
|
<DialogTitle id="responsive-dialog-title">{"Confirmar"}</DialogTitle>
|
||||||
|
<DialogContent>
|
||||||
|
<DialogContentText>
|
||||||
|
Este elemento se eliminará permanentemente. ¿Deseas continuar?.
|
||||||
|
</DialogContentText>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button autoFocus onClick={handleClose} color="primary">
|
||||||
|
Cancelar
|
||||||
|
</Button>
|
||||||
|
<Button onClick={handleClose} color="primary" autoFocus>
|
||||||
|
Aceptar
|
||||||
|
</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ResponsiveDialog;
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
type DetalleProductoRow = {
|
||||||
|
artCodigo: number;
|
||||||
|
artNombre: string;
|
||||||
|
artDescripcion: string;
|
||||||
|
artStockMinimo: number;
|
||||||
|
artEstado: any;
|
||||||
|
};
|
||||||
|
|
||||||
|
type DetalleProductoType = {
|
||||||
|
columns: string[];
|
||||||
|
rows: DetalleProductoRow[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DetalleProductoType;
|
||||||
|
|
@ -1,24 +1,9 @@
|
||||||
import { Controller, useForm } from 'react-hook-form';
|
|
||||||
import Button from '@mui/material/Button';
|
|
||||||
import Checkbox from '@mui/material/Checkbox';
|
|
||||||
import FormControl from '@mui/material/FormControl';
|
|
||||||
import FormControlLabel from '@mui/material/FormControlLabel';
|
|
||||||
import TextField from '@mui/material/TextField';
|
|
||||||
import Typography from '@mui/material/Typography';
|
import Typography from '@mui/material/Typography';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import _ from '@lodash';
|
|
||||||
import Paper from '@mui/material/Paper';
|
import Paper from '@mui/material/Paper';
|
||||||
import FuseSvgIcon from '@fuse/core/FuseSvgIcon';
|
|
||||||
import AvatarGroup from '@mui/material/AvatarGroup';
|
|
||||||
import Avatar from '@mui/material/Avatar';
|
|
||||||
import Box from '@mui/material/Box';
|
import Box from '@mui/material/Box';
|
||||||
import { z } from 'zod';
|
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
|
||||||
import Tabs from '@mui/material/Tabs';
|
|
||||||
import Tab from '@mui/material/Tab';
|
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import JwtLoginTab from './tabs/JwtSignInTab';
|
import JwtLoginTab from './tabs/JwtSignInTab';
|
||||||
import FirebaseSignInTab from './tabs/FirebaseSignInTab';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Form Validation Schema
|
* Form Validation Schema
|
||||||
|
|
@ -39,14 +24,9 @@ const tabs = [
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
function SignInPage() {
|
function SignInPage() {
|
||||||
const [selectedTabId, setSelectedTabId] = useState(tabs[0].id);
|
const [selectedTabId, setSelectedTabId] = useState(tabs[0].id);
|
||||||
|
|
||||||
function handleSelectTab(id: string) {
|
|
||||||
setSelectedTabId("jwt");
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex min-w-0 h-screen flex-auto flex-col justify-center items-center sm:justify-center md:p-32">
|
<div className="flex min-w-0 h-screen flex-auto flex-col justify-center items-center sm:justify-center md:p-32">
|
||||||
<Paper className="flex min-h-full w-full overflow-hidden justify-center items-center rounded-0 sm:min-h-auto sm:w-auto sm:rounded-2xl sm:shadow md:w-full md:max-w-6xl">
|
<Paper className="flex min-h-full w-full overflow-hidden justify-center items-center rounded-0 sm:min-h-auto sm:w-auto sm:rounded-2xl sm:shadow md:w-full md:max-w-6xl">
|
||||||
|
|
@ -93,16 +73,17 @@ function SignInPage() {
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</Tabs> */}
|
</Tabs> */}
|
||||||
{selectedTabId === 'jwt' && <JwtLoginTab />}
|
{/* {selectedTabId === 'jwt' && <JwtLoginTab />} */}
|
||||||
|
<JwtLoginTab />
|
||||||
|
|
||||||
{/* {selectedTabId === 'firebase' && <FirebaseSignInTab />} */}
|
{/* {selectedTabId === 'firebase' && <FirebaseSignInTab />} */}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Box
|
<Box
|
||||||
className="relative hidden h-auto justify-center items-center flex-auto p-64 md:flex lg:px-112"
|
className="relative hidden h-auto justify-center items-center flex-auto p-64 md:flex lg:px-112"
|
||||||
sx={{ backgroundColor: 'primary.main' }}>
|
sx={{ backgroundColor: 'primary.main' }}
|
||||||
|
>
|
||||||
<svg
|
<svg
|
||||||
className="pointer-events-none absolute inset-0"
|
className="pointer-events-none absolute inset-0"
|
||||||
viewBox="0 0 960 540"
|
viewBox="0 0 960 540"
|
||||||
|
|
@ -174,14 +155,20 @@ function SignInPage() {
|
||||||
</div>
|
</div>
|
||||||
<div className="flex overflow-hidden items-center mt-4 text-md leading-none text-gray-400">
|
<div className="flex overflow-hidden items-center mt-4 text-md leading-none text-gray-400">
|
||||||
<div>Soporte técnico: 0967722226</div>
|
<div>Soporte técnico: 0967722226</div>
|
||||||
<a aria-label="Chat WhatsApp" href="https://wa.me/967722226/?text=Hola!%20Necesito%20ayuda%20en%20el%20sistema%20de%20facturación">
|
<a
|
||||||
<img className='w-52' alt="Chat WhatsApp" src="assets/images/logo/WhatsApp-Logo.wine.svg" />
|
aria-label="Chat WhatsApp"
|
||||||
|
href="https://wa.me/967722226/?text=Hola!%20Necesito%20ayuda%20en%20el%20sistema%20de%20facturación"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
className="w-52"
|
||||||
|
alt="Chat WhatsApp"
|
||||||
|
src="assets/images/logo/WhatsApp-Logo.wine.svg"
|
||||||
|
/>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex overflow-hidden mt-2 text-md leading-none text-gray-400">
|
<div className="flex overflow-hidden mt-2 text-md leading-none text-gray-400">
|
||||||
<div>Correo eletrónico: info@qsoftec.com</div>
|
<div>Correo eletrónico: info@qsoftec.com</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</Box>
|
</Box>
|
||||||
</Paper>
|
</Paper>
|
||||||
|
|
@ -189,4 +176,4 @@ function SignInPage() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default SignInPage;
|
export default SignInPage;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import Button from '@mui/material/Button';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { Controller, useForm } from 'react-hook-form';
|
import { Controller, useForm } from 'react-hook-form';
|
||||||
import _ from '@lodash';
|
import _ from '@lodash';
|
||||||
import { AxiosError } from 'axios';
|
import axios, { AxiosError } from 'axios';
|
||||||
import FormControl from '@mui/material/FormControl';
|
import FormControl from '@mui/material/FormControl';
|
||||||
import FormControlLabel from '@mui/material/FormControlLabel';
|
import FormControlLabel from '@mui/material/FormControlLabel';
|
||||||
import Checkbox from '@mui/material/Checkbox';
|
import Checkbox from '@mui/material/Checkbox';
|
||||||
|
|
@ -16,7 +16,7 @@ import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
* Form Validation Schema
|
* Form Validation Schema
|
||||||
*/
|
*/
|
||||||
const schema = z.object({
|
const schema = z.object({
|
||||||
email: z.string().email('Debe ingresar un correo válido').nonempty('Debe ingresar un correo'),
|
email: z.string().nonempty('Debe ingresar un correo'),
|
||||||
password: z
|
password: z
|
||||||
.string()
|
.string()
|
||||||
.min(4, 'La contraseña es muy corta, debe ingresar almenos 4 caracteres.')
|
.min(4, 'La contraseña es muy corta, debe ingresar almenos 4 caracteres.')
|
||||||
|
|
@ -47,13 +47,57 @@ function jwtSignInTab() {
|
||||||
const { isValid, dirtyFields, errors } = formState;
|
const { isValid, dirtyFields, errors } = formState;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setValue('email', 'admin@qsoftec.com', { shouldDirty: true, shouldValidate: true });
|
setValue('email', 'andres', { shouldDirty: true, shouldValidate: true });
|
||||||
setValue('password', 'admin', { shouldDirty: true, shouldValidate: true });
|
setValue('password', '1234567Aa', { shouldDirty: true, shouldValidate: true });
|
||||||
}, [setValue]);
|
}, [setValue]);
|
||||||
|
|
||||||
function onSubmit(formData: FormType) {
|
function onSubmit(formData: FormType) {
|
||||||
const { email, password } = formData;
|
const { email, password } = formData;
|
||||||
|
|
||||||
|
/* const data = JSON.stringify({
|
||||||
|
headerIn: {
|
||||||
|
dispositivo: 'WeLaptop',
|
||||||
|
canal: null,
|
||||||
|
medio: null,
|
||||||
|
aplicacion: 'CardControlWeb',
|
||||||
|
tipoTransaccion: '0101001',
|
||||||
|
usuario: 'ADMIN',
|
||||||
|
uuid: '355b8668e50a06cf894e015c850d5bb9dc58a',
|
||||||
|
fechaHora: null,
|
||||||
|
idioma: null,
|
||||||
|
empresa: null,
|
||||||
|
geolocalizacion: '37.4215452, -122.0837541'
|
||||||
|
},
|
||||||
|
bodyIn: {
|
||||||
|
entidad: 'Usuario',
|
||||||
|
tipoConsulta: 1,
|
||||||
|
parametros: {
|
||||||
|
user: 'Nick',
|
||||||
|
password: '21365'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
method: 'post',
|
||||||
|
maxBodyLength: Infinity,
|
||||||
|
url: 'http://services.qsoftec.com:18080/inventario-rs-services-1.0-SNAPSHOT/servicios/autenticacion',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
data
|
||||||
|
};
|
||||||
|
|
||||||
|
axios
|
||||||
|
.request(config)
|
||||||
|
.then((response) => {
|
||||||
|
console.log(response.headers)
|
||||||
|
//console.log(JSON.stringify(response.data));
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.log(error);
|
||||||
|
});
|
||||||
|
*/
|
||||||
jwtService
|
jwtService
|
||||||
.signIn({
|
.signIn({
|
||||||
email,
|
email,
|
||||||
|
|
@ -97,7 +141,7 @@ function jwtSignInTab() {
|
||||||
className="mb-24"
|
className="mb-24"
|
||||||
label="Correo electrónico"
|
label="Correo electrónico"
|
||||||
autoFocus
|
autoFocus
|
||||||
type="email"
|
// type="email"
|
||||||
error={!!errors.email}
|
error={!!errors.email}
|
||||||
helperText={errors?.email?.message}
|
helperText={errors?.email?.message}
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
|
|
|
||||||
|
|
@ -1,53 +1,25 @@
|
||||||
import Typography from '@mui/material/Typography';
|
import Typography from '@mui/material/Typography';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import AvatarGroup from '@mui/material/AvatarGroup';
|
|
||||||
import Avatar from '@mui/material/Avatar';
|
|
||||||
import Box from '@mui/material/Box';
|
import Box from '@mui/material/Box';
|
||||||
import Paper from '@mui/material/Paper';
|
import Paper from '@mui/material/Paper';
|
||||||
import Tabs from '@mui/material/Tabs';
|
|
||||||
import Tab from '@mui/material/Tab';
|
|
||||||
import { useState } from 'react';
|
|
||||||
import _ from '../../../@lodash/@lodash';
|
|
||||||
import JwtSignUpTab from './tabs/JwSignUpTab';
|
import JwtSignUpTab from './tabs/JwSignUpTab';
|
||||||
import FirebaseSignUpTab from './tabs/FirebaseSignUpTab';
|
import FormRegister from './formRegister/FormRegister';
|
||||||
|
|
||||||
const tabs = [
|
|
||||||
{
|
|
||||||
id: 'jwt',
|
|
||||||
title: 'JWT',
|
|
||||||
logo: 'assets/images/logo/jwt.svg',
|
|
||||||
logoClass: 'h-40 p-4 bg-black rounded-12'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'firebase',
|
|
||||||
title: 'Firebase',
|
|
||||||
logo: 'assets/images/logo/firebase.svg',
|
|
||||||
logoClass: 'h-40'
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The sign up page.
|
* The sign up page.
|
||||||
*/
|
*/
|
||||||
function SignUpPage() {
|
function SignUpPage() {
|
||||||
const [selectedTabId, setSelectedTabId] = useState(tabs[0].id);
|
|
||||||
|
|
||||||
function handleSelectTab(id: string) {
|
|
||||||
setSelectedTabId(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex min-w-0 h-screen flex-auto flex-col justify-center items-center sm:justify-center md:p-32">
|
<div className="flex min-w-0 flex-1 flex-col items-center sm:flex-row sm:justify-center md:items-start md:justify-start">
|
||||||
<Paper className="flex min-h-full w-full overflow-hidden rounded-0 sm:min-h-auto sm:w-auto sm:rounded-2xl sm:shadow md:w-full md:max-w-6xl">
|
<Paper className="h-full w-full px-16 py-8 ltr:border-r-1 rtl:border-l-1 sm:h-auto sm:w-auto sm:rounded-2xl sm:p-48 sm:shadow md:flex md:h-full md:w-1/2 md:items-center md:justify-end md:rounded-none md:p-64 md:shadow-none">
|
||||||
<div className="w-full px-16 py-32 ltr:border-r-1 rtl:border-l-1 sm:w-auto sm:p-48 md:p-64">
|
<div className="mx-auto w-full max-w-400 sm:mx-0 sm:w-400">
|
||||||
<div className="mx-auto w-full max-w-320 sm:mx-0 sm:w-320">
|
|
||||||
<img
|
<img
|
||||||
className="w-48"
|
className="w-36"
|
||||||
src="assets/images/logo/logo1.svg"
|
src="assets/images/logo/logo1.svg"
|
||||||
alt="logo"
|
alt="logo"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Typography className="mt-32 text-4xl font-extrabold leading-tight tracking-tight">
|
<Typography className="mt-32 text-3xl font-extrabold leading-tight tracking-tight">
|
||||||
Registrarse
|
Registrarse
|
||||||
</Typography>
|
</Typography>
|
||||||
<div className="mt-2 flex items-baseline font-medium">
|
<div className="mt-2 flex items-baseline font-medium">
|
||||||
|
|
@ -59,120 +31,102 @@ function SignUpPage() {
|
||||||
Inicia sesión
|
Inicia sesión
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
{/*
|
<FormRegister />
|
||||||
<Tabs
|
{/* <JwtSignUpTab /> */}
|
||||||
value={_.findIndex(tabs, { id: selectedTabId })}
|
|
||||||
variant="fullWidth"
|
|
||||||
className="w-full mt-24 mb-32"
|
|
||||||
indicatorColor="secondary"
|
|
||||||
>
|
|
||||||
{tabs.map((item) => (
|
|
||||||
<Tab
|
|
||||||
onClick={() => handleSelectTab(item.id)}
|
|
||||||
key={item.id}
|
|
||||||
icon={
|
|
||||||
<img
|
|
||||||
className={item.logoClass}
|
|
||||||
src={item.logo}
|
|
||||||
alt={item.title}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
className="min-w-0"
|
|
||||||
label={item.title}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</Tabs>
|
|
||||||
*/}
|
|
||||||
<JwtSignUpTab />
|
|
||||||
{/* {selectedTabId === 'firebase' && <FirebaseSignUpTab />}
|
|
||||||
*/} </div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</Paper>
|
||||||
|
|
||||||
<Box
|
<Box
|
||||||
className="relative hidden h-auto justify-center items-center flex-auto p-64 md:flex lg:px-112"
|
className="relative hidden h-full flex-auto items-center justify-center overflow-hidden p-48 md:flex lg:px-112 w-3/5"
|
||||||
sx={{ backgroundColor: 'primary.main' }}>
|
sx={{ backgroundColor: 'primary.main' }}
|
||||||
<svg
|
>
|
||||||
className="pointer-events-none absolute inset-0"
|
<svg
|
||||||
viewBox="0 0 960 540"
|
className="pointer-events-none absolute inset-0"
|
||||||
width="100%"
|
viewBox="0 0 960 540"
|
||||||
height="100%"
|
width="100%"
|
||||||
preserveAspectRatio="xMidYMax slice"
|
height="100%"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
preserveAspectRatio="xMidYMax slice"
|
||||||
>
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
<Box
|
>
|
||||||
component="g"
|
|
||||||
sx={{ color: 'primary.light' }}
|
|
||||||
className="opacity-20"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
strokeWidth="100"
|
|
||||||
>
|
|
||||||
<circle
|
|
||||||
r="234"
|
|
||||||
cx="796"
|
|
||||||
cy="23"
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
</svg>
|
|
||||||
<Box
|
<Box
|
||||||
component="svg"
|
component="g"
|
||||||
className="absolute -right-64 -top-64 opacity-20"
|
|
||||||
sx={{ color: 'primary.light' }}
|
sx={{ color: 'primary.light' }}
|
||||||
viewBox="0 0 220 192"
|
className="opacity-20"
|
||||||
width="220px"
|
|
||||||
height="192px"
|
|
||||||
fill="none"
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeWidth="100"
|
||||||
>
|
>
|
||||||
<defs>
|
<circle
|
||||||
<pattern
|
r="234"
|
||||||
id="837c3e70-6c3a-44e6-8854-cc48c737b659"
|
cx="796"
|
||||||
x="0"
|
cy="23"
|
||||||
y="0"
|
|
||||||
width="20"
|
|
||||||
height="20"
|
|
||||||
patternUnits="userSpaceOnUse"
|
|
||||||
>
|
|
||||||
<rect
|
|
||||||
x="0"
|
|
||||||
y="0"
|
|
||||||
width="4"
|
|
||||||
height="4"
|
|
||||||
fill="currentColor"
|
|
||||||
/>
|
|
||||||
</pattern>
|
|
||||||
</defs>
|
|
||||||
<rect
|
|
||||||
width="220"
|
|
||||||
height="192"
|
|
||||||
fill="url(#837c3e70-6c3a-44e6-8854-cc48c737b659)"
|
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
</svg>
|
||||||
<div className="relative z-10 w-full max-w-2xl">
|
<Box
|
||||||
<img
|
component="svg"
|
||||||
className="w-216 "
|
className="absolute -right-64 -top-64 opacity-20"
|
||||||
src="assets/images/empresa/logoAlphaWC.svg"
|
sx={{ color: 'primary.light' }}
|
||||||
alt="logo"
|
viewBox="0 0 220 192"
|
||||||
/>
|
width="220px"
|
||||||
<div className="text-3xl font-bold leading-loose text-gray-100">
|
height="192px"
|
||||||
<div>Bienvenido al sistema que se encarga de tu facturación electrónica.</div>
|
fill="none"
|
||||||
</div>
|
>
|
||||||
<div className="flex items-center mt-14 text-md leading-none text-gray-400">
|
<defs>
|
||||||
<div>¿Necesitas ayuda? Comunícate con nosotros.</div>
|
<pattern
|
||||||
</div>
|
id="837c3e70-6c3a-44e6-8854-cc48c737b659"
|
||||||
<div className="flex overflow-hidden items-center mt-4 text-md leading-none text-gray-400">
|
x="0"
|
||||||
<div>Soporte técnico: 0967722226</div>
|
y="0"
|
||||||
<a aria-label="Chat WhatsApp" href="https://wa.me/967722226/?text=Hola!%20Necesito%20ayuda%20en%20el%20sistema%20de%20facturación">
|
width="20"
|
||||||
<img className='w-52' alt="Chat WhatsApp" src="assets/images/logo/WhatsApp-Logo.wine.svg" />
|
height="20"
|
||||||
</a>
|
patternUnits="userSpaceOnUse"
|
||||||
</div>
|
>
|
||||||
<div className="flex overflow-hidden mt-2 text-md leading-none text-gray-400">
|
<rect
|
||||||
<div>Correo eletrónico: info@qsoftec.com</div>
|
x="0"
|
||||||
</div>
|
y="0"
|
||||||
|
width="4"
|
||||||
</div>
|
height="4"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
</pattern>
|
||||||
|
</defs>
|
||||||
|
<rect
|
||||||
|
width="220"
|
||||||
|
height="192"
|
||||||
|
fill="url(#837c3e70-6c3a-44e6-8854-cc48c737b659)"
|
||||||
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
</Paper>
|
|
||||||
|
<div className="relative z-10 w-full max-w-2xl">
|
||||||
|
<img
|
||||||
|
className="w-216 "
|
||||||
|
src="assets/images/empresa/logoAlphaWC.svg"
|
||||||
|
alt="logo"
|
||||||
|
/>
|
||||||
|
<div className="text-3xl font-bold leading-loose text-gray-100">
|
||||||
|
<div>Bienvenido al sistema que se encarga de tu facturación electrónica.</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center mt-14 text-md leading-none text-gray-400">
|
||||||
|
<div>¿Necesitas ayuda? Comunícate con nosotros.</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex overflow-hidden items-center mt-4 text-md leading-none text-gray-400">
|
||||||
|
<div>Soporte técnico: 0967722226</div>
|
||||||
|
<a
|
||||||
|
aria-label="Chat WhatsApp"
|
||||||
|
href="https://wa.me/967722226/?text=Hola!%20Necesito%20ayuda%20en%20el%20sistema%20de%20facturación"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
className="w-52"
|
||||||
|
alt="Chat WhatsApp"
|
||||||
|
src="assets/images/logo/WhatsApp-Logo.wine.svg"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div className="flex overflow-hidden mt-2 text-md leading-none text-gray-400">
|
||||||
|
<div>Correo eletrónico: info@qsoftec.com</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Box>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
import { useFormik } from 'formik';
|
||||||
|
import * as Yup from 'yup';
|
||||||
|
import { registerUser } from 'src/app/services/user.service';
|
||||||
|
import { SignUpPayload } from './interface';
|
||||||
|
import FormRegisterRender from './FormRegisterRender';
|
||||||
|
|
||||||
|
function FormRegister() {
|
||||||
|
const formik = useFormik<SignUpPayload>({
|
||||||
|
initialValues: {
|
||||||
|
detCodigo: 0,
|
||||||
|
empCodContribuyente: '',
|
||||||
|
empContacto: '',
|
||||||
|
empDescripcion: '',
|
||||||
|
empDireccion: '',
|
||||||
|
empIdentificacion: '',
|
||||||
|
empLlevaContabilidad: '',
|
||||||
|
empMail: '',
|
||||||
|
empNombreComercial: '',
|
||||||
|
empRazonSocial: '',
|
||||||
|
password: '',
|
||||||
|
passwordConfirm: '',
|
||||||
|
usuNombre: '',
|
||||||
|
usuUsuario: '',
|
||||||
|
rolCodigo: 2
|
||||||
|
},
|
||||||
|
validationSchema: Yup.object({
|
||||||
|
usuUsuario: Yup.string().required('Debe ingresar el usuario'),
|
||||||
|
usuNombre: Yup.string().required('Debe ingresar el nombre de usuario'),
|
||||||
|
detCodigo: Yup.number().test('len', 'Debe Seleccionar una opción', (val: number) => val !== 0),
|
||||||
|
empIdentificacion: Yup.string().required('Debe ingresar el número de identificación'),
|
||||||
|
empRazonSocial: Yup.string().required('Debe ingresar la razón social'),
|
||||||
|
empNombreComercial: Yup.string().required('Debe ingresar el nombre comercial'),
|
||||||
|
empContacto: Yup.string().required('Debe ingresar un contacto'),
|
||||||
|
empDireccion: Yup.string().required('Debe ingresar la dirección'),
|
||||||
|
empMail: Yup.string().email('Debe ingresar un correo válido').required('Debe ingresar un correo'),
|
||||||
|
empCodContribuyente: Yup.string().required('Debe ingresar el codigo'),
|
||||||
|
empDescripcion: Yup.string().required('Debe ingresar una descripción'),
|
||||||
|
empLlevaContabilidad: Yup.string().required('Debe seleccionar una opción'),
|
||||||
|
password: Yup.string()
|
||||||
|
.required('Por favor ingrese su contraseña.')
|
||||||
|
.min(4, 'La contraseña es muy corta, debe ingresar almenos 4 caracteres'),
|
||||||
|
passwordConfirm: Yup.string()
|
||||||
|
.oneOf([Yup.ref('password'), null], 'Las contraseñas no coinciden')
|
||||||
|
.required('Campo Obligatorio')
|
||||||
|
}),
|
||||||
|
onSubmit: (value) => {
|
||||||
|
console.log('first');
|
||||||
|
console.log(value);
|
||||||
|
registerUser(value).then((response) => {
|
||||||
|
console.log(response);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return <FormRegisterRender formik={formik} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default FormRegister;
|
||||||
|
|
@ -0,0 +1,298 @@
|
||||||
|
import { FormikProps } from 'formik';
|
||||||
|
import { Button, MenuItem, TextField } from '@mui/material';
|
||||||
|
import { SignUpPayload } from './interface';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
formik: FormikProps<SignUpPayload>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const tipoEmpresa = [
|
||||||
|
{ detCodigo: 1, detNombre: 'Publica' },
|
||||||
|
{ detCodigo: 3, detNombre: 'Privada' }
|
||||||
|
];
|
||||||
|
function FormRegisterRender({ formik }: Props) {
|
||||||
|
return (
|
||||||
|
<form
|
||||||
|
name="registerForm"
|
||||||
|
noValidate
|
||||||
|
className="mt-20 flex w-full flex-col justify-center"
|
||||||
|
onSubmit={formik.handleSubmit}
|
||||||
|
>
|
||||||
|
<TextField
|
||||||
|
className="mb-10"
|
||||||
|
size="small"
|
||||||
|
label="Usuario"
|
||||||
|
type="text"
|
||||||
|
name="usuUsuario"
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
value={formik.values.usuUsuario}
|
||||||
|
onBlur={formik.handleBlur}
|
||||||
|
error={formik.errors.usuUsuario && formik.touched.usuUsuario}
|
||||||
|
helperText={formik.errors.usuUsuario && formik.touched.usuUsuario ? formik.errors.usuUsuario : false}
|
||||||
|
variant="outlined"
|
||||||
|
required
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
<TextField
|
||||||
|
className="mb-10"
|
||||||
|
size="small"
|
||||||
|
label="Nombre usuario"
|
||||||
|
type="text"
|
||||||
|
name="usuNombre"
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
value={formik.values.usuNombre}
|
||||||
|
onBlur={formik.handleBlur}
|
||||||
|
error={formik.errors.usuNombre && formik.touched.usuNombre}
|
||||||
|
helperText={formik.errors.usuNombre && formik.touched.usuNombre ? formik.errors.usuNombre : false}
|
||||||
|
variant="outlined"
|
||||||
|
required
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextField
|
||||||
|
className="mb-10"
|
||||||
|
size="small"
|
||||||
|
label="Razón social"
|
||||||
|
type="text"
|
||||||
|
name="empRazonSocial"
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
value={formik.values.empRazonSocial}
|
||||||
|
onBlur={formik.handleBlur}
|
||||||
|
error={formik.errors.empRazonSocial && formik.touched.empRazonSocial}
|
||||||
|
helperText={
|
||||||
|
formik.errors.empRazonSocial && formik.touched.empRazonSocial ? formik.errors.empRazonSocial : false
|
||||||
|
}
|
||||||
|
variant="outlined"
|
||||||
|
required
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextField
|
||||||
|
className="mb-10"
|
||||||
|
size="small"
|
||||||
|
label="Nombre comercial"
|
||||||
|
type="text"
|
||||||
|
name="empNombreComercial"
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
value={formik.values.empNombreComercial}
|
||||||
|
onBlur={formik.handleBlur}
|
||||||
|
error={formik.errors.empNombreComercial && formik.touched.empNombreComercial}
|
||||||
|
helperText={
|
||||||
|
formik.errors.empNombreComercial && formik.touched.empNombreComercial
|
||||||
|
? formik.errors.empNombreComercial
|
||||||
|
: false
|
||||||
|
}
|
||||||
|
variant="outlined"
|
||||||
|
required
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextField
|
||||||
|
className="mb-10"
|
||||||
|
size="small"
|
||||||
|
label="Identificacón"
|
||||||
|
type="text"
|
||||||
|
name="empIdentificacion"
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
value={formik.values.empIdentificacion}
|
||||||
|
onBlur={formik.handleBlur}
|
||||||
|
error={formik.errors.empIdentificacion && formik.touched.empIdentificacion}
|
||||||
|
helperText={
|
||||||
|
formik.errors.empIdentificacion && formik.touched.empIdentificacion
|
||||||
|
? formik.errors.empIdentificacion
|
||||||
|
: false
|
||||||
|
}
|
||||||
|
variant="outlined"
|
||||||
|
required
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextField
|
||||||
|
className="mb-10"
|
||||||
|
size="small"
|
||||||
|
select
|
||||||
|
label="Tipo de empresa"
|
||||||
|
name="detCodigo"
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
value={formik.values.detCodigo}
|
||||||
|
onBlur={formik.handleBlur}
|
||||||
|
error={formik.errors.detCodigo && formik.touched.detCodigo}
|
||||||
|
helperText={formik.errors.detCodigo && formik.touched.detCodigo ? formik.errors.detCodigo : false}
|
||||||
|
variant="outlined"
|
||||||
|
required
|
||||||
|
fullWidth
|
||||||
|
>
|
||||||
|
<MenuItem value={0}>Seleccione..</MenuItem>
|
||||||
|
{tipoEmpresa.map((option) => (
|
||||||
|
<MenuItem
|
||||||
|
key={option.detCodigo}
|
||||||
|
value={option.detCodigo}
|
||||||
|
>
|
||||||
|
{option.detNombre}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</TextField>
|
||||||
|
|
||||||
|
<TextField
|
||||||
|
className="mb-10"
|
||||||
|
size="small"
|
||||||
|
label="Contacto"
|
||||||
|
type="text"
|
||||||
|
name="empContacto"
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
value={formik.values.empContacto}
|
||||||
|
onBlur={formik.handleBlur}
|
||||||
|
error={formik.errors.empContacto && formik.touched.empContacto}
|
||||||
|
helperText={formik.errors.empContacto && formik.touched.empContacto ? formik.errors.empContacto : false}
|
||||||
|
variant="outlined"
|
||||||
|
required
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextField
|
||||||
|
className="mb-10"
|
||||||
|
size="small"
|
||||||
|
label="Dirección"
|
||||||
|
type="text"
|
||||||
|
name="empDireccion"
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
value={formik.values.empDireccion}
|
||||||
|
onBlur={formik.handleBlur}
|
||||||
|
error={formik.errors.empDireccion && formik.touched.empDireccion}
|
||||||
|
helperText={
|
||||||
|
formik.errors.empDireccion && formik.touched.empDireccion ? formik.errors.empDireccion : false
|
||||||
|
}
|
||||||
|
variant="outlined"
|
||||||
|
required
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextField
|
||||||
|
className="mb-10"
|
||||||
|
size="small"
|
||||||
|
label="Correo electrónico"
|
||||||
|
type="email"
|
||||||
|
name="empMail"
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
value={formik.values.empMail}
|
||||||
|
onBlur={formik.handleBlur}
|
||||||
|
error={formik.errors.empMail && formik.touched.empMail}
|
||||||
|
helperText={formik.errors.empMail && formik.touched.empMail ? formik.errors.empMail : false}
|
||||||
|
variant="outlined"
|
||||||
|
required
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextField
|
||||||
|
className="mb-10"
|
||||||
|
size="small"
|
||||||
|
label="Codigo de contribuyente"
|
||||||
|
type="text"
|
||||||
|
name="empCodContribuyente"
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
value={formik.values.empCodContribuyente}
|
||||||
|
onBlur={formik.handleBlur}
|
||||||
|
error={formik.errors.empCodContribuyente && formik.touched.empCodContribuyente}
|
||||||
|
helperText={
|
||||||
|
formik.errors.empCodContribuyente && formik.touched.empCodContribuyente
|
||||||
|
? formik.errors.empCodContribuyente
|
||||||
|
: false
|
||||||
|
}
|
||||||
|
variant="outlined"
|
||||||
|
required
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextField
|
||||||
|
className="mb-10"
|
||||||
|
size="small"
|
||||||
|
label="Descripción"
|
||||||
|
type="text"
|
||||||
|
name="empDescripcion"
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
value={formik.values.empDescripcion}
|
||||||
|
onBlur={formik.handleBlur}
|
||||||
|
error={formik.errors.empDescripcion && formik.touched.empDescripcion}
|
||||||
|
helperText={
|
||||||
|
formik.errors.empDescripcion && formik.touched.empDescripcion ? formik.errors.empDescripcion : false
|
||||||
|
}
|
||||||
|
variant="outlined"
|
||||||
|
required
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextField
|
||||||
|
className="mb-10"
|
||||||
|
size="small"
|
||||||
|
select
|
||||||
|
label="Lleva la contabilidad"
|
||||||
|
name="empLlevaContabilidad"
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
value={formik.values.empLlevaContabilidad}
|
||||||
|
onBlur={formik.handleBlur}
|
||||||
|
error={formik.errors.empLlevaContabilidad && formik.touched.empLlevaContabilidad}
|
||||||
|
helperText={
|
||||||
|
formik.errors.empLlevaContabilidad && formik.touched.empLlevaContabilidad
|
||||||
|
? formik.errors.empLlevaContabilidad
|
||||||
|
: false
|
||||||
|
}
|
||||||
|
variant="outlined"
|
||||||
|
required
|
||||||
|
fullWidth
|
||||||
|
>
|
||||||
|
<MenuItem value="0">NO</MenuItem>
|
||||||
|
<MenuItem value="1">SI</MenuItem>
|
||||||
|
</TextField>
|
||||||
|
|
||||||
|
<TextField
|
||||||
|
className="mb-10"
|
||||||
|
size="small"
|
||||||
|
label="Contraseña"
|
||||||
|
type="password"
|
||||||
|
name="password"
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
value={formik.values.password}
|
||||||
|
onBlur={formik.handleBlur}
|
||||||
|
error={formik.errors.password && formik.touched.password}
|
||||||
|
helperText={formik.errors.password && formik.touched.password ? formik.errors.password : false}
|
||||||
|
variant="outlined"
|
||||||
|
required
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextField
|
||||||
|
className="mb-10"
|
||||||
|
size="small"
|
||||||
|
label="Confirmar contraseña"
|
||||||
|
type="password"
|
||||||
|
name="passwordConfirm"
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
value={formik.values.passwordConfirm}
|
||||||
|
onBlur={formik.handleBlur}
|
||||||
|
error={formik.errors.passwordConfirm && formik.touched.passwordConfirm}
|
||||||
|
helperText={
|
||||||
|
formik.errors.passwordConfirm && formik.touched.passwordConfirm
|
||||||
|
? formik.errors.passwordConfirm
|
||||||
|
: false
|
||||||
|
}
|
||||||
|
variant="outlined"
|
||||||
|
required
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="secondary"
|
||||||
|
className="mt-24 w-full col-span-2"
|
||||||
|
aria-label="Register"
|
||||||
|
// disabled={_.isEmpty(dirtyFields)}
|
||||||
|
type="submit"
|
||||||
|
size="large"
|
||||||
|
>
|
||||||
|
Registrarse
|
||||||
|
</Button>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default FormRegisterRender;
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
export interface SignUpPayload {
|
||||||
|
usuUsuario: string;
|
||||||
|
usuNombre: string;
|
||||||
|
detCodigo: number;
|
||||||
|
empIdentificacion: string;
|
||||||
|
empRazonSocial: string;
|
||||||
|
empNombreComercial: string;
|
||||||
|
empContacto: string;
|
||||||
|
empDireccion: string;
|
||||||
|
empMail: string;
|
||||||
|
empCodContribuyente: string | number;
|
||||||
|
empDescripcion: string;
|
||||||
|
empLlevaContabilidad: string | number;
|
||||||
|
password: string;
|
||||||
|
passwordConfirm: string;
|
||||||
|
rolCodigo: number;
|
||||||
|
}
|
||||||
|
|
@ -1,28 +1,40 @@
|
||||||
import { Controller, useForm } from 'react-hook-form';
|
import { Controller, useForm } from 'react-hook-form';
|
||||||
import TextField from '@mui/material/TextField';
|
import TextField from '@mui/material/TextField';
|
||||||
import FormControl from '@mui/material/FormControl';
|
|
||||||
import FormControlLabel from '@mui/material/FormControlLabel';
|
|
||||||
import Checkbox from '@mui/material/Checkbox';
|
|
||||||
import FormHelperText from '@mui/material/FormHelperText';
|
|
||||||
import Button from '@mui/material/Button';
|
import Button from '@mui/material/Button';
|
||||||
import _ from '@lodash';
|
import _ from '@lodash';
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import { SignUpPayload, useAuth } from '../../../auth/AuthRouteProvider';
|
import { MenuItem } from '@mui/material';
|
||||||
|
import { SignUpPayload } from '../../../auth/AuthRouteProvider';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Form Validation Schema
|
* Form Validation Schema
|
||||||
*/
|
*/
|
||||||
|
const tipoEmpresa = [
|
||||||
|
{ detCodigo: 1, detNombre: 'Publica' },
|
||||||
|
{ detCodigo: 2, detNombre: 'Privada' }
|
||||||
|
];
|
||||||
|
|
||||||
const schema = z
|
const schema = z
|
||||||
.object({
|
.object({
|
||||||
displayName: z.string().nonempty('Debe ingresar un nombre de usuario'),
|
usuUsuario: z.string().nonempty('Debe ingresar el usuario'),
|
||||||
email: z.string().email('Debe ingresar un correo válido').nonempty('Debe ingresar un correo'),
|
usuNombre: z.string().nonempty('Debe ingresar el nombre de usuario'),
|
||||||
|
detCodigo: z.number().refine((val) => val !== 0, 'Debe Seleccionar una opción'),
|
||||||
|
empIdentificacion: z.string().nonempty('Debe ingresar el número de identificación'),
|
||||||
|
empRazonSocial: z.string().nonempty('Debe ingresar la razón social'),
|
||||||
|
empNombreComercial: z.string().nonempty('Debe ingresar el nombre comercial'),
|
||||||
|
empContacto: z.string().nonempty('Debe ingresar un contacto'),
|
||||||
|
empDireccion: z.string().nonempty('Debe ingresar la dirección'),
|
||||||
|
empMail: z.string().email('Debe ingresar un correo válido').nonempty('Debe ingresar un correo'),
|
||||||
|
empCodContribuyente: z.string().nonempty('Debe ingresar el codigo'),
|
||||||
|
empDescripcion: z.string().nonempty('Debe ingresar una descripción'),
|
||||||
|
empLlevaContabilidad: z.string().nonempty('Debe seleccionar una opción'),
|
||||||
password: z
|
password: z
|
||||||
.string()
|
.string()
|
||||||
.nonempty('Por favor ingrese su contraseña.')
|
.nonempty('Por favor ingrese su contraseña.')
|
||||||
.min(4, 'La contraseña es muy corta, debe ingresar almenos 4 caracteres'),
|
.min(4, 'La contraseña es muy corta, debe ingresar almenos 4 caracteres'),
|
||||||
passwordConfirm: z.string().nonempty('Debe ingresar su contraseña'),
|
passwordConfirm: z.string().nonempty('Debe ingresar su contraseña')
|
||||||
acceptTermsConditions: z.boolean().refine((val) => val === true, 'Debe aceptar los términos y condiciones')
|
// acceptTermsConditions: z.boolean().refine((val) => val === true, 'Debe aceptar los términos y condiciones')
|
||||||
})
|
})
|
||||||
.refine((data) => data.password === data.passwordConfirm, {
|
.refine((data) => data.password === data.passwordConfirm, {
|
||||||
message: 'Contraseñas no coinciden',
|
message: 'Contraseñas no coinciden',
|
||||||
|
|
@ -30,16 +42,24 @@ const schema = z
|
||||||
});
|
});
|
||||||
|
|
||||||
const defaultValues = {
|
const defaultValues = {
|
||||||
displayName: '',
|
usuUsuario: '',
|
||||||
email: '',
|
usuNombre: '',
|
||||||
|
detCodigo: 0,
|
||||||
|
empIdentificacion: '',
|
||||||
|
empRazonSocial: '',
|
||||||
|
empNombreComercial: '',
|
||||||
|
empContacto: '',
|
||||||
|
empDireccion: '',
|
||||||
|
empMail: '',
|
||||||
|
empCodContribuyente: '',
|
||||||
|
empDescripcion: '',
|
||||||
|
empLlevaContabilidad: '',
|
||||||
password: '',
|
password: '',
|
||||||
passwordConfirm: '',
|
passwordConfirm: ''
|
||||||
acceptTermsConditions: false
|
// acceptTermsConditions: false
|
||||||
};
|
};
|
||||||
|
|
||||||
function JwtSignUpTab() {
|
function JwtSignUpTab() {
|
||||||
const { jwtService } = useAuth();
|
|
||||||
|
|
||||||
const { control, formState, handleSubmit, setError } = useForm({
|
const { control, formState, handleSubmit, setError } = useForm({
|
||||||
mode: 'onChange',
|
mode: 'onChange',
|
||||||
defaultValues,
|
defaultValues,
|
||||||
|
|
@ -49,7 +69,8 @@ function JwtSignUpTab() {
|
||||||
const { isValid, dirtyFields, errors } = formState;
|
const { isValid, dirtyFields, errors } = formState;
|
||||||
|
|
||||||
function onSubmit(formData: SignUpPayload) {
|
function onSubmit(formData: SignUpPayload) {
|
||||||
const { displayName, email, password } = formData;
|
console.log(formData);
|
||||||
|
/* const { displayName, email, password } = formData;
|
||||||
jwtService
|
jwtService
|
||||||
.signUp({
|
.signUp({
|
||||||
displayName,
|
displayName,
|
||||||
|
|
@ -63,28 +84,28 @@ function JwtSignUpTab() {
|
||||||
_errors.forEach(({ message, type }) => {
|
_errors.forEach(({ message, type }) => {
|
||||||
setError(type, { type: 'manual', message });
|
setError(type, { type: 'manual', message });
|
||||||
});
|
});
|
||||||
});
|
}); */
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form
|
<form
|
||||||
name="registerForm"
|
name="registerForm"
|
||||||
noValidate
|
noValidate
|
||||||
className="mt-32 flex w-full flex-col justify-center"
|
className="mt-20 flex w-full flex-col justify-center"
|
||||||
onSubmit={handleSubmit(onSubmit)}
|
onSubmit={handleSubmit(onSubmit)}
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="displayName"
|
name="usuUsuario"
|
||||||
control={control}
|
control={control}
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<TextField
|
<TextField
|
||||||
{...field}
|
{...field}
|
||||||
className="mb-24"
|
className="mb-10"
|
||||||
label="Nombre de usuario"
|
size="small"
|
||||||
autoFocus
|
label="Usuario"
|
||||||
type="name"
|
type="text"
|
||||||
error={!!errors.displayName}
|
error={!!errors.usuUsuario}
|
||||||
helperText={errors?.displayName?.message}
|
helperText={errors?.usuUsuario?.message}
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
required
|
required
|
||||||
fullWidth
|
fullWidth
|
||||||
|
|
@ -93,16 +114,17 @@ function JwtSignUpTab() {
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Controller
|
<Controller
|
||||||
name="email"
|
name="usuNombre"
|
||||||
control={control}
|
control={control}
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<TextField
|
<TextField
|
||||||
{...field}
|
{...field}
|
||||||
className="mb-24"
|
className="mb-10"
|
||||||
label="Correo electrónico"
|
size="small"
|
||||||
type="email"
|
label="Nombre usuario"
|
||||||
error={!!errors.email}
|
type="text"
|
||||||
helperText={errors?.email?.message}
|
error={!!errors.usuNombre}
|
||||||
|
helperText={errors?.usuNombre?.message}
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
required
|
required
|
||||||
fullWidth
|
fullWidth
|
||||||
|
|
@ -110,13 +132,199 @@ function JwtSignUpTab() {
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<Controller
|
||||||
|
name="empRazonSocial"
|
||||||
|
control={control}
|
||||||
|
render={({ field }) => (
|
||||||
|
<TextField
|
||||||
|
{...field}
|
||||||
|
className="mb-10"
|
||||||
|
size="small"
|
||||||
|
label="Razón social"
|
||||||
|
autoFocus
|
||||||
|
type="text"
|
||||||
|
error={!!errors.empRazonSocial}
|
||||||
|
helperText={errors?.empRazonSocial?.message}
|
||||||
|
variant="outlined"
|
||||||
|
required
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Controller
|
||||||
|
name="empNombreComercial"
|
||||||
|
control={control}
|
||||||
|
render={({ field }) => (
|
||||||
|
<TextField
|
||||||
|
{...field}
|
||||||
|
className="mb-10"
|
||||||
|
size="small"
|
||||||
|
label="Nombre comercial"
|
||||||
|
type="text"
|
||||||
|
error={!!errors.empNombreComercial}
|
||||||
|
helperText={errors?.empNombreComercial?.message}
|
||||||
|
variant="outlined"
|
||||||
|
required
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Controller
|
||||||
|
name="detCodigo"
|
||||||
|
control={control}
|
||||||
|
render={({ field }) => (
|
||||||
|
<TextField
|
||||||
|
{...field}
|
||||||
|
className="mb-10"
|
||||||
|
size="small"
|
||||||
|
select
|
||||||
|
label="Tipo de empresa"
|
||||||
|
error={!!errors.detCodigo}
|
||||||
|
helperText={errors?.detCodigo?.message}
|
||||||
|
variant="outlined"
|
||||||
|
required
|
||||||
|
fullWidth
|
||||||
|
>
|
||||||
|
<MenuItem value={0}>Seleccione..</MenuItem>
|
||||||
|
{tipoEmpresa.map((option) => (
|
||||||
|
<MenuItem
|
||||||
|
key={option.detCodigo}
|
||||||
|
value={option.detCodigo}
|
||||||
|
>
|
||||||
|
{option.detNombre}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</TextField>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Controller
|
||||||
|
name="empContacto"
|
||||||
|
control={control}
|
||||||
|
render={({ field }) => (
|
||||||
|
<TextField
|
||||||
|
{...field}
|
||||||
|
className="mb-10"
|
||||||
|
size="small"
|
||||||
|
label="Contacto"
|
||||||
|
type="text"
|
||||||
|
error={!!errors.empContacto}
|
||||||
|
helperText={errors?.empContacto?.message}
|
||||||
|
variant="outlined"
|
||||||
|
required
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Controller
|
||||||
|
name="empDireccion"
|
||||||
|
control={control}
|
||||||
|
render={({ field }) => (
|
||||||
|
<TextField
|
||||||
|
{...field}
|
||||||
|
className="mb-10"
|
||||||
|
size="small"
|
||||||
|
label="Dirección"
|
||||||
|
type="text"
|
||||||
|
error={!!errors.empDireccion}
|
||||||
|
helperText={errors?.empDireccion?.message}
|
||||||
|
variant="outlined"
|
||||||
|
required
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Controller
|
||||||
|
name="empMail"
|
||||||
|
control={control}
|
||||||
|
render={({ field }) => (
|
||||||
|
<TextField
|
||||||
|
{...field}
|
||||||
|
className="mb-10"
|
||||||
|
size="small"
|
||||||
|
label="Correo electrónico"
|
||||||
|
type="email"
|
||||||
|
error={!!errors.empMail}
|
||||||
|
helperText={errors?.empMail?.message}
|
||||||
|
variant="outlined"
|
||||||
|
required
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Controller
|
||||||
|
name="empCodContribuyente"
|
||||||
|
control={control}
|
||||||
|
render={({ field }) => (
|
||||||
|
<TextField
|
||||||
|
{...field}
|
||||||
|
className="mb-10"
|
||||||
|
size="small"
|
||||||
|
label="Codigo de contribuyente"
|
||||||
|
type="text"
|
||||||
|
error={!!errors.empCodContribuyente}
|
||||||
|
helperText={errors?.empCodContribuyente?.message}
|
||||||
|
variant="outlined"
|
||||||
|
required
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Controller
|
||||||
|
name="empDescripcion"
|
||||||
|
control={control}
|
||||||
|
render={({ field }) => (
|
||||||
|
<TextField
|
||||||
|
{...field}
|
||||||
|
className="mb-10"
|
||||||
|
size="small"
|
||||||
|
label="Descripción"
|
||||||
|
type="text"
|
||||||
|
error={!!errors.empDescripcion}
|
||||||
|
helperText={errors?.empDescripcion?.message}
|
||||||
|
variant="outlined"
|
||||||
|
required
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Controller
|
||||||
|
name="empLlevaContabilidad"
|
||||||
|
control={control}
|
||||||
|
render={({ field }) => (
|
||||||
|
<TextField
|
||||||
|
{...field}
|
||||||
|
className="mb-10"
|
||||||
|
size="small"
|
||||||
|
select
|
||||||
|
label="Lleva la contabilidad"
|
||||||
|
error={!!errors.empLlevaContabilidad}
|
||||||
|
helperText={errors?.empLlevaContabilidad?.message}
|
||||||
|
variant="outlined"
|
||||||
|
required
|
||||||
|
fullWidth
|
||||||
|
>
|
||||||
|
<MenuItem value="0">NO</MenuItem>
|
||||||
|
<MenuItem value="1">SI</MenuItem>
|
||||||
|
</TextField>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
<Controller
|
<Controller
|
||||||
name="password"
|
name="password"
|
||||||
control={control}
|
control={control}
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<TextField
|
<TextField
|
||||||
{...field}
|
{...field}
|
||||||
className="mb-24"
|
className="mb-10"
|
||||||
|
size="small"
|
||||||
label="Contraseña"
|
label="Contraseña"
|
||||||
type="password"
|
type="password"
|
||||||
error={!!errors.password}
|
error={!!errors.password}
|
||||||
|
|
@ -134,7 +342,8 @@ function JwtSignUpTab() {
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<TextField
|
<TextField
|
||||||
{...field}
|
{...field}
|
||||||
className="mb-24"
|
className="mb-10"
|
||||||
|
size="small"
|
||||||
label="Confirmar contraseña"
|
label="Confirmar contraseña"
|
||||||
type="password"
|
type="password"
|
||||||
error={!!errors.passwordConfirm}
|
error={!!errors.passwordConfirm}
|
||||||
|
|
@ -146,12 +355,12 @@ function JwtSignUpTab() {
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Controller
|
{/* <Controller
|
||||||
name="acceptTermsConditions"
|
name="acceptTermsConditions"
|
||||||
control={control}
|
control={control}
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormControl
|
<FormControl
|
||||||
className="items-center"
|
className="items-center col-span-2"
|
||||||
error={!!errors.acceptTermsConditions}
|
error={!!errors.acceptTermsConditions}
|
||||||
>
|
>
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
|
|
@ -166,14 +375,14 @@ function JwtSignUpTab() {
|
||||||
<FormHelperText>{errors?.acceptTermsConditions?.message}</FormHelperText>
|
<FormHelperText>{errors?.acceptTermsConditions?.message}</FormHelperText>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
)}
|
)}
|
||||||
/>
|
/> */}
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
variant="contained"
|
variant="contained"
|
||||||
color="secondary"
|
color="secondary"
|
||||||
className="mt-24 w-full"
|
className="mt-24 w-full col-span-2"
|
||||||
aria-label="Register"
|
aria-label="Register"
|
||||||
disabled={_.isEmpty(dirtyFields) || !isValid}
|
disabled={_.isEmpty(dirtyFields)}
|
||||||
type="submit"
|
type="submit"
|
||||||
size="large"
|
size="large"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,177 @@
|
||||||
|
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||||
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||||
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||||
|
// import { dispatch } from 'app/store/store';
|
||||||
|
|
||||||
|
import config from 'app/configs/enviroment';
|
||||||
|
// import { displayError } from '../notifications/displayMessage';
|
||||||
|
// import { displayMessage } from 'notifications/displayMessage';
|
||||||
|
// import { logout } from 'store/reducers/auth/auth';
|
||||||
|
|
||||||
|
// eslint-disable-next-line consistent-return
|
||||||
|
const post = (endpoint, body, transId) => {
|
||||||
|
const trama = {
|
||||||
|
headerIn: headerIn(transId),
|
||||||
|
bodyIn: body
|
||||||
|
};
|
||||||
|
const requestOptions = {
|
||||||
|
method: 'POST',
|
||||||
|
headers: header(),
|
||||||
|
body: JSON.stringify(trama),
|
||||||
|
redirect: 'follow'
|
||||||
|
};
|
||||||
|
const apiEndpoints = config.api + endpoint;
|
||||||
|
try {
|
||||||
|
return fetch(apiEndpoints, requestOptions).then(handleResponse);
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const postMultipart = (endpoint, body, transId, files) => {
|
||||||
|
const trama = {
|
||||||
|
headerIn: headerIn(transId),
|
||||||
|
bodyIn: body
|
||||||
|
};
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('0', JSON.stringify(trama));
|
||||||
|
if (files.length > 0) {
|
||||||
|
files.map((file, index) => {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
||||||
|
formData.append(index + 1, file);
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const requestOptions = {
|
||||||
|
method: 'POST',
|
||||||
|
headers: headerM(),
|
||||||
|
body: formData
|
||||||
|
};
|
||||||
|
|
||||||
|
const apiEndpoints = config.api + endpoint;
|
||||||
|
|
||||||
|
return fetch(apiEndpoints, requestOptions).then(handleResponse);
|
||||||
|
};
|
||||||
|
|
||||||
|
const header = () => {
|
||||||
|
const token = localStorage.getItem('token');
|
||||||
|
const myHeaders = new Headers();
|
||||||
|
// eslint-disable-next-line no-unused-expressions
|
||||||
|
token && myHeaders.append('Authorization', `${token}`);
|
||||||
|
myHeaders.append('Content-Type', 'application/json');
|
||||||
|
return myHeaders;
|
||||||
|
};
|
||||||
|
|
||||||
|
const headerM = () => {
|
||||||
|
const token = localStorage.getItem('token');
|
||||||
|
const myHeaders = new Headers();
|
||||||
|
// eslint-disable-next-line no-unused-expressions
|
||||||
|
token && myHeaders.append('Authorization', `${token}`);
|
||||||
|
// myHeaders.append("Content-Type", "application/json");
|
||||||
|
return myHeaders;
|
||||||
|
};
|
||||||
|
|
||||||
|
const headerIn = (transId) => {
|
||||||
|
const user = JSON.parse(localStorage.getItem('user'));
|
||||||
|
const { headerIn } = config;
|
||||||
|
headerIn.tipoTransaccion = transId;
|
||||||
|
if (user) {
|
||||||
|
// headerIn.usuario = user.usuario;
|
||||||
|
headerIn.usuario = user.usercode;
|
||||||
|
} else {
|
||||||
|
headerIn.usuario = 'user-no';
|
||||||
|
}
|
||||||
|
|
||||||
|
return headerIn;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleResponse = (response) => {
|
||||||
|
response.headers.forEach((item,i) => {
|
||||||
|
console.log(item,i)
|
||||||
|
})
|
||||||
|
if (response.status === 401) {
|
||||||
|
localStorage.removeItem('user');
|
||||||
|
localStorage.removeItem('token');
|
||||||
|
// return dispatch(logout());
|
||||||
|
}
|
||||||
|
if (!response.ok) {
|
||||||
|
messageStatusCode(response.clone());
|
||||||
|
throw response;
|
||||||
|
} else {
|
||||||
|
let isBlod = false;
|
||||||
|
let isHtml = false;
|
||||||
|
response.headers.forEach((val, key) => {
|
||||||
|
if (key === 'content-disposition') isBlod = true;
|
||||||
|
|
||||||
|
if (val.indexOf('text/html') !== -1) isHtml = true;
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
||||||
|
if (key === 'authorization') localStorage.setItem('accessToken', val);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (isBlod || isHtml) {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
messageStatusCode(response.clone());
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
||||||
|
return response.json().then((data) => data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function messageStatusCode(response) {
|
||||||
|
const code = response.status;
|
||||||
|
let error = false;
|
||||||
|
// eslint-disable-next-line default-case
|
||||||
|
switch (code) {
|
||||||
|
case 200:
|
||||||
|
response.json().then((data) => {
|
||||||
|
if (data.error && data.error.codigo !== '0') {
|
||||||
|
if (data.error.mensaje) {
|
||||||
|
// "ERROR NO CONTROLADO:
|
||||||
|
if (data.error.mensaje.includes('com.stripe.exception.CardException')) {
|
||||||
|
if (data.error.mensaje.includes('Your card has insufficient funds.; code: card_declined')) {
|
||||||
|
// displayError('La transacción no se pudo realizar, fondos insuficientes');
|
||||||
|
} else if (data.error.mensaje.includes('This transaction requires authentication.')) {
|
||||||
|
// displayError('La transacción no se pudo realizar, su tarjeta requiere autentificación');
|
||||||
|
} else {
|
||||||
|
// displayMessage('error', `Error ${data.error.mensaje}`);
|
||||||
|
// displayError(`Error ${data.error.mensaje}`);
|
||||||
|
}
|
||||||
|
} else if (data.error.codigo !== '1002') {
|
||||||
|
// displayMessage('error', data.error.mensaje);
|
||||||
|
// displayError(data.error.mensaje);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 502:
|
||||||
|
error = true;
|
||||||
|
// displayMessage('error', 'Conexión rechazada');
|
||||||
|
// displayError('Connection refused');
|
||||||
|
break;
|
||||||
|
case 500:
|
||||||
|
error = true;
|
||||||
|
// displayError('Internal Error Server');
|
||||||
|
response.json().then((data) => {
|
||||||
|
console.error('sdfsdfsdfds', data);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 405:
|
||||||
|
error = true;
|
||||||
|
// displayError('Failed to load resource');
|
||||||
|
break;
|
||||||
|
case 404:
|
||||||
|
error = true;
|
||||||
|
// displayError('Page not Found');
|
||||||
|
break;
|
||||||
|
case 401:
|
||||||
|
error = true;
|
||||||
|
// displayError('Cierre sesión, su sesión a caducado');
|
||||||
|
}
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
export { post, postMultipart };
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
import { post } from './dataServices';
|
||||||
|
|
||||||
|
export interface RegisterUser {
|
||||||
|
usuUsuario: string;
|
||||||
|
usuNombre: string;
|
||||||
|
usuDescripcion?: string;
|
||||||
|
usuUrlImagen?: string;
|
||||||
|
detCodigo: number;
|
||||||
|
rolCodigo?: number;
|
||||||
|
empIdentificacion: string;
|
||||||
|
empRazonSocial: string;
|
||||||
|
empNombreComercial: string;
|
||||||
|
empContacto: string;
|
||||||
|
empDireccion: string;
|
||||||
|
empMail: string;
|
||||||
|
empCodContribuyente: string | number;
|
||||||
|
empDescripcion: string;
|
||||||
|
empLlevaContabilidad: number | string;
|
||||||
|
password: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const loginIn = (username: string, password: string) => {
|
||||||
|
const body = {
|
||||||
|
tipoConsulta: 1,
|
||||||
|
entidad: 'Usuario',
|
||||||
|
parametros: {
|
||||||
|
user: username,
|
||||||
|
password
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const endpoint = '/autenticacion';
|
||||||
|
return post(endpoint, body, '0101001');
|
||||||
|
};
|
||||||
|
|
||||||
|
export const registerUser = (data: RegisterUser) => {
|
||||||
|
const body = {
|
||||||
|
tipoAccion: 1,
|
||||||
|
entidad: 'Usuario',
|
||||||
|
entidades: [data]
|
||||||
|
};
|
||||||
|
const endpoint = '/accion';
|
||||||
|
return post(endpoint, body, '0101012');
|
||||||
|
};
|
||||||
|
|
@ -27,7 +27,9 @@ export const addAppMiddleware = dynamicInstance.addMiddleware.withTypes<Config>(
|
||||||
const middlewares: Middleware[] = [apiService.middleware, dynamicMiddleware];
|
const middlewares: Middleware[] = [apiService.middleware, dynamicMiddleware];
|
||||||
|
|
||||||
if (process.env.NODE_ENV === 'development') {
|
if (process.env.NODE_ENV === 'development') {
|
||||||
const logger = createLogger({ collapsed: (getState, action, logEntry) => (logEntry ? !logEntry.error : true) });
|
const logger = createLogger({
|
||||||
|
collapsed: (getState, action, logEntry) => (logEntry ? !logEntry.error : true)
|
||||||
|
});
|
||||||
middlewares.push(logger);
|
middlewares.push(logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -61,6 +63,7 @@ export function configureAppStore(initialState?: RootState) {
|
||||||
const store = configureStore({
|
const store = configureStore({
|
||||||
reducer: rootReducer,
|
reducer: rootReducer,
|
||||||
preloadedState: initialState,
|
preloadedState: initialState,
|
||||||
|
devTools: true,
|
||||||
middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(middlewares)
|
middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(middlewares)
|
||||||
}) as Store<RootState>;
|
}) as Store<RootState>;
|
||||||
|
|
||||||
|
|
@ -108,4 +111,6 @@ export const withAppMiddleware = dynamicInstance.withMiddleware.withTypes<Config
|
||||||
|
|
||||||
const store = configureAppStore();
|
const store = configureAppStore();
|
||||||
|
|
||||||
export default store;
|
const { dispatch } = store;
|
||||||
|
|
||||||
|
export {store, dispatch};
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import { useMemo } from 'react';
|
||||||
import { Provider } from 'react-redux';
|
import { Provider } from 'react-redux';
|
||||||
import ErrorBoundary from '@fuse/utils/ErrorBoundary';
|
import ErrorBoundary from '@fuse/utils/ErrorBoundary';
|
||||||
import AppContext from './AppContext';
|
import AppContext from './AppContext';
|
||||||
import store from './store/store';
|
import { store } from './store/store';
|
||||||
|
|
||||||
type ComponentProps = {
|
type ComponentProps = {
|
||||||
name?: string;
|
name?: string;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import { styled, alpha } from '@mui/material/styles';
|
||||||
|
import Box from '@mui/material/Box';
|
||||||
|
import Toolbar from '@mui/material/Toolbar';
|
||||||
|
import IconButton from '@mui/material/IconButton';
|
||||||
|
import Typography from '@mui/material/Typography';
|
||||||
|
import InputBase from '@mui/material/InputBase';
|
||||||
|
import FuseSvgIcon from '@fuse/core/FuseSvgIcon';
|
||||||
|
import FuseSearch from '@fuse/core/FuseSearch';
|
||||||
|
import { Card } from '@mui/material';
|
||||||
|
import { color } from '@mui/system';
|
||||||
|
|
||||||
|
const Search = styled('div')(({ theme }) => ({
|
||||||
|
position: 'relative',
|
||||||
|
borderRadius: theme.shape.borderRadius,
|
||||||
|
backgroundColor: alpha(theme.palette.common.black, 0.06),
|
||||||
|
'&:hover': {
|
||||||
|
/* backgroundColor: alpha(theme.palette.common.white, 0.25), */
|
||||||
|
},
|
||||||
|
width: '100%',
|
||||||
|
[theme.breakpoints.up('sm')]: {
|
||||||
|
/* marginLeft: theme.spacing(), */
|
||||||
|
width: 'auto',
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
const SearchIconWrapper = styled('div')(({ theme }) => ({
|
||||||
|
padding: theme.spacing(0, 2),
|
||||||
|
height: '100%',
|
||||||
|
position: 'absolute',
|
||||||
|
pointerEvents: 'none',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
}));
|
||||||
|
|
||||||
|
const StyledInputBase = styled(InputBase)(({ theme }) => ({
|
||||||
|
color: 'inherit',
|
||||||
|
width: '100%',
|
||||||
|
'& .MuiInputBase-input': {
|
||||||
|
padding: theme.spacing(1, 1, 1, 0),
|
||||||
|
// vertical padding + font size from searchIcon
|
||||||
|
paddingLeft: `calc(1em + ${theme.spacing(4)})`,
|
||||||
|
transition: theme.transitions.create('width'),
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
function BuscarProducto() {
|
||||||
|
return (
|
||||||
|
<Box sx={{ flexGrow: 1 }}>
|
||||||
|
<div
|
||||||
|
className='bg-white'>
|
||||||
|
<Typography className="text-lg font-medium tracking-tight leading-6 truncate"
|
||||||
|
paddingTop={1}
|
||||||
|
paddingLeft={3}
|
||||||
|
>
|
||||||
|
{("Buscar producto")}
|
||||||
|
</Typography>
|
||||||
|
<Toolbar>
|
||||||
|
<Search>
|
||||||
|
<SearchIconWrapper>
|
||||||
|
<FuseSvgIcon
|
||||||
|
className="text-48 text-black"
|
||||||
|
size={24}
|
||||||
|
color="action"
|
||||||
|
>
|
||||||
|
heroicons-outline:search
|
||||||
|
</FuseSvgIcon>
|
||||||
|
</SearchIconWrapper>
|
||||||
|
<StyledInputBase
|
||||||
|
placeholder="Buscar Producto"
|
||||||
|
inputProps={{ 'aria-label': 'search' }}
|
||||||
|
/>
|
||||||
|
</Search>
|
||||||
|
</Toolbar>
|
||||||
|
</div>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default BuscarProducto;
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
import FuseSvgIcon from "@fuse/core/FuseSvgIcon";
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
useMediaQuery,
|
||||||
|
useTheme,
|
||||||
|
Dialog,
|
||||||
|
DialogTitle,
|
||||||
|
DialogContent,
|
||||||
|
DialogContentText,
|
||||||
|
DialogActions,
|
||||||
|
IconButton,
|
||||||
|
} from "@mui/material";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
function ResponsiveDialog() {
|
||||||
|
const [open, setOpen] = React.useState(false);
|
||||||
|
const theme = useTheme();
|
||||||
|
const fullScreen = useMediaQuery(theme.breakpoints.down("sm"));
|
||||||
|
|
||||||
|
const handleClickOpen = () => {
|
||||||
|
setOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
setOpen(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<IconButton size="small" color="default"
|
||||||
|
onClick={handleClickOpen}>
|
||||||
|
<FuseSvgIcon>heroicons-outline:trash</FuseSvgIcon>
|
||||||
|
</IconButton>
|
||||||
|
<Dialog
|
||||||
|
fullScreen={fullScreen}
|
||||||
|
open={open}
|
||||||
|
onClose={handleClose}
|
||||||
|
aria-labelledby="responsive-dialog-title"
|
||||||
|
>
|
||||||
|
<DialogTitle id="responsive-dialog-title">{"Confirmar"}</DialogTitle>
|
||||||
|
<DialogContent>
|
||||||
|
<DialogContentText>
|
||||||
|
Este elemento se eliminará permanentemente. ¿Deseas continuar?.
|
||||||
|
</DialogContentText>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button autoFocus onClick={handleClose} color="primary">
|
||||||
|
Cancelar
|
||||||
|
</Button>
|
||||||
|
<Button onClick={handleClose} color="primary" autoFocus>
|
||||||
|
Aceptar
|
||||||
|
</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ResponsiveDialog;
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
type DetalleProductoRow = {
|
||||||
|
artCodigo: number;
|
||||||
|
artNombre: string;
|
||||||
|
artDescripcion: string;
|
||||||
|
artStockMinimo: number;
|
||||||
|
artEstado: any;
|
||||||
|
};
|
||||||
|
|
||||||
|
type DetalleProductoType = {
|
||||||
|
columns: string[];
|
||||||
|
rows: DetalleProductoRow[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DetalleProductoType;
|
||||||
|
|
@ -17,31 +17,31 @@ table.simple {
|
||||||
}
|
}
|
||||||
|
|
||||||
table.simple thead tr th {
|
table.simple thead tr th {
|
||||||
padding: 16px 8px;
|
/* padding: 16px 16px; */
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
|
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.simple thead tr th:first-child {
|
table.simple thead tr th:first-child {
|
||||||
padding-left: 24px;
|
padding-left: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.simple thead tr th:last-child {
|
table.simple thead tr th:last-child {
|
||||||
padding-right: 24px;
|
padding-right: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.simple tbody tr td {
|
table.simple tbody tr td {
|
||||||
padding: 12px 8px;
|
padding: 12px 12px;
|
||||||
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
|
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
|
||||||
}
|
}
|
||||||
|
|
||||||
table.simple tbody tr td:first-child {
|
table.simple tbody tr td:first-child {
|
||||||
padding-left: 24px;
|
padding-left: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.simple tbody tr td:last-child {
|
table.simple tbody tr td:last-child {
|
||||||
padding-right: 24px;
|
padding-right: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.simple tbody tr:last-child td {
|
table.simple tbody tr:last-child td {
|
||||||
|
|
|
||||||
|
|
@ -48,5 +48,5 @@
|
||||||
"tailwind.config.js",
|
"tailwind.config.js",
|
||||||
"vite.config.mts",
|
"vite.config.mts",
|
||||||
"vite-env.d.ts"
|
"vite-env.d.ts"
|
||||||
],
|
, "src/app/main/producto/.tsx" ],
|
||||||
}
|
}
|
||||||
|
|
|
||||||
68
yarn.lock
68
yarn.lock
|
|
@ -2825,7 +2825,7 @@
|
||||||
resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.11.tgz#56588b17ae8f50c53983a524fc3cc47437969d64"
|
resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.11.tgz#56588b17ae8f50c53983a524fc3cc47437969d64"
|
||||||
integrity sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==
|
integrity sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==
|
||||||
|
|
||||||
"@types/hoist-non-react-statics@*", "@types/hoist-non-react-statics@^3.3.0":
|
"@types/hoist-non-react-statics@*", "@types/hoist-non-react-statics@^3.3.0", "@types/hoist-non-react-statics@^3.3.1":
|
||||||
version "3.3.5"
|
version "3.3.5"
|
||||||
resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz#dab7867ef789d87e2b4b0003c9d65c49cc44a494"
|
resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz#dab7867ef789d87e2b4b0003c9d65c49cc44a494"
|
||||||
integrity sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==
|
integrity sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==
|
||||||
|
|
@ -4243,6 +4243,11 @@ deep-is@^0.1.3:
|
||||||
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
|
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
|
||||||
integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==
|
integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==
|
||||||
|
|
||||||
|
deepmerge@^2.1.1:
|
||||||
|
version "2.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-2.2.1.tgz#5d3ff22a01c00f645405a2fbc17d0778a1801170"
|
||||||
|
integrity sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==
|
||||||
|
|
||||||
define-data-property@^1.0.1, define-data-property@^1.1.1:
|
define-data-property@^1.0.1, define-data-property@^1.1.1:
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.1.tgz#c35f7cd0ab09883480d12ac5cb213715587800b3"
|
resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.1.tgz#c35f7cd0ab09883480d12ac5cb213715587800b3"
|
||||||
|
|
@ -5238,6 +5243,20 @@ form-data@^4.0.0:
|
||||||
combined-stream "^1.0.8"
|
combined-stream "^1.0.8"
|
||||||
mime-types "^2.1.12"
|
mime-types "^2.1.12"
|
||||||
|
|
||||||
|
formik@^2.4.5:
|
||||||
|
version "2.4.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/formik/-/formik-2.4.5.tgz#f899b5b7a6f103a8fabb679823e8fafc7e0ee1b4"
|
||||||
|
integrity sha512-Gxlht0TD3vVdzMDHwkiNZqJ7Mvg77xQNfmBRrNtvzcHZs72TJppSTDKHpImCMJZwcWPBJ8jSQQ95GJzXFf1nAQ==
|
||||||
|
dependencies:
|
||||||
|
"@types/hoist-non-react-statics" "^3.3.1"
|
||||||
|
deepmerge "^2.1.1"
|
||||||
|
hoist-non-react-statics "^3.3.0"
|
||||||
|
lodash "^4.17.21"
|
||||||
|
lodash-es "^4.17.21"
|
||||||
|
react-fast-compare "^2.0.1"
|
||||||
|
tiny-warning "^1.0.2"
|
||||||
|
tslib "^2.0.0"
|
||||||
|
|
||||||
fraction.js@^4.3.6:
|
fraction.js@^4.3.6:
|
||||||
version "4.3.7"
|
version "4.3.7"
|
||||||
resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.3.7.tgz#06ca0085157e42fda7f9e726e79fefc4068840f7"
|
resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.3.7.tgz#06ca0085157e42fda7f9e726e79fefc4068840f7"
|
||||||
|
|
@ -6382,6 +6401,11 @@ locate-path@^6.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
p-locate "^5.0.0"
|
p-locate "^5.0.0"
|
||||||
|
|
||||||
|
lodash-es@^4.17.21:
|
||||||
|
version "4.17.21"
|
||||||
|
resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee"
|
||||||
|
integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==
|
||||||
|
|
||||||
lodash.camelcase@^4.3.0:
|
lodash.camelcase@^4.3.0:
|
||||||
version "4.3.0"
|
version "4.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6"
|
resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6"
|
||||||
|
|
@ -7296,6 +7320,11 @@ prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
|
||||||
object-assign "^4.1.1"
|
object-assign "^4.1.1"
|
||||||
react-is "^16.13.1"
|
react-is "^16.13.1"
|
||||||
|
|
||||||
|
property-expr@^2.0.5:
|
||||||
|
version "2.0.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/property-expr/-/property-expr-2.0.6.tgz#f77bc00d5928a6c748414ad12882e83f24aec1e8"
|
||||||
|
integrity sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==
|
||||||
|
|
||||||
protobufjs@^7.2.4:
|
protobufjs@^7.2.4:
|
||||||
version "7.2.6"
|
version "7.2.6"
|
||||||
resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.2.6.tgz#4a0ccd79eb292717aacf07530a07e0ed20278215"
|
resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.2.6.tgz#4a0ccd79eb292717aacf07530a07e0ed20278215"
|
||||||
|
|
@ -7383,6 +7412,11 @@ react-draft-wysiwyg@1.15.0:
|
||||||
linkify-it "^2.2.0"
|
linkify-it "^2.2.0"
|
||||||
prop-types "^15.7.2"
|
prop-types "^15.7.2"
|
||||||
|
|
||||||
|
react-fast-compare@^2.0.1:
|
||||||
|
version "2.0.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9"
|
||||||
|
integrity sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==
|
||||||
|
|
||||||
react-fast-compare@^3.0.1:
|
react-fast-compare@^3.0.1:
|
||||||
version "3.2.2"
|
version "3.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.2.tgz#929a97a532304ce9fee4bcae44234f1ce2c21d49"
|
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.2.tgz#929a97a532304ce9fee4bcae44234f1ce2c21d49"
|
||||||
|
|
@ -8458,6 +8492,11 @@ throat@^4.1.0:
|
||||||
resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a"
|
resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a"
|
||||||
integrity sha512-wCVxLDcFxw7ujDxaeJC6nfl2XfHJNYs8yUYJnvMgtPEFlttP9tHSfRUv2vBe6C4hkVFPWoP1P6ZccbYjmSEkKA==
|
integrity sha512-wCVxLDcFxw7ujDxaeJC6nfl2XfHJNYs8yUYJnvMgtPEFlttP9tHSfRUv2vBe6C4hkVFPWoP1P6ZccbYjmSEkKA==
|
||||||
|
|
||||||
|
tiny-case@^1.0.3:
|
||||||
|
version "1.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/tiny-case/-/tiny-case-1.0.3.tgz#d980d66bc72b5d5a9ca86fb7c9ffdb9c898ddd03"
|
||||||
|
integrity sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==
|
||||||
|
|
||||||
tiny-warning@^1.0.2:
|
tiny-warning@^1.0.2:
|
||||||
version "1.0.3"
|
version "1.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754"
|
resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754"
|
||||||
|
|
@ -8500,6 +8539,11 @@ to-regex@^3.0.1, to-regex@^3.0.2:
|
||||||
regex-not "^1.0.2"
|
regex-not "^1.0.2"
|
||||||
safe-regex "^1.1.0"
|
safe-regex "^1.1.0"
|
||||||
|
|
||||||
|
toposort@^2.0.2:
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/toposort/-/toposort-2.0.2.tgz#ae21768175d1559d48bef35420b2f4962f09c330"
|
||||||
|
integrity sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==
|
||||||
|
|
||||||
tr46@~0.0.3:
|
tr46@~0.0.3:
|
||||||
version "0.0.3"
|
version "0.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
|
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
|
||||||
|
|
@ -8600,7 +8644,7 @@ tslib@^1.8.1:
|
||||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
|
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
|
||||||
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
|
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
|
||||||
|
|
||||||
tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.0, tslib@^2.4.0, tslib@^2.6.2:
|
tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.0, tslib@^2.4.0, tslib@^2.6.2:
|
||||||
version "2.6.2"
|
version "2.6.2"
|
||||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae"
|
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae"
|
||||||
integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
|
integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
|
||||||
|
|
@ -8629,6 +8673,11 @@ type-fest@^0.20.2:
|
||||||
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4"
|
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4"
|
||||||
integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==
|
integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==
|
||||||
|
|
||||||
|
type-fest@^2.19.0:
|
||||||
|
version "2.19.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b"
|
||||||
|
integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==
|
||||||
|
|
||||||
typed-array-buffer@^1.0.0:
|
typed-array-buffer@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz#18de3e7ed7974b0a729d3feecb94338d1472cd60"
|
resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz#18de3e7ed7974b0a729d3feecb94338d1472cd60"
|
||||||
|
|
@ -8823,6 +8872,11 @@ util@0.12.5:
|
||||||
is-typed-array "^1.1.3"
|
is-typed-array "^1.1.3"
|
||||||
which-typed-array "^1.1.2"
|
which-typed-array "^1.1.2"
|
||||||
|
|
||||||
|
uuid@^9.0.1:
|
||||||
|
version "9.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30"
|
||||||
|
integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==
|
||||||
|
|
||||||
v8-compile-cache-lib@^3.0.1:
|
v8-compile-cache-lib@^3.0.1:
|
||||||
version "3.0.1"
|
version "3.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf"
|
resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf"
|
||||||
|
|
@ -9126,6 +9180,16 @@ yocto-queue@^0.1.0:
|
||||||
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
|
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
|
||||||
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
|
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
|
||||||
|
|
||||||
|
yup@^1.3.3:
|
||||||
|
version "1.3.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/yup/-/yup-1.3.3.tgz#d2f6020ad1679754c5f8178a29243d5447dead04"
|
||||||
|
integrity sha512-v8QwZSsHH2K3/G9WSkp6mZKO+hugKT1EmnMqLNUcfu51HU9MDyhlETT/JgtzprnrnQHPWsjc6MUDMBp/l9fNnw==
|
||||||
|
dependencies:
|
||||||
|
property-expr "^2.0.5"
|
||||||
|
tiny-case "^1.0.3"
|
||||||
|
toposort "^2.0.2"
|
||||||
|
type-fest "^2.19.0"
|
||||||
|
|
||||||
zod@3.22.4:
|
zod@3.22.4:
|
||||||
version "3.22.4"
|
version "3.22.4"
|
||||||
resolved "https://registry.yarnpkg.com/zod/-/zod-3.22.4.tgz#f31c3a9386f61b1f228af56faa9255e845cf3fff"
|
resolved "https://registry.yarnpkg.com/zod/-/zod-3.22.4.tgz#f31c3a9386f61b1f228af56faa9255e845cf3fff"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue