diff --git a/package.json b/package.json index 6928e76..cf6bbec 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "install": "^0.13.0", "next": "12.1.6", "nookies": "^2.5.2", + "notistack": "^2.0.5", "npm": "^8.10.0", "nprogress": "^0.2.0", "patternomaly": "^1.3.2", diff --git a/src/components/administrativeTables/NotificationsTable.tsx b/src/components/administrativeTables/NotificationsTable.tsx index e462c4f..9610612 100644 --- a/src/components/administrativeTables/NotificationsTable.tsx +++ b/src/components/administrativeTables/NotificationsTable.tsx @@ -171,7 +171,14 @@ function EnhancedTableHead(props: EnhancedTableProps) { ); } -export default function ClientTable() { +interface NotificationData { + title: string, + body: string, + users: string + deleted_at: Date, +} + +export default function ClientTable({notifications}: any) { const [order, setOrder] = useState('asc'); const [orderBy, setOrderBy] = useState('status'); const [selected, setSelected] = useState([]); @@ -190,7 +197,7 @@ export default function ClientTable() { const handleSelectAllClick = (event: React.ChangeEvent) => { if (event.target.checked) { - const newSelecteds = rows.map((n) => n.notification); + const newSelecteds = notifications.map((n) => n.id.toString()); setSelected(newSelecteds); return; } @@ -229,8 +236,7 @@ export default function ClientTable() { const isSelected = (name: string) => selected.indexOf(name) !== -1; // Avoid a layout jump when reaching the last page with empty rows. - const emptyRows = - page > 0 ? Math.max(0, (1 + page) * rowsPerPage - rows.length) : 0; + const emptyRows = page > 0 ? Math.max(0, (1 + page) * rowsPerPage - notifications.length) : 0; return ( @@ -247,23 +253,23 @@ export default function ClientTable() { orderBy={orderBy} onSelectAllClick={handleSelectAllClick} onRequestSort={handleRequestSort} - rowCount={rows.length} + rowCount={notifications.length} /> - {stableSort(rows, getComparator(order, orderBy)) + {stableSort(notifications, getComparator(order, orderBy)) .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) .map((row, index) => { - const isItemSelected = isSelected(row.notification.toString()); + const isItemSelected = isSelected(row.id.toString()); const labelId = `enhanced-table-checkbox-${index}`; return ( handleClick(event, row.notification.toString())} + onClick={(event) => handleClick(event, row.id.toString())} role="checkbox" aria-checked={isItemSelected} tabIndex={-1} - key={row.notification} + key={index} selected={isItemSelected} > @@ -281,10 +287,10 @@ export default function ClientTable() { scope="row" padding="none" > - {row.notification} + {row.title} - {row.client} - {row.status} + {'copel'} + {row.deleted_at===null? 'ativo' : 'inativo'} ); })} @@ -303,7 +309,7 @@ export default function ClientTable() { { setViewModal(false) @@ -44,7 +45,7 @@ export default function Sidebar() { return ( <> - +
setViewModal(!viewModal)} > @@ -57,22 +58,6 @@ export default function Sidebar() {
  • {'Visão Geral'}
  • {'FAQ >'}
  • {'Notificações >'}

    25

  • - {/*
  • setEconomiaDrawer(!economiaDrawer)} className={router.pathname=='/grossSavings' || router.pathname=='/accumulatedSavings' || router.pathname=='/estimatedCost' || router.pathname=='/costIndicator' ? 'actualPath' : null } >{'Economia >'}
  • -
    -
  • Economia Bruta
  • -
  • Economia Acumulada
  • -
  • Custo Estimado
  • -
  • Custo R/MWh
  • -
    */} - {/*
  • {'Telemetria >'}
  • -
  • {'Resumo de Op. '}
  • -
  • {'Notícias >'}
  • -
  • {'PLD >'}
  • -
  • {'Info Setorial >'}
  • -
  • {'Consumo'}
  • -
  • {'Notificações >'}

    25

  • -
  • {'Sobre Nós >'}
  • -
  • {'FAQ >'}
  • */} - +
    setViewModal(!viewModal)} > diff --git a/src/contexts/AuthContext.tsx b/src/contexts/AuthContext.tsx index b0ae9d6..c422e20 100644 --- a/src/contexts/AuthContext.tsx +++ b/src/contexts/AuthContext.tsx @@ -31,20 +31,35 @@ export function AuthProvider({children}: {children: React.ReactNode}) { const isAuthenticated = !!user async function signIn({email, password}: SignInData) { - const { token, user }: any = await signInRequest({ + const { token, user, exception }: any = await signInRequest({ email, password }) - setCookie(undefined, '@smartAuth-token', token, { - maxAge: 60 * 60 * 1, // 1 hour - }) + if (token) { + setCookie(undefined, '@smartAuth-token', token, { + maxAge: 60 * 60 * 1, // 1 hour + }) + } + + if (user.role) { + setCookie(undefined, 'user-role', user.role) + } + + if (!exception) { + if (user.role == 2) { + Router.push('/dashboard') + } else { + Router.push('administrative/clients') + } + return; + } else { + return + } api.defaults.headers['Authorization'] = `Bearer ${token}` setUser(user) - - Router.push('/dashboard') } return ( diff --git a/src/pages/administrative/notification/index.tsx b/src/pages/administrative/notification/index.tsx index eb68a3e..d2631c1 100644 --- a/src/pages/administrative/notification/index.tsx +++ b/src/pages/administrative/notification/index.tsx @@ -1,29 +1,32 @@ import CheckBoxIcon from '@mui/icons-material/CheckBox'; import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank'; -import RadioButtonCheckedIcon from '@mui/icons-material/RadioButtonChecked'; -import RadioButtonUncheckedIcon from '@mui/icons-material/RadioButtonUnchecked'; import Autocomplete from '@mui/material/Autocomplete'; import Box from '@mui/material/Box'; import Checkbox from '@mui/material/Checkbox'; import FormControl from '@mui/material/FormControl'; -import InputLabel from '@mui/material/InputLabel'; -import MenuItem from '@mui/material/MenuItem'; import Modal from '@mui/material/Modal'; -import Select, { SelectChangeEvent } from '@mui/material/Select'; import TextField from '@mui/material/TextField'; import Typography from '@mui/material/Typography'; import Head from 'next/head' -import React from 'react' +import React, { useState } from 'react' import NotificationsTable from '../../../components/administrativeTables/NotificationsTable' -import BasicButton from '../../../components/buttons/basicButton/BasicButton'; import FaqButton1 from '../../../components/buttons/faqButton/FaqButton1'; import FaqButton2 from '../../../components/buttons/faqButton/FaqButton2'; import Header from '../../../components/header/Header' import PageTitle from '../../../components/pageTitle/PageTitle' import { api } from '../../../services/api'; import { FaqView } from '../../../styles/layouts/commonQuestions/FaqView' -import { NotificationView } from './notificationView' + +import Radio from '@mui/material/Radio'; +import RadioGroup from '@mui/material/RadioGroup'; +import FormControlLabel from '@mui/material/FormControlLabel'; +import getAPIClient from '../../../services/ssrApi'; +import { GetServerSideProps } from 'next'; +import { parseCookies } from 'nookies'; +import Notifications from '../../notifications'; +import Snackbar from '@mui/material/Snackbar'; +import MuiAlert, { AlertProps } from '@mui/material/Alert'; const style = { position: 'absolute' as const, @@ -39,15 +42,56 @@ const style = { overflowY: 'scroll' }; +const Alert = React.forwardRef(function Alert( + props, + ref, +) { + return ; +}); + const icon = ; const checkedIcon = ; -export default function commonQuestions() { +interface NotificationInterface { + title: string, + body: string, + users: object[] +} + +export default function notification({clients, notifications}) { + + const [notification, setNotification] = useState({ + title: '', + body: '', + users: [] + }) + + const [open, setOpen] = useState(false); + const [openSnackSuccess, setOpenSnackSuccess] = useState(false); + const [openSnackError, setOpenSnackError] = useState(false); + + const [radiusValue, setRadiusValue] = useState('all'); - const [open, setOpen] = React.useState(false); const handleOpen = () => setOpen(true); const handleClose = () => setOpen(false); + const handleCloseSnack = (event?: React.SyntheticEvent | Event, reason?: string) => { + if (reason === 'clickaway') { + return; + } + + setOpenSnackError(false); + }; + + + async function handleRegisterNewNotification({title, body, users}: NotificationInterface) { + await api.post('/notification', { + title, + body, + users + }).then(res => setOpenSnackSuccess(true)).catch(res => setOpenSnackError(true)) + } + return ( @@ -56,84 +100,137 @@ export default function commonQuestions() {
    + + + notificação cadastrada com sucesso! + + + + + Notificação não cadastrada! + + +

    Disparar Notificações

    Pode ser que todas as notificaçõs demorem alguns minutos para estarem disponíveis
    -

    + { + setNotification({ + ...notification, + title: value.target.value + }) + }} variant="outlined" />

    + { + setNotification({ + ...notification, + body: value.target.value + }) + }} variant="outlined" />

    - option.title} - renderOption={(props, option, { selected }) => ( -
  • - - {option.title} -
  • - )} - sx={{ml:8}} - style={{ width: 700 }} - renderInput={(params) => ( - - )} - />
    - } - checkedIcon={} - /> - - Disparar para todos os clientes - } - checkedIcon={} - /> - - Disparar somente para alguns clientes + + + } checked={radiusValue==='all'? true : false}onChange={(value: React.ChangeEvent) => { + setRadiusValue(value.target.value) + }} label="Disparar para todos os clientes" /> + } checked={radiusValue==='some'? true : false} onChange={(value: React.ChangeEvent) => { + setRadiusValue(value.target.value) + }} label="Disparar somente para alguns clientes" /> + +
    - - + { + radiusValue === 'some'? + { + setNotification({...notification, users: newValue.map((el) => {return {"user_id": el.id}})}); + }} + getOptionLabel={(option) => option.name} + renderOption={(props, option, { selected }) => ( +
  • + + {option.name} +
  • + )} + sx={{ml:8}} + style={{ width: 700 }} + renderInput={(params) => ( + + )} + /> : + null + } + + {console.log()}} /> + { + handleRegisterNewNotification(notification) + }} />
    - + ) } -const top100Films = [ - { title: 'The Shawshank Redemption', year: 1994 }, - { title: 'The Godfather', year: 1972 }, - { title: 'The Godfather: Part II', year: 1974 }, - { title: 'The Dark Knight', year: 2008 }, - { title: '12 Angry Men', year: 1957 }, - { title: "Schindler's List", year: 1993 }, - { title: 'Pulp Fiction', year: 1994 }, - { - title: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, -]; +export const getServerSideProps: GetServerSideProps = async (ctx) => { + const apiClient = getAPIClient(ctx) + const { ['@smartAuth-token']: token } = parseCookies(ctx) + + let clients = []; + let notifications = []; + + await apiClient.get('/user').then(res => { + clients = res.data + }).catch(res => { + console.log(res) + }) + + await apiClient.get('/notification').then(res => { + notifications = res.data + }).catch(res => { + console.log(res) + }) + + if (!token) { + return { + redirect: { + destination: '/', + permanent: false + } + } + } + + return { + props: { + clients, + notifications + } + } +} diff --git a/src/pages/administrative/notification/notificationView.ts b/src/pages/administrative/notification/notificationView.ts index eef7f16..cc0aca2 100644 --- a/src/pages/administrative/notification/notificationView.ts +++ b/src/pages/administrative/notification/notificationView.ts @@ -3,7 +3,7 @@ import styled from 'styled-components' export const NotificationView = styled.nav` - display: flex; + display: flex; align-items: center; flex-direction: column; diff --git a/src/pages/dashboard.tsx b/src/pages/dashboard.tsx index 1615fab..a5ff7c6 100644 --- a/src/pages/dashboard.tsx +++ b/src/pages/dashboard.tsx @@ -66,7 +66,6 @@ export default function Dashboard() { } export const getServerSideProps: GetServerSideProps = async (ctx) => { - const apiClient = getAPIClient(ctx) const { ['@smartAuth-token']: token } = parseCookies(ctx) if (!token) { diff --git a/src/services/auth.ts b/src/services/auth.ts index 3a36874..52640dc 100644 --- a/src/services/auth.ts +++ b/src/services/auth.ts @@ -15,36 +15,40 @@ type UserObjectType = { name: string; email: string; client_id: number - id: number + id: number, + role: number } export async function signInRequest(data: SignInRequestData) { - let user: UserObjectType, token: string + let user: UserObjectType, token: string, exception: any = null await api.post('/auth/login', { "email": data.email, "password": data.password, "device_name": "test" }).then(res => { + token = res.data.token user = { name: res.data.user.name, email: res.data.user.email, client_id: res.data.user.client_id, - id: res.data.user.id + id: res.data.user.id, + role: res.data.user.roles[0].pivot.role_id } - token = res.data.token }).catch(res => { - console.log(res) + exception = res }) return { - token: token, + token, user: { - name: user.name, - email: user.email, - client_id: user.client_id, - id: user.id - } + name: user?.name, + email: user?.email, + client_id: user?.client_id, + id: user?.id, + role: user?.role + }, + exception } } @@ -57,7 +61,8 @@ export default async function recoverUserInformation(id) { name: res.data.user.name, email: res.data.user.email, client_id: res.data.user.client_id, - id: res.data.user.id + id: res.data.user.id, + role: res.data.user.roles[0].pivot.role_id } }).catch(res => { console.log(res) diff --git a/src/services/ssrApi.ts b/src/services/ssrApi.ts index 8a23c97..0be3e3e 100644 --- a/src/services/ssrApi.ts +++ b/src/services/ssrApi.ts @@ -17,9 +17,6 @@ export default function getAPIClient(ctx?: Pick | { }); api.interceptors.request.use(config => { - // console.log(config) - // config.headers = {Authorization: `Bearer ${token}`}; - return config; }, ); diff --git a/yarn.lock b/yarn.lock index f46ffc0..ed043f2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1994,7 +1994,7 @@ clone@^1.0.2: version "1.0.4" resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" -clsx@^1.0.4, clsx@^1.1.1: +clsx@^1.0.4, clsx@^1.1.0, clsx@^1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz" @@ -3616,6 +3616,13 @@ normalize-path@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" +notistack@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/notistack/-/notistack-2.0.5.tgz#8eb53720453f6e02182cd0e6784ced630a7bb7e6" + dependencies: + clsx "^1.1.0" + hoist-non-react-statics "^3.3.0" + npm-audit-report@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/npm-audit-report/-/npm-audit-report-3.0.0.tgz#1bf3e531208b5f77347c8d00c3d9badf5be30cd6"