From 95d33f1ccd72154eb92e65b16cff728988ade19b Mon Sep 17 00:00:00 2001 From: joseCorte-exe Date: Wed, 15 Jun 2022 10:34:15 -0300 Subject: [PATCH 1/3] add notification integration --- .../NotificationsTable.tsx | 32 ++- src/contexts/AuthContext.tsx | 4 +- .../administrative/notification/index.tsx | 222 ++++++++++++------ .../notification/notificationView.ts | 2 +- src/services/auth.ts | 27 +-- src/services/ssrApi.ts | 5 +- 6 files changed, 185 insertions(+), 107 deletions(-) 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() { ; 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); + async function handleRegisterNewNotification({title, body, users}: NotificationInterface) { + await api.post('/notification', { + title, + body, + users + }).then(res => setOpenSnackSuccess(true)).catch(res => setOpenSnackError(true)) + } + return ( @@ -61,79 +89,131 @@ export default function commonQuestions() {

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) + }} />
    - + + + + This is a success message! + + + + + This is a success message! + +
    ) } -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/services/auth.ts b/src/services/auth.ts index df78f49..e2b196b 100644 --- a/src/services/auth.ts +++ b/src/services/auth.ts @@ -1,4 +1,4 @@ -import api from "./api"; +import { api } from "./api"; export const TOKEN_KEY = "@smartAuth-token"; @@ -15,7 +15,8 @@ type UserObjectType = { name: string; email: string; client_id: number - id: number + id: number, + role: number } export async function signInRequest(data: SignInRequestData) { @@ -30,7 +31,8 @@ export async function signInRequest(data: SignInRequestData) { 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.role_id } token = res.data.token }).catch(res => { @@ -38,13 +40,8 @@ export async function signInRequest(data: SignInRequestData) { }) return { - token: token, - user: { - name: user.name, - email: user.email, - client_id: user.client_id, - id: user.id - } + token, + user } } @@ -57,18 +54,14 @@ 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.role_id } }).catch(res => { console.log(res) }) return { - user: { - name: user?.name, - email: user?.email, - client_id: user?.client_id, - id: user?.id - } + user } } diff --git a/src/services/ssrApi.ts b/src/services/ssrApi.ts index 4bad590..0be3e3e 100644 --- a/src/services/ssrApi.ts +++ b/src/services/ssrApi.ts @@ -10,16 +10,13 @@ export default function getAPIClient(ctx?: Pick | { req: express.Request; } | null | undefined) { - const { '@smartAuth-token': token } = parseCookies() + const { '@smartAuth-token': token } = parseCookies(ctx) const api = axios.create({ baseURL: "https://smart-energia-api.herokuapp.com/api", }); api.interceptors.request.use(config => { - // console.log(config) - // config.headers = {Authorization: `Bearer ${token}`}; - return config; }, ); From 55a206bd3afadc75d44d0e90c412deca3538efbc Mon Sep 17 00:00:00 2001 From: joseCorte-exe Date: Wed, 15 Jun 2022 13:09:27 -0300 Subject: [PATCH 2/3] add auth and user role --- package.json | 1 + src/components/sidebar/Sidebar.tsx | 29 ++++--------- src/contexts/AuthContext.tsx | 2 +- .../administrative/notification/index.tsx | 41 +++++++++++++------ src/services/auth.ts | 22 +++++++--- yarn.lock | 9 +++- 6 files changed, 63 insertions(+), 41 deletions(-) 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/sidebar/Sidebar.tsx b/src/components/sidebar/Sidebar.tsx index 05c298d..1f08998 100644 --- a/src/components/sidebar/Sidebar.tsx +++ b/src/components/sidebar/Sidebar.tsx @@ -1,11 +1,12 @@ import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; import Modal from '@mui/material/Modal'; -import Stack from '@mui/material/Stack'; import Typography from '@mui/material/Typography'; +import { GetServerSideProps } from 'next'; import Image from 'next/image' import Link from 'next/link' import { useRouter } from 'next/router' +import { parseCookies } from 'nookies'; import React, { useEffect, useState } from 'react' import RenderIf from '../../utils/renderIf'; @@ -34,9 +35,9 @@ export default function Sidebar() { const router = useRouter() - const user = { - role: 'admin' - } + const { ['user-role']: role } = parseCookies() + + console.log(role) useEffect(() => { 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 6e34ac9..32e36b7 100644 --- a/src/contexts/AuthContext.tsx +++ b/src/contexts/AuthContext.tsx @@ -40,7 +40,7 @@ export function AuthProvider({children}: {children: React.ReactNode}) { maxAge: 60 * 60 * 1, // 1 hour }) - // setCookie(undefined, 'user-role', user.role) + setCookie(undefined, 'user-role', user.role) api.defaults.headers['Authorization'] = `Bearer ${token}` diff --git a/src/pages/administrative/notification/index.tsx b/src/pages/administrative/notification/index.tsx index 4b30dcc..021095f 100644 --- a/src/pages/administrative/notification/index.tsx +++ b/src/pages/administrative/notification/index.tsx @@ -25,8 +25,8 @@ import getAPIClient from '../../../services/ssrApi'; import { GetServerSideProps } from 'next'; import { parseCookies } from 'nookies'; import Notifications from '../../notifications'; -import Snackbar from '@mui/material/Snackbar/Snackbar'; -import Alert from '@mui/material/Alert/Alert'; +import Snackbar from '@mui/material/Snackbar'; +import MuiAlert, { AlertProps } from '@mui/material/Alert'; const style = { position: 'absolute' as const, @@ -42,6 +42,13 @@ const style = { overflowY: 'scroll' }; +const Alert = React.forwardRef(function Alert( + props, + ref, +) { + return ; +}); + const icon = ; const checkedIcon = ; @@ -68,6 +75,15 @@ export default function notification({clients, notifications}) { 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, @@ -84,6 +100,17 @@ export default function notification({clients, notifications}) {
    + + + notificação cadastrada com sucesso! + + + + + Notificação não cadastrada! + + +
    @@ -168,16 +195,6 @@ export default function notification({clients, notifications}) { - - - This is a success message! - - - - - This is a success message! - - ) } diff --git a/src/services/auth.ts b/src/services/auth.ts index e2b196b..0edd74e 100644 --- a/src/services/auth.ts +++ b/src/services/auth.ts @@ -27,12 +27,13 @@ export async function signInRequest(data: SignInRequestData) { "password": data.password, "device_name": "test" }).then(res => { + // console.log(res.data.user.roles.pivot.role_id) user = { name: res.data.user.name, email: res.data.user.email, client_id: res.data.user.client_id, id: res.data.user.id, - role: res.data.user.roles.role_id + role: res.data.user.roles[0].pivot.role_id } token = res.data.token }).catch(res => { @@ -40,8 +41,14 @@ export async function signInRequest(data: SignInRequestData) { }) return { - token, - user + token: token, + user: { + name: user?.name, + email: user?.email, + client_id: user?.client_id, + id: user?.id, + role: user?.role + } } } @@ -55,13 +62,18 @@ export default async function recoverUserInformation(id) { email: res.data.user.email, client_id: res.data.user.client_id, id: res.data.user.id, - role: res.data.user.roles.role_id + role: res.data.user.roles[0].pivot.role_id } }).catch(res => { console.log(res) }) return { - user + user: { + name: user?.name, + email: user?.email, + client_id: user?.client_id, + id: user?.id + } } } 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" From e82bf612f9a306b96499c0a1f2962981c53ced8a Mon Sep 17 00:00:00 2001 From: joseCorte-exe Date: Wed, 15 Jun 2022 14:20:47 -0300 Subject: [PATCH 3/3] fix login --- src/contexts/AuthContext.tsx | 27 ++++++++++++++++++++------- src/pages/dashboard.tsx | 1 - src/services/auth.ts | 12 ++++++------ 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/contexts/AuthContext.tsx b/src/contexts/AuthContext.tsx index 32e36b7..c422e20 100644 --- a/src/contexts/AuthContext.tsx +++ b/src/contexts/AuthContext.tsx @@ -31,22 +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 + }) + } - setCookie(undefined, 'user-role', user.role) + 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/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 0edd74e..52640dc 100644 --- a/src/services/auth.ts +++ b/src/services/auth.ts @@ -20,14 +20,14 @@ type UserObjectType = { } 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 => { - // console.log(res.data.user.roles.pivot.role_id) + token = res.data.token user = { name: res.data.user.name, email: res.data.user.email, @@ -35,20 +35,20 @@ export async function signInRequest(data: SignInRequestData) { 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, role: user?.role - } + }, + exception } }