Merge branch 'dev' of https://gitlab.com/kluppsoftware/smart-energia-web into dev
This commit is contained in:
commit
42735388b7
19
package-lock.json
generated
19
package-lock.json
generated
@ -1590,21 +1590,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/caniuse-lite": {
|
|
||||||
"version": "1.0.30001335",
|
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001335.tgz",
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"type": "opencollective",
|
|
||||||
"url": "https://opencollective.com/browserslist"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "tidelift",
|
|
||||||
"url": "https://tidelift.com/funding/github/npm/caniuse-lite"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"license": "CC-BY-4.0"
|
|
||||||
},
|
|
||||||
"node_modules/chalk": {
|
"node_modules/chalk": {
|
||||||
"version": "4.1.2",
|
"version": "4.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||||
@ -5706,10 +5691,6 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz"
|
"resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz"
|
||||||
},
|
},
|
||||||
"caniuse-lite": {
|
|
||||||
"version": "1.0.30001335",
|
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001335.tgz"
|
|
||||||
},
|
|
||||||
"chalk": {
|
"chalk": {
|
||||||
"version": "4.1.2",
|
"version": "4.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev",
|
"dev": "next dev --port=3444",
|
||||||
"build": "next build",
|
"build": "next build",
|
||||||
"start": "next start",
|
"start": "next start",
|
||||||
"lint": "next lint"
|
"lint": "next lint"
|
||||||
|
|||||||
@ -1,34 +1,43 @@
|
|||||||
import Box from '@mui/material/Box';
|
import Box from '@mui/material/Box'
|
||||||
import Checkbox from '@mui/material/Checkbox';
|
import Checkbox from '@mui/material/Checkbox'
|
||||||
import Paper from '@mui/material/Paper';
|
import Paper from '@mui/material/Paper'
|
||||||
import Table from '@mui/material/Table';
|
import Table from '@mui/material/Table'
|
||||||
import TableBody from '@mui/material/TableBody';
|
import TableBody from '@mui/material/TableBody'
|
||||||
import TableCell from '@mui/material/TableCell';
|
import TableCell from '@mui/material/TableCell'
|
||||||
import TableContainer from '@mui/material/TableContainer';
|
import TableContainer from '@mui/material/TableContainer'
|
||||||
import TableHead from '@mui/material/TableHead';
|
import TableHead from '@mui/material/TableHead'
|
||||||
import TablePagination from '@mui/material/TablePagination';
|
import TablePagination from '@mui/material/TablePagination'
|
||||||
import TableRow from '@mui/material/TableRow';
|
import TableRow from '@mui/material/TableRow'
|
||||||
import TableSortLabel from '@mui/material/TableSortLabel';
|
import TableSortLabel from '@mui/material/TableSortLabel'
|
||||||
import { visuallyHidden } from '@mui/utils';
|
import { visuallyHidden } from '@mui/utils'
|
||||||
import { forwardRef, useEffect, useState } from 'react';
|
import { forwardRef, useDeferredValue, useEffect, useState } from 'react'
|
||||||
|
|
||||||
import Image from 'next/image';
|
import Image from 'next/image'
|
||||||
|
|
||||||
import MuiAlert, { AlertProps } from '@mui/material/Alert';
|
import MuiAlert, { AlertProps } from '@mui/material/Alert'
|
||||||
import Snackbar from '@mui/material/Snackbar';
|
import Snackbar from '@mui/material/Snackbar'
|
||||||
|
|
||||||
import Modal from '@mui/material/Modal';
|
import Modal from '@mui/material/Modal'
|
||||||
|
|
||||||
import { FormControl, InputLabel, MenuItem, Select, TextField, Typography } from '@mui/material';
|
import {
|
||||||
import FormData from 'form-data';
|
FormControl,
|
||||||
import { InputUploadView } from '../inputUploadImg/inputUploadView';
|
InputLabel,
|
||||||
|
MenuItem,
|
||||||
|
Select,
|
||||||
|
TextField,
|
||||||
|
Typography
|
||||||
|
} from '@mui/material'
|
||||||
|
import FormData from 'form-data'
|
||||||
|
import { InputUploadView } from '../inputUploadImg/inputUploadView'
|
||||||
|
|
||||||
import { api } from '../../services/api';
|
import { api } from '../../services/api'
|
||||||
import FaqButton1 from '../buttons/faqButton/FaqButton1';
|
import FaqButton1 from '../buttons/faqButton/FaqButton1'
|
||||||
import FaqButton2 from '../buttons/faqButton/FaqButton2';
|
import FaqButton2 from '../buttons/faqButton/FaqButton2'
|
||||||
import { StyledStatus, TableView } from './TableView';
|
import { StyledStatus, TableView } from './TableView'
|
||||||
|
|
||||||
import ReactLoading from 'react-loading';
|
import ReactLoading from 'react-loading'
|
||||||
|
import { sanitizeStringSearch } from '../../utils/stringHelper'
|
||||||
|
import { stableSort } from '../../utils/stableSort'
|
||||||
|
|
||||||
const style = {
|
const style = {
|
||||||
position: 'absolute' as const,
|
position: 'absolute' as const,
|
||||||
@ -42,62 +51,50 @@ const style = {
|
|||||||
boxShadow: 24,
|
boxShadow: 24,
|
||||||
p: 4,
|
p: 4,
|
||||||
overflowY: 'scroll'
|
overflowY: 'scroll'
|
||||||
};
|
}
|
||||||
const Alert = forwardRef<HTMLDivElement, AlertProps>(function Alert(
|
const Alert = forwardRef<HTMLDivElement, AlertProps>(function Alert(
|
||||||
props,
|
props,
|
||||||
ref,
|
ref
|
||||||
) {
|
) {
|
||||||
return <MuiAlert elevation={6} ref={ref} variant="filled" {...props} />;
|
return <MuiAlert elevation={6} ref={ref} variant="filled" {...props} />
|
||||||
});
|
})
|
||||||
|
|
||||||
interface Data {
|
interface Data {
|
||||||
clientCode: number,
|
clientCode: number
|
||||||
name: string,
|
name: string
|
||||||
unity: string,
|
unity: string
|
||||||
status: string,
|
status: string
|
||||||
}
|
}
|
||||||
|
|
||||||
function descendingComparator<T>(a: T, b: T, orderBy: keyof T) {
|
function descendingComparator<T>(a: T, b: T, orderBy: keyof T) {
|
||||||
if (b[orderBy] < a[orderBy]) {
|
if (b[orderBy] < a[orderBy]) {
|
||||||
return -1;
|
return -1
|
||||||
}
|
}
|
||||||
if (b[orderBy] > a[orderBy]) {
|
if (b[orderBy] > a[orderBy]) {
|
||||||
return 1;
|
return 1
|
||||||
}
|
}
|
||||||
return 0;
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
type Order = 'asc' | 'desc';
|
type Order = 'asc' | 'desc'
|
||||||
|
|
||||||
function getComparator<Key extends keyof any>(
|
function getComparator<Key extends keyof any>(
|
||||||
order: Order,
|
order: Order,
|
||||||
orderBy: any,
|
orderBy: any
|
||||||
): (
|
): (
|
||||||
a: { [key in Key]: number | string },
|
a: { [key in Key]: number | string },
|
||||||
b: { [key in Key]: number | string },
|
b: { [key in Key]: number | string }
|
||||||
) => number {
|
) => number {
|
||||||
return order === 'desc'
|
return order === 'desc'
|
||||||
? (a, b) => descendingComparator(a, b, orderBy)
|
? (a, b) => descendingComparator(a, b, orderBy)
|
||||||
: (a, b) => -descendingComparator(a, b, orderBy);
|
: (a, b) => -descendingComparator(a, b, orderBy)
|
||||||
}
|
|
||||||
|
|
||||||
function stableSort<T>(array: any, comparator: (a: T, b: T) => number) {
|
|
||||||
const stabilizedThis = array.map((el, index) => [el, index] as [T, number]);
|
|
||||||
stabilizedThis.sort((a, b) => {
|
|
||||||
const order = comparator(a[0], b[0]);
|
|
||||||
if (order !== 0) {
|
|
||||||
return order;
|
|
||||||
}
|
|
||||||
return a[1] - b[1];
|
|
||||||
});
|
|
||||||
return stabilizedThis.map((el) => el[0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface HeadCell {
|
interface HeadCell {
|
||||||
disablePadding: boolean;
|
disablePadding: boolean
|
||||||
id: keyof Data | string;
|
id: keyof Data | string
|
||||||
label: string;
|
label: string
|
||||||
numeric: boolean;
|
numeric: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const headCells: readonly HeadCell[] = [
|
const headCells: readonly HeadCell[] = [
|
||||||
@ -105,44 +102,70 @@ const headCells: readonly HeadCell[] = [
|
|||||||
id: 'clientCode',
|
id: 'clientCode',
|
||||||
numeric: false,
|
numeric: false,
|
||||||
disablePadding: true,
|
disablePadding: true,
|
||||||
label: 'código do cliente',
|
label: 'código do cliente'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'name',
|
id: 'name',
|
||||||
numeric: false,
|
numeric: false,
|
||||||
disablePadding: false,
|
disablePadding: false,
|
||||||
label: 'name',
|
label: 'name'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'unity',
|
id: 'unity',
|
||||||
numeric: false,
|
numeric: false,
|
||||||
disablePadding: false,
|
disablePadding: false,
|
||||||
label: 'unity',
|
label: 'unity'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'status',
|
id: 'status',
|
||||||
numeric: false,
|
numeric: false,
|
||||||
disablePadding: false,
|
disablePadding: false,
|
||||||
label: 'status',
|
label: 'status'
|
||||||
},
|
}
|
||||||
];
|
]
|
||||||
|
|
||||||
interface EnhancedTableProps {
|
interface EnhancedTableProps {
|
||||||
numSelected: number;
|
numSelected: number
|
||||||
onRequestSort: (event: React.MouseEvent<unknown>, property: keyof Data) => void;
|
onRequestSort: (
|
||||||
onSelectAllClick: (event: React.ChangeEvent<HTMLInputElement>) => void;
|
event: React.MouseEvent<unknown>,
|
||||||
order: Order;
|
property: keyof Data
|
||||||
orderBy: string;
|
) => void
|
||||||
rowCount: number;
|
onSelectAllClick: (event: React.ChangeEvent<HTMLInputElement>) => void
|
||||||
|
order: Order
|
||||||
|
orderBy: string
|
||||||
|
rowCount: number
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ClientsTableInterface {
|
||||||
|
clients: any
|
||||||
|
onChange: any
|
||||||
|
}
|
||||||
|
|
||||||
|
function sortedClients(client, search: string) {
|
||||||
|
search = sanitizeStringSearch(search)
|
||||||
|
|
||||||
|
return client
|
||||||
|
.map(client => ({
|
||||||
|
...client,
|
||||||
|
name: sanitizeStringSearch(client.name),
|
||||||
|
client_id: sanitizeStringSearch(String(client.client_id))
|
||||||
|
}))
|
||||||
|
.filter((client) => client.name.includes(search) || client.client_id.includes(search))
|
||||||
}
|
}
|
||||||
|
|
||||||
function EnhancedTableHead(props: EnhancedTableProps) {
|
function EnhancedTableHead(props: EnhancedTableProps) {
|
||||||
const { onSelectAllClick, order, orderBy, numSelected, rowCount, onRequestSort } =
|
const {
|
||||||
props;
|
onSelectAllClick,
|
||||||
|
order,
|
||||||
|
orderBy,
|
||||||
|
numSelected,
|
||||||
|
rowCount,
|
||||||
|
onRequestSort
|
||||||
|
} = props
|
||||||
const createSortHandler =
|
const createSortHandler =
|
||||||
(property: any) => (event: React.MouseEvent<unknown>) => {
|
(property: any) => (event: React.MouseEvent<unknown>) => {
|
||||||
onRequestSort(event, property);
|
onRequestSort(event, property)
|
||||||
};
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TableHead>
|
<TableHead>
|
||||||
@ -154,14 +177,14 @@ function EnhancedTableHead(props: EnhancedTableProps) {
|
|||||||
checked={rowCount > 0 && numSelected === rowCount}
|
checked={rowCount > 0 && numSelected === rowCount}
|
||||||
onChange={onSelectAllClick}
|
onChange={onSelectAllClick}
|
||||||
inputProps={{
|
inputProps={{
|
||||||
'aria-label': 'select all desserts',
|
'aria-label': 'select all desserts'
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
{headCells.map((headCell) => (
|
{headCells.map((headCell) => (
|
||||||
<TableCell
|
<TableCell
|
||||||
key={headCell.id}
|
key={headCell.id}
|
||||||
align='left'
|
align="left"
|
||||||
padding={headCell.disablePadding ? 'none' : 'normal'}
|
padding={headCell.disablePadding ? 'none' : 'normal'}
|
||||||
sortDirection={orderBy === headCell.id ? order : false}
|
sortDirection={orderBy === headCell.id ? order : false}
|
||||||
>
|
>
|
||||||
@ -181,137 +204,136 @@ function EnhancedTableHead(props: EnhancedTableProps) {
|
|||||||
))}
|
))}
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ClientsTableInterface {
|
export default function ClientTable({
|
||||||
clients: any,
|
clients,
|
||||||
onChange: any
|
onChange
|
||||||
}
|
}: ClientsTableInterface) {
|
||||||
|
const [order, setOrder] = useState<Order>('asc')
|
||||||
|
const [orderBy, setOrderBy] = useState<keyof Data | string>('asc')
|
||||||
|
const [selected, setSelected] = useState<readonly string[]>([])
|
||||||
|
const [page, setPage] = useState<number>(0)
|
||||||
|
const [dense, setDense] = useState<boolean>(false)
|
||||||
|
const [rowsPerPage, setRowsPerPage] = useState<number>(5)
|
||||||
|
|
||||||
export default function ClientTable({ clients, onChange }: ClientsTableInterface) {
|
const [openSnackError, setOpenSnackError] = useState<boolean>(false)
|
||||||
const [order, setOrder] = useState<Order>('asc');
|
|
||||||
const [orderBy, setOrderBy] = useState<keyof Data | string>('asc');
|
|
||||||
const [selected, setSelected] = useState<readonly string[]>([]);
|
|
||||||
const [page, setPage] = useState<number>(0);
|
|
||||||
const [dense, setDense] = useState<boolean>(false);
|
|
||||||
const [rowsPerPage, setRowsPerPage] = useState<number>(5);
|
|
||||||
|
|
||||||
const [openSnackError, setOpenSnackError] = useState<boolean>(false);
|
const [open, setOpen] = useState(false)
|
||||||
|
|
||||||
const [open, setOpen] = useState(false);
|
|
||||||
const [openModalInativar, setOpenModalInativar] = useState(false)
|
const [openModalInativar, setOpenModalInativar] = useState(false)
|
||||||
const handleOpen = () => setOpen(true);
|
const [clientEdit, setClientEdit] = useState<any>()
|
||||||
const handleClose = () => setOpen(false);
|
const [logo, setLogo] = useState(false)
|
||||||
|
const [imageURLS, setImageURLs] = useState([])
|
||||||
|
const [images, setImages] = useState([] as any)
|
||||||
|
const [nivelAcess, setnivelAcess] = useState<any>(2)
|
||||||
|
const [openEditUserModal, setOpenEditUserModal] = useState<any>(false)
|
||||||
|
const [openSnackSuccess, setOpenSnackSuccess] = useState<boolean>(false)
|
||||||
|
const [loading, setLoading] = useState<boolean>(false)
|
||||||
|
|
||||||
|
const [selectedClient, setSelectedClient] = useState<any>(2)
|
||||||
|
const [search, setSearch] = useState('')
|
||||||
const [units, setUnits] = useState([])
|
const [units, setUnits] = useState([])
|
||||||
|
|
||||||
|
// Avoid a layout jump when reaching the last page with empty rows.
|
||||||
|
const emptyRows =
|
||||||
|
page > 0 ? Math.max(0, (1 + page) * rowsPerPage - clients.length) : 0
|
||||||
|
|
||||||
|
const formData = new FormData()
|
||||||
|
|
||||||
|
const listClients = useDeferredValue(
|
||||||
|
sortedClients(stableSort(clients, getComparator(order, orderBy)), search)
|
||||||
|
.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
|
||||||
|
)
|
||||||
|
|
||||||
|
// const handleOpen = () => setOpen(true)
|
||||||
|
const handleClose = () => setOpen(false)
|
||||||
|
|
||||||
function getClientUnits(client_id: number) {
|
function getClientUnits(client_id: number) {
|
||||||
api.post('/units', {
|
api
|
||||||
"filters": [
|
.post('/units', {
|
||||||
{ "type": "=", "field": "dados_cadastrais.cod_smart_cliente", "value": client_id }
|
filters: [
|
||||||
],
|
{
|
||||||
"fields": ["unidade"],
|
type: '=',
|
||||||
"distinct": true
|
field: 'dados_cadastrais.cod_smart_cliente',
|
||||||
}).then(res => setUnits(res.data.data))
|
value: client_id
|
||||||
|
}
|
||||||
|
],
|
||||||
|
fields: ['unidade'],
|
||||||
|
distinct: true
|
||||||
|
})
|
||||||
|
.then((res) => setUnits(res.data.data))
|
||||||
.catch(() => setOpenSnackError(true))
|
.catch(() => setOpenSnackError(true))
|
||||||
|
|
||||||
return units
|
return units
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleCloseSnack = (event?: React.SyntheticEvent | Event, reason?: string) => {
|
const handleCloseSnack = (
|
||||||
|
event?: React.SyntheticEvent | Event,
|
||||||
|
reason?: string
|
||||||
|
) => {
|
||||||
if (reason === 'clickaway') {
|
if (reason === 'clickaway') {
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
setOpenSnackError(false);
|
setOpenSnackError(false)
|
||||||
};
|
}
|
||||||
|
|
||||||
const handleRequestSort = (
|
const handleRequestSort = (
|
||||||
event: React.MouseEvent<unknown>,
|
event: React.MouseEvent<unknown>,
|
||||||
property: keyof Data,
|
property: keyof Data
|
||||||
) => {
|
) => {
|
||||||
const isAsc = orderBy === property && order === 'asc';
|
const isAsc = orderBy === property && order === 'asc'
|
||||||
setOrder(isAsc ? 'desc' : 'asc');
|
setOrder(isAsc ? 'desc' : 'asc')
|
||||||
setOrderBy(property);
|
setOrderBy(property)
|
||||||
};
|
}
|
||||||
|
|
||||||
const handleSelectAllClick = (event: React.ChangeEvent<HTMLInputElement>) => {
|
const handleSelectAllClick = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
if (event.target.checked) {
|
if (event.target.checked) {
|
||||||
const newSelecteds = clients.map((n) => n.name);
|
const newSelecteds = clients.map((n) => n.name)
|
||||||
setSelected(newSelecteds);
|
setSelected(newSelecteds)
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
setSelected([]);
|
setSelected([])
|
||||||
};
|
}
|
||||||
|
|
||||||
const handleClick = (event: React.MouseEvent<unknown>, code: string) => {
|
const handleClick = (event: React.MouseEvent<unknown>, code: string) => {
|
||||||
const selectedIndex = selected.indexOf(code);
|
const selectedIndex = selected.indexOf(code)
|
||||||
let newSelected: readonly string[] = [];
|
let newSelected: readonly string[] = []
|
||||||
|
|
||||||
if (selectedIndex === -1) {
|
if (selectedIndex === -1) {
|
||||||
newSelected = newSelected.concat(selected, code);
|
newSelected = newSelected.concat(selected, code)
|
||||||
} else if (selectedIndex === 0) {
|
} else if (selectedIndex === 0) {
|
||||||
newSelected = newSelected.concat(selected.slice(1));
|
newSelected = newSelected.concat(selected.slice(1))
|
||||||
} else if (selectedIndex === selected.length - 1) {
|
} else if (selectedIndex === selected.length - 1) {
|
||||||
newSelected = newSelected.concat(selected.slice(0, -1));
|
newSelected = newSelected.concat(selected.slice(0, -1))
|
||||||
} else if (selectedIndex > 0) {
|
} else if (selectedIndex > 0) {
|
||||||
newSelected = newSelected.concat(
|
newSelected = newSelected.concat(
|
||||||
selected.slice(0, selectedIndex),
|
selected.slice(0, selectedIndex),
|
||||||
selected.slice(selectedIndex + 1),
|
selected.slice(selectedIndex + 1)
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
setSelected(newSelected);
|
setSelected(newSelected)
|
||||||
};
|
}
|
||||||
|
|
||||||
const handleChangePage = (event: unknown, newPage: number) => {
|
const handleChangePage = (event: unknown, newPage: number) => {
|
||||||
setPage(newPage);
|
setPage(newPage)
|
||||||
};
|
}
|
||||||
|
|
||||||
const handleChangeRowsPerPage = (event: React.ChangeEvent<HTMLInputElement>) => {
|
const handleChangeRowsPerPage = (
|
||||||
setRowsPerPage(parseInt(event.target.value, 10));
|
event: React.ChangeEvent<HTMLInputElement>
|
||||||
setPage(0);
|
) => {
|
||||||
};
|
setRowsPerPage(parseInt(event.target.value, 10))
|
||||||
|
setPage(0)
|
||||||
|
}
|
||||||
|
|
||||||
const isSelected = (code: any) => selected.indexOf(code.toString()) !== -1;
|
const isSelected = (code: any) => selected.indexOf(code.toString()) !== -1
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
onChange(selected)
|
|
||||||
}, [selected])
|
|
||||||
|
|
||||||
// Avoid a layout jump when reaching the last page with empty rows.
|
|
||||||
const emptyRows =
|
|
||||||
page > 0 ? Math.max(0, (1 + page) * rowsPerPage - clients.length) : 0;
|
|
||||||
|
|
||||||
const formData = new FormData()
|
|
||||||
|
|
||||||
const [clientEdit, setClientEdit] = useState<any>()
|
|
||||||
const [logo, setLogo] = useState(false)
|
|
||||||
const [imageURLS, setImageURLs] = useState([])
|
|
||||||
const [images, setImages] = useState([] as any)
|
|
||||||
const [nivelAcess, setnivelAcess] = useState<any>(2);
|
|
||||||
const [openEditUserModal, setOpenEditUserModal] = useState<any>(false);
|
|
||||||
|
|
||||||
const [selectedClient, setSelectedClient] = useState<any>(2);
|
|
||||||
const [search, setSearch] = useState('')
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (images.length < 1) return
|
|
||||||
const newImageUrls: any = []
|
|
||||||
images.forEach((image: any) =>
|
|
||||||
newImageUrls.push(URL.createObjectURL(image))
|
|
||||||
)
|
|
||||||
setImageURLs(newImageUrls)
|
|
||||||
}, [images])
|
|
||||||
|
|
||||||
function onImageChange(e: any) {
|
function onImageChange(e: any) {
|
||||||
setImages([...e.target.files])
|
setImages([...e.target.files])
|
||||||
setLogo(e.target.files[0])
|
setLogo(e.target.files[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
const [openSnackSuccess, setOpenSnackSuccess] = useState<boolean>(false)
|
|
||||||
const [loading, setLoading] = useState<boolean>(false)
|
|
||||||
|
|
||||||
async function handleUpdateClient(props, id) {
|
async function handleUpdateClient(props, id) {
|
||||||
logo && formData.append('file', logo)
|
logo && formData.append('file', logo)
|
||||||
let new_profile_picture
|
let new_profile_picture
|
||||||
@ -337,14 +359,40 @@ export default function ClientTable({ clients, onChange }: ClientsTableInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
onChange(selected)
|
||||||
|
}, [selected])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (images.length < 1) return
|
||||||
|
const newImageUrls: any = []
|
||||||
|
images.forEach((image: any) =>
|
||||||
|
newImageUrls.push(URL.createObjectURL(image))
|
||||||
|
)
|
||||||
|
setImageURLs(newImageUrls)
|
||||||
|
}, [images])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TableView>
|
<TableView>
|
||||||
<Snackbar open={openSnackError} autoHideDuration={4000} onClose={handleCloseSnack}>
|
<Snackbar
|
||||||
<Alert onClose={handleCloseSnack} severity="error" sx={{ width: '100%' }}>
|
open={openSnackError}
|
||||||
|
autoHideDuration={4000}
|
||||||
|
onClose={handleCloseSnack}
|
||||||
|
>
|
||||||
|
<Alert
|
||||||
|
onClose={handleCloseSnack}
|
||||||
|
severity="error"
|
||||||
|
sx={{ width: '100%' }}
|
||||||
|
>
|
||||||
Não foi possivel encontrar unidades do client!
|
Não foi possivel encontrar unidades do client!
|
||||||
</Alert>
|
</Alert>
|
||||||
</Snackbar>
|
</Snackbar>
|
||||||
<TextField onChange={(e) => setSearch(e.target.value)} placeholder='persquisar por nome:' />
|
|
||||||
|
<TextField
|
||||||
|
onChange={(e) => setSearch(e.target.value)}
|
||||||
|
placeholder="Pesquisar por nome:"
|
||||||
|
/>
|
||||||
|
|
||||||
<Paper sx={{ width: '100%', mb: 2 }}>
|
<Paper sx={{ width: '100%', mb: 2 }}>
|
||||||
<TableContainer>
|
<TableContainer>
|
||||||
<Table
|
<Table
|
||||||
@ -361,58 +409,81 @@ export default function ClientTable({ clients, onChange }: ClientsTableInterface
|
|||||||
rowCount={clients.length}
|
rowCount={clients.length}
|
||||||
/>
|
/>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{stableSort(clients, getComparator(order, orderBy))
|
{listClients.map((row, index) => {
|
||||||
.filter(client => client.name.toLowerCase().includes(search.toLowerCase()))
|
const isItemSelected = isSelected(row.id)
|
||||||
.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
|
const labelId = `enhanced-table-checkbox-${index}`
|
||||||
.map((row, index) => {
|
|
||||||
const isItemSelected = isSelected(row.id);
|
|
||||||
const labelId = `enhanced-table-checkbox-${index}`;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TableRow
|
<TableRow
|
||||||
hover
|
hover
|
||||||
onClick={(event) => handleClick(event, row.id.toString())}
|
onClick={(event) => handleClick(event, row.id.toString())}
|
||||||
role="checkbox"
|
role="checkbox"
|
||||||
aria-checked={isItemSelected}
|
aria-checked={isItemSelected}
|
||||||
tabIndex={-1}
|
tabIndex={-1}
|
||||||
key={row.id}
|
key={row.id}
|
||||||
selected={isItemSelected}
|
selected={isItemSelected}
|
||||||
|
>
|
||||||
|
<TableCell padding="checkbox">
|
||||||
|
<Checkbox
|
||||||
|
color="primary"
|
||||||
|
checked={isItemSelected}
|
||||||
|
inputProps={{ 'aria-labelledby': labelId }}
|
||||||
|
/>
|
||||||
|
</TableCell>
|
||||||
|
|
||||||
|
<TableCell
|
||||||
|
component="th"
|
||||||
|
id={labelId}
|
||||||
|
scope="row"
|
||||||
|
padding="none"
|
||||||
>
|
>
|
||||||
<TableCell padding="checkbox">
|
Client - {row.client_id}
|
||||||
<Checkbox
|
</TableCell>
|
||||||
color="primary"
|
|
||||||
checked={isItemSelected}
|
<TableCell
|
||||||
inputProps={{
|
align="left"
|
||||||
'aria-labelledby': labelId,
|
style={{ cursor: 'pointer' }}
|
||||||
}}
|
onClick={() => {
|
||||||
/>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell
|
|
||||||
component="th"
|
|
||||||
id={labelId}
|
|
||||||
scope="row"
|
|
||||||
padding="none"
|
|
||||||
>
|
|
||||||
Client - {row.client_id}
|
|
||||||
</TableCell>
|
|
||||||
<TableCell align="left" style={{ cursor: 'pointer' }} onClick={() => {
|
|
||||||
setOpenEditUserModal(true)
|
setOpenEditUserModal(true)
|
||||||
setSelectedClient(row)
|
setSelectedClient(row)
|
||||||
setClientEdit({ email: row.email, name: row.name, client_id: row.client_id, profile_picture: row.profile_picture })
|
setClientEdit({
|
||||||
}}>{row.name}</TableCell>
|
email: row.email,
|
||||||
<TableCell align="left" style={{ cursor: 'pointer' }} onClick={() => {
|
name: row.name,
|
||||||
|
client_id: row.client_id,
|
||||||
|
profile_picture: row.profile_picture
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{row.name}
|
||||||
|
</TableCell>
|
||||||
|
|
||||||
|
<TableCell
|
||||||
|
align="left"
|
||||||
|
style={{ cursor: 'pointer' }}
|
||||||
|
onClick={() => {
|
||||||
setOpen(true)
|
setOpen(true)
|
||||||
getClientUnits(row.client_id)
|
getClientUnits(row.client_id)
|
||||||
setSelectedClient(row)
|
setSelectedClient(row)
|
||||||
}}>clique aqui para ver as unidades</TableCell>
|
}}
|
||||||
<TableCell align="left"><StyledStatus status={row.deleted_at ? 'inativo' : 'ativo'}> {row.deleted_at ? 'inativo' : 'ativo'}</StyledStatus></TableCell>
|
>
|
||||||
</TableRow>
|
clique aqui para ver as unidades
|
||||||
);
|
</TableCell>
|
||||||
})}
|
|
||||||
|
<TableCell align="left">
|
||||||
|
<StyledStatus
|
||||||
|
status={row.deleted_at ? 'inativo' : 'ativo'}
|
||||||
|
>
|
||||||
|
{' '}
|
||||||
|
{row.deleted_at ? 'inativo' : 'ativo'}
|
||||||
|
</StyledStatus>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
)
|
||||||
|
})}
|
||||||
{emptyRows > 0 && (
|
{emptyRows > 0 && (
|
||||||
<TableRow
|
<TableRow
|
||||||
style={{
|
style={{
|
||||||
height: (dense ? 33 : 53) * emptyRows,
|
height: (dense ? 33 : 53) * emptyRows
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<TableCell colSpan={6} />
|
<TableCell colSpan={6} />
|
||||||
@ -421,6 +492,7 @@ export default function ClientTable({ clients, onChange }: ClientsTableInterface
|
|||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
</TableContainer>
|
</TableContainer>
|
||||||
|
|
||||||
<TablePagination
|
<TablePagination
|
||||||
rowsPerPageOptions={[5, 10, 25]}
|
rowsPerPageOptions={[5, 10, 25]}
|
||||||
component="div"
|
component="div"
|
||||||
@ -431,6 +503,7 @@ export default function ClientTable({ clients, onChange }: ClientsTableInterface
|
|||||||
onRowsPerPageChange={handleChangeRowsPerPage}
|
onRowsPerPageChange={handleChangeRowsPerPage}
|
||||||
/>
|
/>
|
||||||
</Paper>
|
</Paper>
|
||||||
|
|
||||||
<Modal
|
<Modal
|
||||||
open={openEditUserModal}
|
open={openEditUserModal}
|
||||||
onClose={() => setOpenEditUserModal(false)}
|
onClose={() => setOpenEditUserModal(false)}
|
||||||
@ -515,13 +588,15 @@ export default function ClientTable({ clients, onChange }: ClientsTableInterface
|
|||||||
<div className="imgContainer">
|
<div className="imgContainer">
|
||||||
<article>
|
<article>
|
||||||
{imageURLS.map((imageSrc, index) => {
|
{imageURLS.map((imageSrc, index) => {
|
||||||
return <Image
|
return (
|
||||||
src={imageSrc}
|
<Image
|
||||||
key={index}
|
src={imageSrc}
|
||||||
width={30}
|
key={index}
|
||||||
height={30}
|
width={30}
|
||||||
className="image"
|
height={30}
|
||||||
/>
|
className="image"
|
||||||
|
/>
|
||||||
|
)
|
||||||
})}
|
})}
|
||||||
</article>
|
</article>
|
||||||
</div>
|
</div>
|
||||||
@ -543,7 +618,7 @@ export default function ClientTable({ clients, onChange }: ClientsTableInterface
|
|||||||
</div>
|
</div>
|
||||||
</InputUploadView>
|
</InputUploadView>
|
||||||
|
|
||||||
<div className='select'>
|
<div className="select">
|
||||||
<FormControl sx={{ width: 350, ml: 5, mt: 2 }}>
|
<FormControl sx={{ width: 350, ml: 5, mt: 2 }}>
|
||||||
<InputLabel id="demo-select-small">Nivel de acesso</InputLabel>
|
<InputLabel id="demo-select-small">Nivel de acesso</InputLabel>
|
||||||
<Select
|
<Select
|
||||||
@ -551,24 +626,29 @@ export default function ClientTable({ clients, onChange }: ClientsTableInterface
|
|||||||
id="demo-select-small"
|
id="demo-select-small"
|
||||||
value={nivelAcess}
|
value={nivelAcess}
|
||||||
label="Unidade"
|
label="Unidade"
|
||||||
onChange={value => setnivelAcess(value.target.value)}
|
onChange={(value) => setnivelAcess(value.target.value)}
|
||||||
fullWidth
|
fullWidth
|
||||||
>
|
>
|
||||||
<MenuItem value={1}>Administrador</MenuItem>
|
<MenuItem value={1}>Administrador</MenuItem>
|
||||||
<MenuItem value={2}>Cliente</MenuItem>
|
<MenuItem value={2}>Cliente</MenuItem>
|
||||||
|
|
||||||
</Select>
|
</Select>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{!loading && <FaqButton1 title="Cancelar" onClick={() => setOpenEditUserModal(false)} />}
|
{!loading && (
|
||||||
{!loading
|
<FaqButton1
|
||||||
? <FaqButton2
|
title="Cancelar"
|
||||||
|
onClick={() => setOpenEditUserModal(false)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{!loading ? (
|
||||||
|
<FaqButton2
|
||||||
title="Salvar"
|
title="Salvar"
|
||||||
onClick={() => handleUpdateClient(clientEdit, selectedClient.id)}
|
onClick={() => handleUpdateClient(clientEdit, selectedClient.id)}
|
||||||
/>
|
/>
|
||||||
: <ReactLoading type='spin' color='#254f7f' height='5%' width='5%' />
|
) : (
|
||||||
}
|
<ReactLoading type="spin" color="#254f7f" height="5%" width="5%" />
|
||||||
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
@ -579,18 +659,23 @@ export default function ClientTable({ clients, onChange }: ClientsTableInterface
|
|||||||
aria-describedby="modal-modal-description"
|
aria-describedby="modal-modal-description"
|
||||||
>
|
>
|
||||||
<Box sx={style}>
|
<Box sx={style}>
|
||||||
{
|
{units.map((units, index) => {
|
||||||
units.map((units, index) => {
|
return (
|
||||||
return <>
|
<>
|
||||||
<li style={{
|
<li
|
||||||
listStyle: 'none'
|
style={{
|
||||||
}} key={index}>{units.unidade}</li>
|
listStyle: 'none'
|
||||||
|
}}
|
||||||
|
key={index}
|
||||||
|
>
|
||||||
|
{units.unidade}
|
||||||
|
</li>
|
||||||
<hr />
|
<hr />
|
||||||
</>
|
</>
|
||||||
})
|
)
|
||||||
}
|
})}
|
||||||
</Box>
|
</Box>
|
||||||
</Modal>
|
</Modal>
|
||||||
</TableView>
|
</TableView>
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,7 +26,7 @@ export function MyApp({ Component, pageProps, notificationsCount }: AppProps | a
|
|||||||
const rota = router.pathname
|
const rota = router.pathname
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleStart = (url) => {
|
const handleStart = () => {
|
||||||
NProgress.start()
|
NProgress.start()
|
||||||
}
|
}
|
||||||
const handleStop = () => {
|
const handleStop = () => {
|
||||||
@ -79,7 +79,7 @@ export const getServerSideProps: GetServerSideProps = async (ctx) => {
|
|||||||
|
|
||||||
let notificationsCount
|
let notificationsCount
|
||||||
|
|
||||||
await apiClient.post('/download').then(console.log)
|
await apiClient.post('/download')
|
||||||
|
|
||||||
if (!token) {
|
if (!token) {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -1,97 +1,120 @@
|
|||||||
import Box from '@mui/material/Box';
|
import Box from '@mui/material/Box'
|
||||||
import FormControl from '@mui/material/FormControl';
|
import FormControl from '@mui/material/FormControl'
|
||||||
import InputLabel from '@mui/material/InputLabel';
|
import InputLabel from '@mui/material/InputLabel'
|
||||||
import MenuItem from '@mui/material/MenuItem';
|
import MenuItem from '@mui/material/MenuItem'
|
||||||
import Select, { SelectChangeEvent } from '@mui/material/Select';
|
import Select, { SelectChangeEvent } from '@mui/material/Select'
|
||||||
import { GetServerSideProps } from 'next';
|
import { GetServerSideProps } from 'next'
|
||||||
import Head from 'next/head';
|
import Head from 'next/head'
|
||||||
import { parseCookies } from 'nookies';
|
import { parseCookies } from 'nookies'
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react'
|
||||||
|
|
||||||
import BasicButton from '../../components/buttons/basicButton/BasicButton';
|
import BasicButton from '../../components/buttons/basicButton/BasicButton'
|
||||||
import Header from '../../components/header/Header';
|
import Header from '../../components/header/Header'
|
||||||
import PageTitle from '../../components/pageTitle/PageTitle';
|
import PageTitle from '../../components/pageTitle/PageTitle'
|
||||||
import { api } from '../../services/api';
|
import { api } from '../../services/api'
|
||||||
import getAPIClient from '../../services/ssrApi';
|
import getAPIClient from '../../services/ssrApi'
|
||||||
import { TableBodyView, TableHeader, TableView } from '../../styles/layouts/ResumoOperacao/ResumoOperacaoView';
|
import {
|
||||||
|
TableBodyView,
|
||||||
|
TableHeader,
|
||||||
|
TableView
|
||||||
|
} from '../../styles/layouts/ResumoOperacao/ResumoOperacaoView'
|
||||||
|
|
||||||
import Fab from '@mui/material/Fab';
|
import Fab from '@mui/material/Fab'
|
||||||
|
|
||||||
import NavigationIcon from '@mui/icons-material/Navigation';
|
import NavigationIcon from '@mui/icons-material/Navigation'
|
||||||
|
|
||||||
export default function ResumoOperacao({tableData, clients, userName, clientMonth}: any) {
|
export default function ResumoOperacao({
|
||||||
const csvData = tableData;
|
tableData,
|
||||||
|
clients,
|
||||||
const [month, setMonth] = useState('');
|
userName,
|
||||||
const [unidade, setUnidade] = useState(clients[0].cod_smart_unidade);
|
clientMonth
|
||||||
const [tableDataState, setTableDataState] = useState<any>([]);
|
}: any) {
|
||||||
|
const [month, setMonth] = useState('')
|
||||||
|
const [unidade, setUnidade] = useState(clients[0].cod_smart_unidade)
|
||||||
|
const [tableDataState, setTableDataState] = useState<any>([])
|
||||||
|
|
||||||
const { ['user-id']: id } = parseCookies()
|
const { ['user-id']: id } = parseCookies()
|
||||||
|
|
||||||
const handleChangeMonth = (event: SelectChangeEvent) => {
|
const handleChangeMonth = (event: SelectChangeEvent) => {
|
||||||
setMonth(event.target.value);
|
setMonth(event.target.value)
|
||||||
};
|
}
|
||||||
|
|
||||||
const handleChangeUnidade = (event: SelectChangeEvent) => {
|
const handleChangeUnidade = (event: SelectChangeEvent) => {
|
||||||
setUnidade(event.target.value);
|
setUnidade(event.target.value)
|
||||||
};
|
}
|
||||||
|
|
||||||
const [ pageYPosition, setPageYPosition ] = useState(0);
|
const [pageYPosition, setPageYPosition] = useState(0)
|
||||||
|
|
||||||
function getPageYAfterScroll(){
|
function getPageYAfterScroll() {
|
||||||
setPageYPosition(window.scrollY);
|
setPageYPosition(window.scrollY)
|
||||||
}
|
}
|
||||||
|
|
||||||
function downloadCSVFile(csv, filename) {
|
function downloadCSVFile(csv, filename) {
|
||||||
const csv_file = new Blob(["\ufeff",csv], {type: "text/csv"});
|
const csv_file = new Blob(['\ufeff', csv], { type: 'text/csv' })
|
||||||
const download_link = document.createElement("a");
|
const download_link = document.createElement('a')
|
||||||
download_link.download = filename;
|
download_link.download = filename
|
||||||
download_link.href = window.URL.createObjectURL(csv_file);
|
download_link.href = window.URL.createObjectURL(csv_file)
|
||||||
download_link.style.display = "none";
|
download_link.style.display = 'none'
|
||||||
document.body.appendChild(download_link);
|
document.body.appendChild(download_link)
|
||||||
download_link.click();
|
download_link.click()
|
||||||
}
|
}
|
||||||
|
|
||||||
function htmlToCSV(html, filename) {
|
function htmlToCSV(html, filename) {
|
||||||
const data = [];
|
const data = []
|
||||||
const rows = document.querySelectorAll("table tr");
|
const rows = document.querySelectorAll('table tr')
|
||||||
for (let i = 0; i < rows.length; i++) {
|
for (let i = 0; i < rows.length; i++) {
|
||||||
const row = [], cols: any = rows[i].querySelectorAll("td, th");
|
const row = [],
|
||||||
|
cols: any = rows[i].querySelectorAll('td, th')
|
||||||
for (let j = 0; j < cols.length; j++) {
|
for (let j = 0; j < cols.length; j++) {
|
||||||
row.push(cols[j].innerText);
|
row.push(cols[j].innerText)
|
||||||
}
|
}
|
||||||
data.push(row.join(";"));
|
data.push(row.join(';'))
|
||||||
}
|
}
|
||||||
downloadCSVFile(data.join("\n"), filename);
|
downloadCSVFile(data.join('\n'), filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (unidade!=='' || month!==''){
|
if (unidade !== '' || month !== '') {
|
||||||
api.post('/operation/summary', month && !unidade? {
|
api
|
||||||
"filters": [
|
.post(
|
||||||
{"type" : "=", "field": "mes", "value": month}
|
'/operation/summary',
|
||||||
]
|
month && !unidade
|
||||||
} :
|
? {
|
||||||
!month && unidade? {
|
filters: [{ type: '=', field: 'mes', value: month }]
|
||||||
"filters": [
|
}
|
||||||
{"type" : "=", "field": "dados_te.cod_smart_unidade", "value": unidade}
|
: !month && unidade
|
||||||
]
|
? {
|
||||||
} :
|
filters: [
|
||||||
month && unidade? {
|
{
|
||||||
"filters": [
|
type: '=',
|
||||||
{"type" : "=", "field": "mes", "value": month},
|
field: 'dados_te.cod_smart_unidade',
|
||||||
{"type" : "=", "field": "dados_te.cod_smart_unidade", "value": unidade}
|
value: unidade
|
||||||
]
|
}
|
||||||
} : {}
|
]
|
||||||
).then(res => {
|
}
|
||||||
setTableDataState(res.data.data)
|
: month && unidade
|
||||||
})
|
? {
|
||||||
|
filters: [
|
||||||
|
{ type: '=', field: 'mes', value: month },
|
||||||
|
{
|
||||||
|
type: '=',
|
||||||
|
field: 'dados_te.cod_smart_unidade',
|
||||||
|
value: unidade
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
: {}
|
||||||
|
)
|
||||||
|
.then((res) => {
|
||||||
|
setTableDataState(res.data.data)
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
setTableDataState(tableData)
|
setTableDataState(tableData)
|
||||||
}
|
}
|
||||||
}, [month, unidade])
|
}, [month, unidade])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
window?.addEventListener('scroll', getPageYAfterScroll);
|
window?.addEventListener('scroll', getPageYAfterScroll)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -99,15 +122,21 @@ export default function ResumoOperacao({tableData, clients, userName, clientMont
|
|||||||
<Head>
|
<Head>
|
||||||
<title>Smart Energia - Resumo de Operação</title>
|
<title>Smart Energia - Resumo de Operação</title>
|
||||||
</Head>
|
</Head>
|
||||||
|
|
||||||
<Header name={userName}>
|
<Header name={userName}>
|
||||||
<PageTitle title='Resumo de Operações' subtitle='Operações de compra e venda - Mensal' />
|
<PageTitle
|
||||||
|
title="Resumo de Operações"
|
||||||
|
subtitle="Operações de compra e venda - Mensal"
|
||||||
|
/>
|
||||||
</Header>
|
</Header>
|
||||||
|
|
||||||
<TableHeader>
|
<TableHeader>
|
||||||
<article id='select'>
|
<article id="select">
|
||||||
<div className='select'>
|
<div className="select">
|
||||||
<div>
|
<div>
|
||||||
<FormControl fullWidth>
|
<FormControl fullWidth>
|
||||||
<InputLabel id="demo-simple-select-labels">Unidades</InputLabel>
|
<InputLabel id="demo-simple-select-labels">Unidades</InputLabel>
|
||||||
|
|
||||||
<Select
|
<Select
|
||||||
labelId="demo-simple-select-label"
|
labelId="demo-simple-select-label"
|
||||||
id="demo-simple-select"
|
id="demo-simple-select"
|
||||||
@ -116,12 +145,18 @@ export default function ResumoOperacao({tableData, clients, userName, clientMont
|
|||||||
onChange={handleChangeUnidade}
|
onChange={handleChangeUnidade}
|
||||||
fullWidth
|
fullWidth
|
||||||
>
|
>
|
||||||
<MenuItem key={1} value={''}>Todas</MenuItem>
|
<MenuItem key={1} value={''}>
|
||||||
{
|
Todas
|
||||||
clients.map((value) => {
|
</MenuItem>
|
||||||
return <MenuItem key={value.cod_smart_unidade} value={value.cod_smart_unidade}>{value.unidade}</MenuItem>
|
|
||||||
})
|
{clients.map((value) => (
|
||||||
}
|
<MenuItem
|
||||||
|
key={value.cod_smart_unidade}
|
||||||
|
value={value.cod_smart_unidade}
|
||||||
|
>
|
||||||
|
{value.unidade}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</div>
|
</div>
|
||||||
@ -138,68 +173,122 @@ export default function ResumoOperacao({tableData, clients, userName, clientMont
|
|||||||
fullWidth
|
fullWidth
|
||||||
>
|
>
|
||||||
<MenuItem value={''}>Todos</MenuItem>
|
<MenuItem value={''}>Todos</MenuItem>
|
||||||
{
|
{clientMonth
|
||||||
clientMonth.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
if (parseFloat(a.mes.slice(0, 2)) < parseFloat(b.mes.slice(0, 2)))
|
if (
|
||||||
if (parseFloat(a.mes.slice(3, 7)) > parseFloat(b.mes.slice(3, 7))) return -1
|
parseFloat(a.mes.slice(0, 2)) <
|
||||||
else return 1
|
parseFloat(b.mes.slice(0, 2))
|
||||||
if (parseFloat(a.mes.slice(0, 2)) > parseFloat(b.mes.slice(0, 2)))
|
)
|
||||||
if (parseFloat(a.mes.slice(3, 7)) < parseFloat(b.mes.slice(3, 7))) return 1
|
if (
|
||||||
else return -1
|
parseFloat(a.mes.slice(3, 7)) >
|
||||||
|
parseFloat(b.mes.slice(3, 7))
|
||||||
|
)
|
||||||
|
return -1
|
||||||
|
else return 1
|
||||||
|
if (
|
||||||
|
parseFloat(a.mes.slice(0, 2)) >
|
||||||
|
parseFloat(b.mes.slice(0, 2))
|
||||||
|
)
|
||||||
|
if (
|
||||||
|
parseFloat(a.mes.slice(3, 7)) <
|
||||||
|
parseFloat(b.mes.slice(3, 7))
|
||||||
|
)
|
||||||
|
return 1
|
||||||
|
else return -1
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}).map((value) => {
|
|
||||||
return <MenuItem key={value.mes} value={value.mes}>{value.mes}</MenuItem>
|
|
||||||
})
|
})
|
||||||
}
|
.map((value) => {
|
||||||
|
return (
|
||||||
|
<MenuItem key={value.mes} value={value.mes}>
|
||||||
|
{value.mes}
|
||||||
|
</MenuItem>
|
||||||
|
)
|
||||||
|
})}
|
||||||
</Select>
|
</Select>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
<article>
|
<article>
|
||||||
<BasicButton title='Download' onClick={() => {
|
<BasicButton
|
||||||
const html = document.querySelector("table").outerHTML;
|
title="Download"
|
||||||
htmlToCSV(html, "resumo_operacao.csv");
|
onClick={() => {
|
||||||
}}/>
|
const html = document.querySelector('table').outerHTML
|
||||||
|
htmlToCSV(html, 'resumo_operacao.csv')
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</article>
|
</article>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
<TableBodyView>
|
<TableBodyView>
|
||||||
<table className="tg">
|
<table className="tg">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th className='tg-8oo6'>Mês </th>
|
<th className="tg-8oo6">Mês </th>
|
||||||
<th className='tg-8oo6'>Unidade </th>
|
<th className="tg-8oo6">Unidade </th>
|
||||||
<th className='tg-8oo6'>Operação</th>
|
<th className="tg-8oo6">Operação</th>
|
||||||
<th className='tg-8oo6'>Contraparte</th>
|
<th className="tg-8oo6">Contraparte</th>
|
||||||
<th className='tg-8oo6'>Montante (MWh)</th>
|
<th className="tg-8oo6">Montante (MWh)</th>
|
||||||
<th className='tg-8oo6'>Preço(R$/MWh)</th>
|
<th className="tg-8oo6">Preço(R$/MWh)</th>
|
||||||
<th className='tg-8oo6'>Nota Fiscal (R$)</th>
|
<th className="tg-8oo6">Nota Fiscal (R$)</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{
|
{tableDataState?.map((value, index) => {
|
||||||
tableDataState?.map((value, index) => {
|
if (value.mes.slice(4, 7) != '2020')
|
||||||
if (value.mes.slice(4,7) != '2020')
|
return (
|
||||||
return <tr>
|
<tr>
|
||||||
<td key={value.mes} className='tg-gceh'>{value.mes}</td>
|
<td key={value.mes} className="tg-gceh">
|
||||||
<td key={value.cod_smart_unidade} className='tg-gceh'>{value.unidade}</td>
|
{value.mes}
|
||||||
<td key={value.operacao} className='tg-gceh'>{value.nf_c_icms > 0 ? 'Compra' : 'Cessão'}</td>
|
</td>
|
||||||
<td key={value.contraparte} className='tg-gceh'>{value.contraparte}</td>
|
|
||||||
<td key={value.montante_nf} className='tg-gceh'>{parseFloat(value.montante_nf).toLocaleString('pt-br')}</td>
|
<td key={value.cod_smart_unidade} className="tg-gceh">
|
||||||
<td key={value.preco_nf} className='tg-gceh'>{parseFloat(value.preco_nf).toLocaleString('pt-br',{style: 'currency', currency: 'BRL', minimumFractionDigits: 2})}</td>
|
{value.unidade}
|
||||||
<td key={value.nf_c_icms} className='tg-gceh'>{parseFloat(value.nf_c_icms).toLocaleString('pt-br',{style: 'currency', currency: 'BRL', minimumFractionDigits: 2})}</td>
|
</td>
|
||||||
|
|
||||||
|
<td key={value.operacao} className="tg-gceh">
|
||||||
|
{value.nf_c_icms > 0 ? 'Compra' : 'Cessão'}
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td key={value.contraparte} className="tg-gceh">
|
||||||
|
{value.contraparte}
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td key={value.montante_nf} className="tg-gceh">
|
||||||
|
{parseFloat(value.montante_nf).toLocaleString('pt-br')}
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td key={value.preco_nf} className="tg-gceh">
|
||||||
|
{parseFloat(value.preco_nf).toLocaleString('pt-br', {
|
||||||
|
style: 'currency',
|
||||||
|
currency: 'BRL',
|
||||||
|
minimumFractionDigits: 2
|
||||||
|
})}
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td key={value.nf_c_icms} className="tg-gceh">
|
||||||
|
{parseFloat(value.nf_c_icms).toLocaleString('pt-br', {
|
||||||
|
style: 'currency',
|
||||||
|
currency: 'BRL',
|
||||||
|
minimumFractionDigits: 2
|
||||||
|
})}
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
})
|
)
|
||||||
}
|
})}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</TableBodyView>
|
</TableBodyView>
|
||||||
{pageYPosition > 300 && <a href="#select" style={{position: 'fixed', right: '50px', bottom: '100px'}}>
|
{pageYPosition > 300 && (
|
||||||
<Fab aria-label="add">
|
<a
|
||||||
<NavigationIcon />
|
href="#select"
|
||||||
</Fab>
|
style={{ position: 'fixed', right: '50px', bottom: '100px' }}
|
||||||
</a>}
|
>
|
||||||
|
<Fab aria-label="add">
|
||||||
|
<NavigationIcon />
|
||||||
|
</Fab>
|
||||||
|
</a>
|
||||||
|
)}
|
||||||
</TableView>
|
</TableView>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -210,40 +299,48 @@ export const getServerSideProps: GetServerSideProps = async (ctx) => {
|
|||||||
const { ['user-client_id']: client_id } = parseCookies(ctx)
|
const { ['user-client_id']: client_id } = parseCookies(ctx)
|
||||||
const { ['user-name']: userName } = parseCookies(ctx)
|
const { ['user-name']: userName } = parseCookies(ctx)
|
||||||
|
|
||||||
let tableData = [];
|
let tableData = []
|
||||||
let clientMonth = [];
|
let clientMonth = []
|
||||||
|
|
||||||
await apiClient.post('/operation/summary', {
|
await apiClient
|
||||||
"filters": []
|
.post('/operation/summary', {
|
||||||
}).then(res => {
|
filters: []
|
||||||
tableData = res.data.data
|
})
|
||||||
})
|
.then((res) => {
|
||||||
|
tableData = res.data.data
|
||||||
|
})
|
||||||
|
|
||||||
let clients = [];
|
let clients = []
|
||||||
|
|
||||||
await apiClient.post('/operation', {
|
await apiClient
|
||||||
"filters": [
|
.post('/operation', {
|
||||||
{"type" : ">=", "field":"dados_te.mes", "value":1, "interval": "year"}
|
filters: [
|
||||||
],
|
{ type: '>=', field: 'dados_te.mes', value: 1, interval: 'year' }
|
||||||
"fields": ["mes"],
|
],
|
||||||
"distinct": true
|
fields: ['mes'],
|
||||||
}).then(res => {
|
distinct: true
|
||||||
clientMonth = res.data.data
|
})
|
||||||
})
|
.then((res) => {
|
||||||
|
clientMonth = res.data.data
|
||||||
|
})
|
||||||
|
|
||||||
await apiClient.post('/units', {
|
await apiClient
|
||||||
"filters": [
|
.post('/units', {
|
||||||
{"type" : "=", "field": "dados_cadastrais.cod_smart_cliente", "value": client_id},
|
filters: [
|
||||||
{"type" : "not_in", "field": "dados_cadastrais.codigo_scde", "value":["0P"]}
|
{
|
||||||
],
|
type: '=',
|
||||||
"fields": [
|
field: 'dados_cadastrais.cod_smart_cliente',
|
||||||
"unidade",
|
value: client_id
|
||||||
"cod_smart_unidade",
|
},
|
||||||
"codigo_scde"],
|
{ type: 'not_in', field: 'dados_cadastrais.codigo_scde', value: ['0P'] },
|
||||||
"distinct": true
|
{ type: 'order', field: 'dados_cadastrais.cliente', value: ['asc'] },
|
||||||
}).then(res => {
|
],
|
||||||
clients = res.data.data
|
fields: ['unidade', 'cod_smart_unidade', 'codigo_scde'],
|
||||||
})
|
distinct: true
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
clients = res.data.data
|
||||||
|
})
|
||||||
|
|
||||||
if (!token) {
|
if (!token) {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -1,25 +1,31 @@
|
|||||||
import axios from "axios";
|
import axios from 'axios'
|
||||||
import * as express from 'express';
|
import * as express from 'express'
|
||||||
import * as next from 'next';
|
import * as next from 'next'
|
||||||
import { parseCookies } from "nookies";
|
import { parseCookies } from 'nookies'
|
||||||
|
|
||||||
export default function getAPIClient(ctx?: Pick<next.NextPageContext, 'req'> | {
|
|
||||||
req: next.NextApiRequest;
|
|
||||||
} | {
|
|
||||||
req: express.Request;
|
|
||||||
} | null | undefined) {
|
|
||||||
|
|
||||||
|
export default function getAPIClient(
|
||||||
|
ctx?:
|
||||||
|
| Pick<next.NextPageContext, 'req'>
|
||||||
|
| {
|
||||||
|
req: next.NextApiRequest
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
req: express.Request
|
||||||
|
}
|
||||||
|
| null
|
||||||
|
| undefined
|
||||||
|
) {
|
||||||
const { '@smartAuth-token': token } = parseCookies(ctx)
|
const { '@smartAuth-token': token } = parseCookies(ctx)
|
||||||
|
|
||||||
const api = axios.create({
|
const api = axios.create({
|
||||||
baseURL: 'https://api.energiasmart.com.br/api'
|
// baseURL: 'https://api.energiasmart.com.br/api'
|
||||||
// baseURL: 'https://api.energiasmart.klupp.com.br/api'
|
// baseURL: 'https://api.energiasmart.klupp.com.br/api'
|
||||||
|
baseURL: 'http://api-smart.test/api'
|
||||||
})
|
})
|
||||||
|
|
||||||
api.interceptors.request.use(config => {
|
api.interceptors.request.use((config) => {
|
||||||
return config;
|
return config
|
||||||
},
|
})
|
||||||
);
|
|
||||||
|
|
||||||
if (token) {
|
if (token) {
|
||||||
api.defaults.headers['Authorization'] = `Bearer ${token}`
|
api.defaults.headers['Authorization'] = `Bearer ${token}`
|
||||||
|
|||||||
3
src/utils/formatPrice.ts
Normal file
3
src/utils/formatPrice.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export function formatPrice(value: string | number): string {
|
||||||
|
return parseFloat(`${value}`).toLocaleString("pt-BR", { style: "currency", currency: "BRL" });
|
||||||
|
}
|
||||||
18
src/utils/stableSort.ts
Normal file
18
src/utils/stableSort.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
export function stableSort<T = any>(
|
||||||
|
array: any,
|
||||||
|
comparator: (a: T, b: T) => number
|
||||||
|
) {
|
||||||
|
const stabilizedThis = array.map((el, index) => [el, index] as [T, number])
|
||||||
|
|
||||||
|
stabilizedThis.sort((a, b) => {
|
||||||
|
const order = comparator(a[0], b[0])
|
||||||
|
|
||||||
|
if (order !== 0) {
|
||||||
|
return order
|
||||||
|
}
|
||||||
|
|
||||||
|
return a[1] - b[1]
|
||||||
|
})
|
||||||
|
|
||||||
|
return stabilizedThis.map((el) => el[0])
|
||||||
|
}
|
||||||
25
src/utils/stringHelper.ts
Normal file
25
src/utils/stringHelper.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
export function sanitizeStringSearch(value: string): string {
|
||||||
|
return value
|
||||||
|
.trim()
|
||||||
|
.normalize("NFD")
|
||||||
|
.replace(/[\u0300-\u036f]/g, "")
|
||||||
|
.toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function sortedString<T = any>(field: string = "", optionsSorts: Intl.CollatorOptions = {}) {
|
||||||
|
const locale = "pt-BR";
|
||||||
|
|
||||||
|
optionsSorts = {
|
||||||
|
...optionsSorts,
|
||||||
|
sensitivity: optionsSorts?.sensitivity ?? "variant",
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!field) return Intl.Collator(locale, optionsSorts).compare;
|
||||||
|
|
||||||
|
return (a: T, b: T): number =>
|
||||||
|
(a[field as keyof T] as string)?.localeCompare(
|
||||||
|
(b[field as keyof T] as string) ?? "",
|
||||||
|
locale,
|
||||||
|
optionsSorts
|
||||||
|
);
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user