Skip to content
Snippets Groups Projects
Notifications.js 8.81 KiB
Newer Older
/*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre
Departamento de Informatica - Universidade Federal do Parana

This file is part of Plataforma Integrada MEC.

Plataforma Integrada MEC is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Plataforma Integrada MEC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with Plataforma Integrada MEC.  If not, see <http://www.gnu.org/licenses/>.*/
lfr20's avatar
lfr20 committed
import React, { useState, useEffect, useContext } from 'react';
import NotificationsIcon from '@material-ui/icons/Notifications';
import { Button } from '@material-ui/core';
import Badge from '@material-ui/core/Badge';
import styled from 'styled-components'
import Menu from '@material-ui/core/Menu';
lfr20's avatar
lfr20 committed
import { apiDomain } from '../env.js'
import ActivityListItem from './ActivityListItem.js'
lfr20's avatar
lfr20 committed
import { getRequest, postRequest } from './HelperFunctions/getAxiosConfig.js'
import { withStyles } from '@material-ui/core/styles';
lfr20's avatar
lfr20 committed
import { Link } from 'react-router-dom'
import { getRecipientHref } from './Activities/getRecipientHref.js'
import SnackBar from '../Components/SnackbarComponent'
lfr20's avatar
lfr20 committed
import { Store } from '../Store';
lfr20's avatar
lfr20 committed
const StyledBadge = styled(Badge)`
    .MuiBadge-dot-45{
        height : 9px ;
        width : 9px ;
        transform : scale(1) translate( 01%, -40%);
    }
`

const StyledNotificationsIcon = styled(NotificationsIcon)`
    flex : 1;
    align-self : center;
    margin-left : 0 !important;
    color: #00bcd4;
`

const StyledNotificationButton = styled(Button)`
    height : 56px !important;
    width : 56px !important;
    border-radius : 50% !important;
    &:hover {
        color : #00bcd4 !important;
lfr20's avatar
lfr20 committed
    paper: {
        border: '1px solid #d3d4d5',
    },
lfr20's avatar
lfr20 committed
    <Menu
        elevation={0}
        getContentAnchorEl={null}
        anchorOrigin={{
            horizontal: 'center',
            vertical: "bottom",
        }}
        transformOrigin={{
            vertical: 'top',
            horizontal: 'center',
        }}
        {...props}
    />
lfr20's avatar
lfr20 committed
export default function Notification(props) {
    const [anchorEl, setAnchorEl] = React.useState(null);
lfr20's avatar
lfr20 committed
    const { state } = useContext(Store);
    const [notifications, setNotifications] = useState([]);
lfr20's avatar
lfr20 committed
    const [snack, setSnack] = useState({
        open: false,
        text: "",
        severity: "",
        color: ""
    });
    // eslint-disable-next-line
    const [notificatonsLength, setLength] = useState(0);
lfr20's avatar
lfr20 committed
    function handleAxiosSuccess(data) {
        if (data.errors)
            setSnack({
                open: true,
                text: "Erro ao buscar suas notificações",
                severity: "error",
                color: "red"
            })
        else {
            setNotifications(data)
            setLength(data.length)
        }
lfr20's avatar
lfr20 committed
    function handleAxiosError(error) {
        setSnack({
            open: true,
            text: "Erro ao buscar suas notificações",
            severity: "error",
            color: "red"
        })
        getRequest('/feed?offset=0&limit=30', handleAxiosSuccess, handleAxiosError)
    function handleClick(event) {
        console.log('event.currentTarget: ', event.currentTarget)
        setAnchorEl(event.currentTarget);
    }

    function handleClose() {
        setAnchorEl(null);
    }
lfr20's avatar
lfr20 committed

    function handleClickNotification() {
        const payload = {
            "activities": {
                "ids": []
            }
        }

        for (let index = 0; index < notifications.length; index++) {
            const notification = notifications[index];
            payload.activities.ids.push(notification.id)
        }

        postRequest(
            '/activities/view',
            payload,
            (data) => {
                if (data.errors)
                    setSnack({
                        open: true,
                        text: "Erro ao marcar as notificações como lidas!",
                        severity: "error",
                        color: "red"
                    })
                else {
                    setSnack({
                        open: true,
                        text: "Todas as notificações foram marcadas como lidas!",
                        severity: "success",
                        color: "green"
                    })
                    setNotifications([])
                }
            },
            (error) => {
                setSnack({
                    open: true,
                    text: "Erro ao marcar as notificações como lidas!",
                    severity: "error",
                    color: "red"
                })
            },
        )


    }

        <React.Fragment>
lfr20's avatar
lfr20 committed
            <SnackBar
                snackbarOpen={snack.open}
                handleClose={() => {
                    setSnack({
                        open: false,
                        text: "",
                        severity: "",
                        color: ""
                    })
                }}
                severity={snack.severity}
                color={snack.color}
                text={snack.text}
            />
            <StyledNotificationButton onClick={handleClick}>
                <StyledBadge badgeContent={1} color="secondary" variant="dot" overlap="circle" className="badge">
lfr20's avatar
lfr20 committed
                    <StyledNotificationsIcon className={`${state.contrast}IconColor`} />
lfr20's avatar
lfr20 committed
                </StyledBadge>
            </StyledNotificationButton>
            <StyledMenu
                id="simple-menu"
                anchorEl={anchorEl}
                keepMounted
                open={Boolean(anchorEl)}
                onClose={handleClose}
lfr20's avatar
lfr20 committed
                contrast={state.contrast}
lfr20's avatar
lfr20 committed
            >
lfr20's avatar
lfr20 committed
                <ContainerDiv contrast={state.contrast}>
lfr20's avatar
lfr20 committed
                    <div className="cabecalho">
                        <span style={{ fontSize: "15px" }}>NOTIFICAÇÕES </span>
                        <span className="cabecalho-marcar" onClick={handleClickNotification}>Marcar todas como lidas</span>
                    </div>
                    {
                        notifications.map((notification) =>
                            (notification.recipient !== null) &&
vgm18's avatar
vgm18 committed
                            (notification.viewed === false) &&
                            (notification.recipient_type !== "NilClass") &&
lfr20's avatar
lfr20 committed
                            <ActivityListItem
lfr20's avatar
lfr20 committed
                                contrast={state.contrast}
lfr20's avatar
lfr20 committed
                                onMenuBar={true}
                                avatar={notification.owner.avatar ? apiDomain + notification.owner.avatar : null}
                                activity={notification.activity}
                                actionType={notification.trackable_type}
                                objectType={notification.recipient_type}
                                createdAt={notification.created_at}
                                ownerName={notification.owner.name}
                                ownerHref={'/perfil'}
                                recipientName={notification.recipient.name}
                                recipientHref={getRecipientHref(notification)}
                            />
                        )
                    }
                    <div style={{ padding: "0 15px", borderTop: "1px solid #dadada" }}>
                        <Link to="/perfil">
                            <NoPadButton>
                                MOSTRAR TODAS
vgm18's avatar
vgm18 committed
                            </NoPadButton>
lfr20's avatar
lfr20 committed
                        </Link>
                    </div>
                </ContainerDiv>
            </StyledMenu>
        </React.Fragment>
const NoPadButton = styled(Button)`
    padding : 6px 0 !important;
const ContainerDiv = styled.div`
    margin-top : 10px;
    right : 5%;
    width : 360px;
    max-height : 400px;
    box-shadow : 8px 8px 8px 8px
    rgba(0,0,0,.1);
    overflow-y : scroll;
    padding : 5px 5px 5px 5px;
    min-width : 160px;
lfr20's avatar
lfr20 committed
    background-color: ${props => props.contrast === '' ? "#f1f1f1" : "black"};
    .cabecalho {
        border-bottom : 1px solid #dadada;
        padding : 10px 15px;
lfr20's avatar
lfr20 committed
        color: ${props => props.contrast === '' ? "black" : "yellow"};

        .cabecalho-marcar {
            font-family: Lato,bold;
            font-size: 12px;
            -webkit-text-decoration-line: underline;
            text-decoration-line: underline;
            float: right;
lfr20's avatar
lfr20 committed
            cursor: pointer;