diff --git a/package-lock.json b/package-lock.json index 6e417c9..8b2b55e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1590,21 +1590,6 @@ "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz", "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": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -5706,10 +5691,6 @@ "version": "1.0.0", "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": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", diff --git a/package.json b/package.json index 8177659..cf01459 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "0.1.0", "private": true, "scripts": { - "dev": "next dev", + "dev": "next dev --port=3444", "build": "next build", "start": "next start", "lint": "next lint" diff --git a/src/components/administrativeTables/ClientsTable.tsx b/src/components/administrativeTables/ClientsTable.tsx index 8ea1290..0b29a02 100644 --- a/src/components/administrativeTables/ClientsTable.tsx +++ b/src/components/administrativeTables/ClientsTable.tsx @@ -1,34 +1,43 @@ -import Box from '@mui/material/Box'; -import Checkbox from '@mui/material/Checkbox'; -import Paper from '@mui/material/Paper'; -import Table from '@mui/material/Table'; -import TableBody from '@mui/material/TableBody'; -import TableCell from '@mui/material/TableCell'; -import TableContainer from '@mui/material/TableContainer'; -import TableHead from '@mui/material/TableHead'; -import TablePagination from '@mui/material/TablePagination'; -import TableRow from '@mui/material/TableRow'; -import TableSortLabel from '@mui/material/TableSortLabel'; -import { visuallyHidden } from '@mui/utils'; -import { forwardRef, useEffect, useState } from 'react'; +import Box from '@mui/material/Box' +import Checkbox from '@mui/material/Checkbox' +import Paper from '@mui/material/Paper' +import Table from '@mui/material/Table' +import TableBody from '@mui/material/TableBody' +import TableCell from '@mui/material/TableCell' +import TableContainer from '@mui/material/TableContainer' +import TableHead from '@mui/material/TableHead' +import TablePagination from '@mui/material/TablePagination' +import TableRow from '@mui/material/TableRow' +import TableSortLabel from '@mui/material/TableSortLabel' +import { visuallyHidden } from '@mui/utils' +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 Snackbar from '@mui/material/Snackbar'; +import MuiAlert, { AlertProps } from '@mui/material/Alert' +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 FormData from 'form-data'; -import { InputUploadView } from '../inputUploadImg/inputUploadView'; +import { + FormControl, + InputLabel, + MenuItem, + Select, + TextField, + Typography +} from '@mui/material' +import FormData from 'form-data' +import { InputUploadView } from '../inputUploadImg/inputUploadView' -import { api } from '../../services/api'; -import FaqButton1 from '../buttons/faqButton/FaqButton1'; -import FaqButton2 from '../buttons/faqButton/FaqButton2'; -import { StyledStatus, TableView } from './TableView'; +import { api } from '../../services/api' +import FaqButton1 from '../buttons/faqButton/FaqButton1' +import FaqButton2 from '../buttons/faqButton/FaqButton2' +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 = { position: 'absolute' as const, @@ -42,62 +51,50 @@ const style = { boxShadow: 24, p: 4, overflowY: 'scroll' -}; +} const Alert = forwardRef(function Alert( props, - ref, + ref ) { - return ; -}); + return +}) interface Data { - clientCode: number, - name: string, - unity: string, - status: string, + clientCode: number + name: string + unity: string + status: string } function descendingComparator(a: T, b: T, orderBy: keyof T) { if (b[orderBy] < a[orderBy]) { - return -1; + return -1 } if (b[orderBy] > a[orderBy]) { - return 1; + return 1 } - return 0; + return 0 } -type Order = 'asc' | 'desc'; +type Order = 'asc' | 'desc' function getComparator( order: Order, - orderBy: any, + orderBy: any ): ( a: { [key in Key]: number | string }, - b: { [key in Key]: number | string }, + b: { [key in Key]: number | string } ) => number { return order === 'desc' ? (a, b) => descendingComparator(a, b, orderBy) - : (a, b) => -descendingComparator(a, b, orderBy); -} - -function stableSort(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]); + : (a, b) => -descendingComparator(a, b, orderBy) } interface HeadCell { - disablePadding: boolean; - id: keyof Data | string; - label: string; - numeric: boolean; + disablePadding: boolean + id: keyof Data | string + label: string + numeric: boolean } const headCells: readonly HeadCell[] = [ @@ -105,44 +102,70 @@ const headCells: readonly HeadCell[] = [ id: 'clientCode', numeric: false, disablePadding: true, - label: 'código do cliente', + label: 'código do cliente' }, { id: 'name', numeric: false, disablePadding: false, - label: 'name', + label: 'name' }, { id: 'unity', numeric: false, disablePadding: false, - label: 'unity', + label: 'unity' }, { id: 'status', numeric: false, disablePadding: false, - label: 'status', - }, -]; + label: 'status' + } +] interface EnhancedTableProps { - numSelected: number; - onRequestSort: (event: React.MouseEvent, property: keyof Data) => void; - onSelectAllClick: (event: React.ChangeEvent) => void; - order: Order; - orderBy: string; - rowCount: number; + numSelected: number + onRequestSort: ( + event: React.MouseEvent, + property: keyof Data + ) => void + onSelectAllClick: (event: React.ChangeEvent) => 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) { - const { onSelectAllClick, order, orderBy, numSelected, rowCount, onRequestSort } = - props; + const { + onSelectAllClick, + order, + orderBy, + numSelected, + rowCount, + onRequestSort + } = props const createSortHandler = (property: any) => (event: React.MouseEvent) => { - onRequestSort(event, property); - }; + onRequestSort(event, property) + } return ( @@ -154,14 +177,14 @@ function EnhancedTableHead(props: EnhancedTableProps) { checked={rowCount > 0 && numSelected === rowCount} onChange={onSelectAllClick} inputProps={{ - 'aria-label': 'select all desserts', + 'aria-label': 'select all desserts' }} /> {headCells.map((headCell) => ( @@ -181,137 +204,136 @@ function EnhancedTableHead(props: EnhancedTableProps) { ))} - ); + ) } -interface ClientsTableInterface { - clients: any, - onChange: any -} +export default function ClientTable({ + clients, + onChange +}: ClientsTableInterface) { + const [order, setOrder] = useState('asc') + const [orderBy, setOrderBy] = useState('asc') + const [selected, setSelected] = useState([]) + const [page, setPage] = useState(0) + const [dense, setDense] = useState(false) + const [rowsPerPage, setRowsPerPage] = useState(5) -export default function ClientTable({ clients, onChange }: ClientsTableInterface) { - const [order, setOrder] = useState('asc'); - const [orderBy, setOrderBy] = useState('asc'); - const [selected, setSelected] = useState([]); - const [page, setPage] = useState(0); - const [dense, setDense] = useState(false); - const [rowsPerPage, setRowsPerPage] = useState(5); + const [openSnackError, setOpenSnackError] = useState(false) - const [openSnackError, setOpenSnackError] = useState(false); - - const [open, setOpen] = useState(false); + const [open, setOpen] = useState(false) const [openModalInativar, setOpenModalInativar] = useState(false) - const handleOpen = () => setOpen(true); - const handleClose = () => setOpen(false); + const [clientEdit, setClientEdit] = useState() + const [logo, setLogo] = useState(false) + const [imageURLS, setImageURLs] = useState([]) + const [images, setImages] = useState([] as any) + const [nivelAcess, setnivelAcess] = useState(2) + const [openEditUserModal, setOpenEditUserModal] = useState(false) + const [openSnackSuccess, setOpenSnackSuccess] = useState(false) + const [loading, setLoading] = useState(false) + const [selectedClient, setSelectedClient] = useState(2) + const [search, setSearch] = 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) { - api.post('/units', { - "filters": [ - { "type": "=", "field": "dados_cadastrais.cod_smart_cliente", "value": client_id } - ], - "fields": ["unidade"], - "distinct": true - }).then(res => setUnits(res.data.data)) + api + .post('/units', { + filters: [ + { + type: '=', + field: 'dados_cadastrais.cod_smart_cliente', + value: client_id + } + ], + fields: ['unidade'], + distinct: true + }) + .then((res) => setUnits(res.data.data)) .catch(() => setOpenSnackError(true)) return units } - const handleCloseSnack = (event?: React.SyntheticEvent | Event, reason?: string) => { + const handleCloseSnack = ( + event?: React.SyntheticEvent | Event, + reason?: string + ) => { if (reason === 'clickaway') { - return; + return } - setOpenSnackError(false); - }; + setOpenSnackError(false) + } const handleRequestSort = ( event: React.MouseEvent, - property: keyof Data, + property: keyof Data ) => { - const isAsc = orderBy === property && order === 'asc'; - setOrder(isAsc ? 'desc' : 'asc'); - setOrderBy(property); - }; + const isAsc = orderBy === property && order === 'asc' + setOrder(isAsc ? 'desc' : 'asc') + setOrderBy(property) + } const handleSelectAllClick = (event: React.ChangeEvent) => { if (event.target.checked) { - const newSelecteds = clients.map((n) => n.name); - setSelected(newSelecteds); - return; + const newSelecteds = clients.map((n) => n.name) + setSelected(newSelecteds) + return } - setSelected([]); - }; + setSelected([]) + } const handleClick = (event: React.MouseEvent, code: string) => { - const selectedIndex = selected.indexOf(code); - let newSelected: readonly string[] = []; + const selectedIndex = selected.indexOf(code) + let newSelected: readonly string[] = [] if (selectedIndex === -1) { - newSelected = newSelected.concat(selected, code); + newSelected = newSelected.concat(selected, code) } else if (selectedIndex === 0) { - newSelected = newSelected.concat(selected.slice(1)); + newSelected = newSelected.concat(selected.slice(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) { newSelected = newSelected.concat( selected.slice(0, selectedIndex), - selected.slice(selectedIndex + 1), - ); + selected.slice(selectedIndex + 1) + ) } - setSelected(newSelected); - }; + setSelected(newSelected) + } const handleChangePage = (event: unknown, newPage: number) => { - setPage(newPage); - }; + setPage(newPage) + } - const handleChangeRowsPerPage = (event: React.ChangeEvent) => { - setRowsPerPage(parseInt(event.target.value, 10)); - setPage(0); - }; + const handleChangeRowsPerPage = ( + event: React.ChangeEvent + ) => { + setRowsPerPage(parseInt(event.target.value, 10)) + setPage(0) + } - 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() - const [logo, setLogo] = useState(false) - const [imageURLS, setImageURLs] = useState([]) - const [images, setImages] = useState([] as any) - const [nivelAcess, setnivelAcess] = useState(2); - const [openEditUserModal, setOpenEditUserModal] = useState(false); - - const [selectedClient, setSelectedClient] = useState(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]) + const isSelected = (code: any) => selected.indexOf(code.toString()) !== -1 function onImageChange(e: any) { setImages([...e.target.files]) setLogo(e.target.files[0]) } - const [openSnackSuccess, setOpenSnackSuccess] = useState(false) - const [loading, setLoading] = useState(false) - async function handleUpdateClient(props, id) { logo && formData.append('file', logo) 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 ( - - + + Não foi possivel encontrar unidades do client! - setSearch(e.target.value)} placeholder='persquisar por nome:' /> + + setSearch(e.target.value)} + placeholder="Pesquisar por nome:" + /> + - {stableSort(clients, getComparator(order, orderBy)) - .filter(client => client.name.toLowerCase().includes(search.toLowerCase())) - .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) - .map((row, index) => { - const isItemSelected = isSelected(row.id); - const labelId = `enhanced-table-checkbox-${index}`; + {listClients.map((row, index) => { + const isItemSelected = isSelected(row.id) + const labelId = `enhanced-table-checkbox-${index}` - return ( - handleClick(event, row.id.toString())} - role="checkbox" - aria-checked={isItemSelected} - tabIndex={-1} - key={row.id} - selected={isItemSelected} + return ( + handleClick(event, row.id.toString())} + role="checkbox" + aria-checked={isItemSelected} + tabIndex={-1} + key={row.id} + selected={isItemSelected} + > + + + + + - - - - - Client - {row.client_id} - - { + Client - {row.client_id} + + + { setOpenEditUserModal(true) setSelectedClient(row) - setClientEdit({ email: row.email, name: row.name, client_id: row.client_id, profile_picture: row.profile_picture }) - }}>{row.name} - { + setClientEdit({ + email: row.email, + name: row.name, + client_id: row.client_id, + profile_picture: row.profile_picture + }) + }} + > + {row.name} + + + { setOpen(true) getClientUnits(row.client_id) setSelectedClient(row) - }}>clique aqui para ver as unidades - {row.deleted_at ? 'inativo' : 'ativo'} - - ); - })} + }} + > + clique aqui para ver as unidades + + + + + {' '} + {row.deleted_at ? 'inativo' : 'ativo'} + + + + ) + })} {emptyRows > 0 && ( @@ -421,6 +492,7 @@ export default function ClientTable({ clients, onChange }: ClientsTableInterface
+
+ setOpenEditUserModal(false)} @@ -515,13 +588,15 @@ export default function ClientTable({ clients, onChange }: ClientsTableInterface
{imageURLS.map((imageSrc, index) => { - return + return ( + + ) })}
@@ -543,7 +618,7 @@ export default function ClientTable({ clients, onChange }: ClientsTableInterface -
+
Nivel de acesso
- {!loading && setOpenEditUserModal(false)} />} - {!loading - ? setOpenEditUserModal(false)} + /> + )} + {!loading ? ( + handleUpdateClient(clientEdit, selectedClient.id)} /> - : - } + ) : ( + + )} @@ -579,18 +659,23 @@ export default function ClientTable({ clients, onChange }: ClientsTableInterface aria-describedby="modal-modal-description" > - { - units.map((units, index) => { - return <> -
  • {units.unidade}
  • + {units.map((units, index) => { + return ( + <> +
  • + {units.unidade} +

  • - }) - } + ) + })}
    - ); + ) } diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index 431cef8..8153eeb 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -26,7 +26,7 @@ export function MyApp({ Component, pageProps, notificationsCount }: AppProps | a const rota = router.pathname useEffect(() => { - const handleStart = (url) => { + const handleStart = () => { NProgress.start() } const handleStop = () => { @@ -79,7 +79,7 @@ export const getServerSideProps: GetServerSideProps = async (ctx) => { let notificationsCount - await apiClient.post('/download').then(console.log) + await apiClient.post('/download') if (!token) { return { diff --git a/src/pages/resumoOperacao/index.tsx b/src/pages/resumoOperacao/index.tsx index 03d54dc..11bf449 100644 --- a/src/pages/resumoOperacao/index.tsx +++ b/src/pages/resumoOperacao/index.tsx @@ -1,97 +1,120 @@ -import Box from '@mui/material/Box'; -import FormControl from '@mui/material/FormControl'; -import InputLabel from '@mui/material/InputLabel'; -import MenuItem from '@mui/material/MenuItem'; -import Select, { SelectChangeEvent } from '@mui/material/Select'; -import { GetServerSideProps } from 'next'; -import Head from 'next/head'; -import { parseCookies } from 'nookies'; -import { useEffect, useState } from 'react'; +import Box from '@mui/material/Box' +import FormControl from '@mui/material/FormControl' +import InputLabel from '@mui/material/InputLabel' +import MenuItem from '@mui/material/MenuItem' +import Select, { SelectChangeEvent } from '@mui/material/Select' +import { GetServerSideProps } from 'next' +import Head from 'next/head' +import { parseCookies } from 'nookies' +import { useEffect, useState } from 'react' -import BasicButton from '../../components/buttons/basicButton/BasicButton'; -import Header from '../../components/header/Header'; -import PageTitle from '../../components/pageTitle/PageTitle'; -import { api } from '../../services/api'; -import getAPIClient from '../../services/ssrApi'; -import { TableBodyView, TableHeader, TableView } from '../../styles/layouts/ResumoOperacao/ResumoOperacaoView'; +import BasicButton from '../../components/buttons/basicButton/BasicButton' +import Header from '../../components/header/Header' +import PageTitle from '../../components/pageTitle/PageTitle' +import { api } from '../../services/api' +import getAPIClient from '../../services/ssrApi' +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) { - const csvData = tableData; - - const [month, setMonth] = useState(''); - const [unidade, setUnidade] = useState(clients[0].cod_smart_unidade); - const [tableDataState, setTableDataState] = useState([]); +export default function ResumoOperacao({ + tableData, + clients, + userName, + clientMonth +}: any) { + const [month, setMonth] = useState('') + const [unidade, setUnidade] = useState(clients[0].cod_smart_unidade) + const [tableDataState, setTableDataState] = useState([]) const { ['user-id']: id } = parseCookies() const handleChangeMonth = (event: SelectChangeEvent) => { - setMonth(event.target.value); - }; + setMonth(event.target.value) + } + const handleChangeUnidade = (event: SelectChangeEvent) => { - setUnidade(event.target.value); - }; + setUnidade(event.target.value) + } - const [ pageYPosition, setPageYPosition ] = useState(0); + const [pageYPosition, setPageYPosition] = useState(0) - function getPageYAfterScroll(){ - setPageYPosition(window.scrollY); + function getPageYAfterScroll() { + setPageYPosition(window.scrollY) } function downloadCSVFile(csv, filename) { - const csv_file = new Blob(["\ufeff",csv], {type: "text/csv"}); - const download_link = document.createElement("a"); - download_link.download = filename; - download_link.href = window.URL.createObjectURL(csv_file); - download_link.style.display = "none"; - document.body.appendChild(download_link); - download_link.click(); + const csv_file = new Blob(['\ufeff', csv], { type: 'text/csv' }) + const download_link = document.createElement('a') + download_link.download = filename + download_link.href = window.URL.createObjectURL(csv_file) + download_link.style.display = 'none' + document.body.appendChild(download_link) + download_link.click() } function htmlToCSV(html, filename) { - const data = []; - const rows = document.querySelectorAll("table tr"); + const data = [] + const rows = document.querySelectorAll('table tr') 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++) { - 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(() => { - if (unidade!=='' || month!==''){ - api.post('/operation/summary', month && !unidade? { - "filters": [ - {"type" : "=", "field": "mes", "value": month} - ] - } : - !month && unidade? { - "filters": [ - {"type" : "=", "field": "dados_te.cod_smart_unidade", "value": unidade} - ] - } : - month && unidade? { - "filters": [ - {"type" : "=", "field": "mes", "value": month}, - {"type" : "=", "field": "dados_te.cod_smart_unidade", "value": unidade} - ] - } : {} - ).then(res => { - setTableDataState(res.data.data) - }) + if (unidade !== '' || month !== '') { + api + .post( + '/operation/summary', + month && !unidade + ? { + filters: [{ type: '=', field: 'mes', value: month }] + } + : !month && unidade + ? { + filters: [ + { + type: '=', + field: 'dados_te.cod_smart_unidade', + value: unidade + } + ] + } + : month && unidade + ? { + filters: [ + { type: '=', field: 'mes', value: month }, + { + type: '=', + field: 'dados_te.cod_smart_unidade', + value: unidade + } + ] + } + : {} + ) + .then((res) => { + setTableDataState(res.data.data) + }) } else { setTableDataState(tableData) } }, [month, unidade]) useEffect(() => { - window?.addEventListener('scroll', getPageYAfterScroll); + window?.addEventListener('scroll', getPageYAfterScroll) }, []) return ( @@ -99,15 +122,21 @@ export default function ResumoOperacao({tableData, clients, userName, clientMont Smart Energia - Resumo de Operação +
    - +
    + -
    -
    +
    +
    Unidades +
    @@ -138,68 +173,122 @@ export default function ResumoOperacao({tableData, clients, userName, clientMont fullWidth > Todos - { - clientMonth.sort((a, b) => { - 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 - 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 + {clientMonth + .sort((a, b) => { + 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 + 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 - }).map((value) => { - return {value.mes} }) - } + .map((value) => { + return ( + + {value.mes} + + ) + })}
    - { - const html = document.querySelector("table").outerHTML; - htmlToCSV(html, "resumo_operacao.csv"); - }}/> + { + const html = document.querySelector('table').outerHTML + htmlToCSV(html, 'resumo_operacao.csv') + }} + />
    - - - - - - - + + + + + + + - { - tableDataState?.map((value, index) => { - if (value.mes.slice(4,7) != '2020') - return - - - - - - - + {tableDataState?.map((value, index) => { + if (value.mes.slice(4, 7) != '2020') + return ( + + + + + + + + + + + + + + - }) - } + ) + })}
    Mês Unidade OperaçãoContraparteMontante (MWh)Preço(R$/MWh)Nota Fiscal (R$)Mês Unidade OperaçãoContraparteMontante (MWh)Preço(R$/MWh)Nota Fiscal (R$)
    {value.mes}{value.unidade}{value.nf_c_icms > 0 ? 'Compra' : 'Cessão'}{value.contraparte}{parseFloat(value.montante_nf).toLocaleString('pt-br')}{parseFloat(value.preco_nf).toLocaleString('pt-br',{style: 'currency', currency: 'BRL', minimumFractionDigits: 2})}{parseFloat(value.nf_c_icms).toLocaleString('pt-br',{style: 'currency', currency: 'BRL', minimumFractionDigits: 2})}
    + {value.mes} + + {value.unidade} + + {value.nf_c_icms > 0 ? 'Compra' : 'Cessão'} + + {value.contraparte} + + {parseFloat(value.montante_nf).toLocaleString('pt-br')} + + {parseFloat(value.preco_nf).toLocaleString('pt-br', { + style: 'currency', + currency: 'BRL', + minimumFractionDigits: 2 + })} + + {parseFloat(value.nf_c_icms).toLocaleString('pt-br', { + style: 'currency', + currency: 'BRL', + minimumFractionDigits: 2 + })} +
    - {pageYPosition > 300 && - - - - } + {pageYPosition > 300 && ( + + + + + + )} ) } @@ -210,40 +299,48 @@ export const getServerSideProps: GetServerSideProps = async (ctx) => { const { ['user-client_id']: client_id } = parseCookies(ctx) const { ['user-name']: userName } = parseCookies(ctx) - let tableData = []; - let clientMonth = []; + let tableData = [] + let clientMonth = [] - await apiClient.post('/operation/summary', { - "filters": [] - }).then(res => { - tableData = res.data.data - }) + await apiClient + .post('/operation/summary', { + filters: [] + }) + .then((res) => { + tableData = res.data.data + }) - let clients = []; + let clients = [] - await apiClient.post('/operation', { - "filters": [ - {"type" : ">=", "field":"dados_te.mes", "value":1, "interval": "year"} - ], - "fields": ["mes"], - "distinct": true - }).then(res => { - clientMonth = res.data.data - }) + await apiClient + .post('/operation', { + filters: [ + { type: '>=', field: 'dados_te.mes', value: 1, interval: 'year' } + ], + fields: ['mes'], + distinct: true + }) + .then((res) => { + clientMonth = res.data.data + }) - await apiClient.post('/units', { - "filters": [ - {"type" : "=", "field": "dados_cadastrais.cod_smart_cliente", "value": client_id}, - {"type" : "not_in", "field": "dados_cadastrais.codigo_scde", "value":["0P"]} - ], - "fields": [ - "unidade", - "cod_smart_unidade", - "codigo_scde"], - "distinct": true - }).then(res => { - clients = res.data.data - }) + await apiClient + .post('/units', { + filters: [ + { + type: '=', + field: 'dados_cadastrais.cod_smart_cliente', + value: client_id + }, + { type: 'not_in', field: 'dados_cadastrais.codigo_scde', value: ['0P'] }, + { type: 'order', field: 'dados_cadastrais.cliente', value: ['asc'] }, + ], + fields: ['unidade', 'cod_smart_unidade', 'codigo_scde'], + distinct: true + }) + .then((res) => { + clients = res.data.data + }) if (!token) { return { diff --git a/src/services/ssrApi.ts b/src/services/ssrApi.ts index 2196241..8b1c9a1 100644 --- a/src/services/ssrApi.ts +++ b/src/services/ssrApi.ts @@ -1,25 +1,31 @@ -import axios from "axios"; -import * as express from 'express'; -import * as next from 'next'; -import { parseCookies } from "nookies"; - -export default function getAPIClient(ctx?: Pick | { - req: next.NextApiRequest; -} | { - req: express.Request; -} | null | undefined) { +import axios from 'axios' +import * as express from 'express' +import * as next from 'next' +import { parseCookies } from 'nookies' +export default function getAPIClient( + ctx?: + | Pick + | { + req: next.NextApiRequest + } + | { + req: express.Request + } + | null + | undefined +) { const { '@smartAuth-token': token } = parseCookies(ctx) 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: 'http://api-smart.test/api' }) - api.interceptors.request.use(config => { - return config; - }, - ); + api.interceptors.request.use((config) => { + return config + }) if (token) { api.defaults.headers['Authorization'] = `Bearer ${token}` diff --git a/src/utils/formatPrice.ts b/src/utils/formatPrice.ts new file mode 100644 index 0000000..2e19506 --- /dev/null +++ b/src/utils/formatPrice.ts @@ -0,0 +1,3 @@ +export function formatPrice(value: string | number): string { + return parseFloat(`${value}`).toLocaleString("pt-BR", { style: "currency", currency: "BRL" }); +} diff --git a/src/utils/stableSort.ts b/src/utils/stableSort.ts new file mode 100644 index 0000000..207e52b --- /dev/null +++ b/src/utils/stableSort.ts @@ -0,0 +1,18 @@ +export function stableSort( + 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]) +} diff --git a/src/utils/stringHelper.ts b/src/utils/stringHelper.ts new file mode 100644 index 0000000..c0c3785 --- /dev/null +++ b/src/utils/stringHelper.ts @@ -0,0 +1,25 @@ +export function sanitizeStringSearch(value: string): string { + return value + .trim() + .normalize("NFD") + .replace(/[\u0300-\u036f]/g, "") + .toLowerCase(); +} + +export function sortedString(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 + ); +}