Front completo :D
This commit is contained in:
parent
77058335a3
commit
556a8a2848
|
|
@ -37,8 +37,27 @@ const navigationConfig: FuseNavItemType[] = [
|
||||||
type: 'item',
|
type: 'item',
|
||||||
icon: 'heroicons-outline:clipboard-check',
|
icon: 'heroicons-outline:clipboard-check',
|
||||||
url: 'product/list'
|
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;
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,8 @@ import Error404Page from '../main/404/Error404Page';
|
||||||
import ProjectDashboardAppConfig from '../main/dashboard/project/ProjectDashboardAppConfig';
|
import ProjectDashboardAppConfig from '../main/dashboard/project/ProjectDashboardAppConfig';
|
||||||
import ProductoConfigs from '../main/producto/ProductoConfig';
|
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 = [
|
const routeConfigs: FuseRouteConfigsType = [
|
||||||
SignOutConfig,
|
SignOutConfig,
|
||||||
|
|
@ -17,7 +19,9 @@ const routeConfigs: FuseRouteConfigsType = [
|
||||||
SignUpConfig,
|
SignUpConfig,
|
||||||
ProjectDashboardAppConfig,
|
ProjectDashboardAppConfig,
|
||||||
...ProductoConfigs,
|
...ProductoConfigs,
|
||||||
...InvoiceConfigs
|
...InvoiceConfigs,
|
||||||
|
...ClientConfig,
|
||||||
|
...firmaConfigs
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -19,13 +19,21 @@ function AddClient({ open, setOpen, handleSelectClient }: Props) {
|
||||||
telefono: '',
|
telefono: '',
|
||||||
correo: ''
|
correo: ''
|
||||||
},
|
},
|
||||||
|
|
||||||
validationSchema: Yup.object({
|
validationSchema: Yup.object({
|
||||||
nombreComercial: Yup.string().required('El campo es Obligatorio'),
|
nombreComercial: Yup.string().required('El nombre comercial es requerido'),
|
||||||
razonSocial: Yup.string().required('El campo es Obligatorio'),
|
razonSocial: Yup.string().required('La razón social es requerida'),
|
||||||
identificacion: Yup.string().required('El campo es Obligatorio'),
|
identificacion: Yup.string()
|
||||||
direccion: Yup.string().required('El campo es Obligatorio'),
|
.required('La cédula o RUC es requerida')
|
||||||
telefono: Yup.string().required('El campo es Obligatorio'),
|
.min(10, 'La cédula debe tener 10 digitos')
|
||||||
correo: Yup.string().required('El campo es Obligatorio').email('Correo no valido')
|
.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) => {
|
onSubmit: (value) => {
|
||||||
handleSaveClient(value);
|
handleSaveClient(value);
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ function AddClientRender({ open, setOpen, formik, handleOnChange }: Props) {
|
||||||
>
|
>
|
||||||
<TextField
|
<TextField
|
||||||
size="small"
|
size="small"
|
||||||
label="Identificación"
|
label="Cédula o RUC"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
fullWidth
|
fullWidth
|
||||||
name="identificacion"
|
name="identificacion"
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,7 @@ function ListDetalleProductoRender() {
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<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">
|
||||||
|
|
@ -148,7 +148,7 @@ function ListDetalleProductoRender() {
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case "artEstado": {
|
case "artEstado": {
|
||||||
return (
|
return (
|
||||||
<TableCell key={key} component="th" scope="row">
|
<TableCell key={key} component="th" scope="row" >
|
||||||
<Typography
|
<Typography
|
||||||
className={clsx(
|
className={clsx(
|
||||||
"inline-flex items-center font-bold text-10 px-10 py-2 rounded-full tracking-wide uppercase",
|
"inline-flex items-center font-bold text-10 px-10 py-2 rounded-full tracking-wide uppercase",
|
||||||
|
|
@ -169,21 +169,23 @@ function ListDetalleProductoRender() {
|
||||||
key={key}
|
key={key}
|
||||||
component="th"
|
component="th"
|
||||||
scope="row"
|
scope="row"
|
||||||
className="flex gap-5"
|
className="text-center"
|
||||||
>
|
>
|
||||||
<div>
|
<div className="flex items-center justify-left">
|
||||||
|
<Typography>{value}</Typography>
|
||||||
|
|
||||||
<IconButton size="small" color="inherit">
|
<IconButton size="small" color="inherit">
|
||||||
<FuseSvgIcon>
|
<FuseSvgIcon>
|
||||||
heroicons-outline:pencil-alt
|
heroicons-outline:pencil-alt
|
||||||
</FuseSvgIcon>
|
</FuseSvgIcon>
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<ResponsiveDialog></ResponsiveDialog>
|
<ResponsiveDialog></ResponsiveDialog>
|
||||||
</div>
|
</div>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
return (
|
return (
|
||||||
<TableCell key={key} component="th" scope="row">
|
<TableCell key={key} component="th" scope="row">
|
||||||
|
|
|
||||||
|
|
@ -12,141 +12,214 @@ import {
|
||||||
Grid,
|
Grid,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
import { Formik, Form, Field, ErrorMessage } from "formik";
|
||||||
|
import * as Yup from "yup";
|
||||||
|
|
||||||
const FormularioProductoRender = () => {
|
const FormularioProductoRender = () => {
|
||||||
const [formData, setFormData] = useState({
|
|
||||||
codigo: "",
|
|
||||||
tipo: "",
|
|
||||||
nombre: "",
|
|
||||||
descripcion: "",
|
|
||||||
stockMinimo: "",
|
|
||||||
margenGanancia: "",
|
|
||||||
estado: "",
|
|
||||||
});
|
|
||||||
|
|
||||||
const [datosCargados, setDatosCargados] = useState(false);
|
const [datosCargados, setDatosCargados] = useState(false);
|
||||||
|
|
||||||
const cargarDatosDesdeBD = () => {
|
const validationSchema = Yup.object().shape({
|
||||||
setDatosCargados(true);
|
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 (
|
return (
|
||||||
<Card className="m-20 p-24">
|
<Card className="m-20 p-24">
|
||||||
<CardHeader title="Registro producto" className="text-16 font-bold " />
|
<CardHeader title="Registro producto" className="text-16 font-bold " />
|
||||||
<Divider />
|
<Divider />
|
||||||
<CardContent className="flex">
|
|
||||||
<Grid className="grid grid-cols-1 sm:grid-cols-6 gap-24 w-full min-w-0 p-24">
|
|
||||||
<TextField
|
|
||||||
className="mt-8 mb-16 sm:col-span-3 lg:col-span-3"
|
|
||||||
required
|
|
||||||
label="Código"
|
|
||||||
id="codigo"
|
|
||||||
name="codigo"
|
|
||||||
variant="outlined"
|
|
||||||
fullWidth
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Autocomplete
|
<Formik
|
||||||
className="mt-8 mb-16 sm:col-span-3 lg:col-span-3"
|
initialValues={{
|
||||||
multiple
|
codigo: "",
|
||||||
freeSolo
|
tipo: "",
|
||||||
options={[]}
|
nombre: "",
|
||||||
renderInput={(params) => (
|
estado: "",
|
||||||
<TextField
|
stockMinimo: "",
|
||||||
{...params}
|
margenGanancia: "",
|
||||||
placeholder="Seleccione el tipo de producto"
|
descripcion: "",
|
||||||
label="Tipo"
|
}}
|
||||||
variant="outlined"
|
|
||||||
InputLabelProps={{
|
|
||||||
shrink: true,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<TextField
|
validationSchema={validationSchema}
|
||||||
className="mt-8 mb-16 sm:col-span-3 lg:col-span-3"
|
onSubmit={(values, { setSubmitting }) => {
|
||||||
required
|
console.log(values);
|
||||||
label="Nombre"
|
setSubmitting(false);
|
||||||
id="nombre"
|
}}
|
||||||
name="nombre"
|
|
||||||
variant="outlined"
|
|
||||||
fullWidth
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Autocomplete
|
|
||||||
className="mt-8 mb-16 sm:col-span-3"
|
|
||||||
multiple
|
|
||||||
freeSolo
|
|
||||||
options={["Activo", "Inactivo"]}
|
|
||||||
renderInput={(params) => (
|
|
||||||
<TextField
|
|
||||||
{...params}
|
|
||||||
placeholder="Seleccione el estado del producto"
|
|
||||||
label="Estado"
|
|
||||||
variant="outlined"
|
|
||||||
InputLabelProps={{
|
|
||||||
shrink: true,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<TextField
|
|
||||||
className="mt-8 mb-16 sm:col-span-3 lg:col-span-3"
|
|
||||||
required
|
|
||||||
label="Stock Mínimo"
|
|
||||||
id="stockMinimo"
|
|
||||||
name="stockMinimo"
|
|
||||||
variant="outlined"
|
|
||||||
fullWidth
|
|
||||||
/>
|
|
||||||
|
|
||||||
<TextField
|
|
||||||
className="mt-8 mb-16 sm:col-span-3 md:col-span-3"
|
|
||||||
required
|
|
||||||
label="Margen de Ganancia"
|
|
||||||
id="margenGanancia"
|
|
||||||
name="margenGanancia"
|
|
||||||
variant="outlined"
|
|
||||||
fullWidth
|
|
||||||
/>
|
|
||||||
|
|
||||||
<TextField
|
|
||||||
className="mt-8 mb-16 sm:col-span-6 lg:col-span-6"
|
|
||||||
id="descripcion"
|
|
||||||
label="Descripción"
|
|
||||||
name="descripcion"
|
|
||||||
type="text"
|
|
||||||
multiline
|
|
||||||
rows={5}
|
|
||||||
variant="outlined"
|
|
||||||
fullWidth
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
</CardContent>
|
|
||||||
<CardActions
|
|
||||||
className=""
|
|
||||||
>
|
>
|
||||||
<Button
|
{({ isSubmitting, touched, errors, setFieldTouched }) => (
|
||||||
className="w-320"
|
<Form>
|
||||||
variant="contained"
|
<CardContent className="flex">
|
||||||
size="small"
|
<Grid className="grid grid-cols-1 sm:grid-cols-6 gap-10 w-full min-w-0">
|
||||||
color="secondary"
|
|
||||||
>
|
<div className="mt-20 sm:col-span-3 lg:col-span-3">
|
||||||
Guardar{" "}
|
<Field
|
||||||
</Button>
|
as={TextField}
|
||||||
{datosCargados && (
|
label="Código"
|
||||||
<Button
|
name="codigo"
|
||||||
className="w-320"
|
variant="outlined"
|
||||||
variant="contained"
|
fullWidth
|
||||||
size="small"
|
size="small"
|
||||||
color="primary"
|
error={touched.codigo && !!errors.codigo}
|
||||||
>
|
/>
|
||||||
Actualizar{" "}
|
<ErrorMessage
|
||||||
</Button>
|
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>
|
||||||
)}
|
)}
|
||||||
</CardActions>
|
</Formik>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
Loading…
Reference in New Issue