Skip to content
Snippets Groups Projects
Comment.js 14.3 KiB
Newer Older
Raul Almeida's avatar
Raul Almeida committed
/*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, useContext } from 'react'
import { Store } from '../Store.js'
Raul Almeida's avatar
Raul Almeida committed
import styled from 'styled-components'
import Grid from '@material-ui/core/Grid';
import { Button } from '@material-ui/core';
lfr20's avatar
lfr20 committed
import { Link } from 'react-router-dom'
import { apiDomain } from '../env';
Raul Almeida's avatar
Raul Almeida committed
import Rating from '@material-ui/lab/Rating';
import StarBorderIcon from '@material-ui/icons/StarBorder';
import EditIcon from '@material-ui/icons/Edit';
import TextField from "@material-ui/core/TextField";
lfr20's avatar
lfr20 committed
import Menu from "@material-ui/core/Menu";
import MenuItem from "@material-ui/core/MenuItem";
import ModalExcluir from "./ModalExcluirComentario.js";
import { putRequest, deleteRequest } from "./HelperFunctions/getAxiosConfig";
import { makeStyles } from "@material-ui/styles";
import { noAvatar } from "ImportImages.js";
lfr20's avatar
lfr20 committed
const useStyles = makeStyles((theme) => ({
  darkTextField: {
    maxWidth: "100%",
    fontSize: "15px",
    fontWeight: "lighter",
    color: "white",
    width: "100%",
  },
  lightTextField: {
    maxWidth: "100%",
    fontSize: "15px",
    fontWeight: "lighter",
    color: "black",
    width: "100%",
  },
}));

Raul Almeida's avatar
Raul Almeida committed

lfr20's avatar
lfr20 committed
export default function Comment(props) {
lfr20's avatar
lfr20 committed
  /*
Raul Almeida's avatar
Raul Almeida committed
    Required props:
        rerenderCallback = callback function to trigger re-render on parent component
        reviewRatings = required to update comment even though the user cannot update their rating score...
        objectID = collection/learning object id
        reviewID = self-explanatory I hope
        authorID = author id; links to public user page
        authorAvatar = either a string denoting the author's avatar file location or null
        rating = star rating
        name = title (?)
        authorName = author username
        description = the  user comment itself
        createdAt
        recurso : boolean; determines whether to display orange or purple font
    */
lfr20's avatar
lfr20 committed
  var moment = require("moment");
  const classes = useStyles();
  const { state } = useContext(Store);
  const [displayedComment, setDisplayedComment] = useState(props.description);
  const [editando, setEditando] = useState(false);
  const [anchorEl, setAnchorEl] = React.useState(null);
  const handleClick = (event) => {
    setAnchorEl(event.currentTarget);
  };
  const handleClose = () => {
    setAnchorEl(null);
  };
  const [modalOpen, toggleModal] = useState(false);

  const [comment, setComment] = useState({
    error: false,
    value: props.description,
  });
  const handleChange = (e) => {
    const userInput = e.target.value;
    const flag = userInput.length === 0 ? true : false;
    setComment({ ...comment, error: flag, value: userInput });
  };

  function handleOnSuccessfulComment(data) {
    setDisplayedComment(comment.value);
    setEditando(false);
    props.handlePost();
  }

  const updateComment = () => {
    const finalComment = comment;
    let url;

    if (props.isCollection)
      url = `/collections/${props.objectID}/reviews/${props.reviewID}`;
    else url = `/learning_objects/${props.objectID}/reviews/${props.reviewID}`;

    if (!finalComment.error) {
      let payload = {
        review: {
          description: finalComment.value,
          review_ratings_attributes: props.reviewRatings,
        },
      };
      putRequest(url, payload, handleOnSuccessfulComment, (error) => {
        console.log(error);
      });
Raul Almeida's avatar
Raul Almeida committed
    }
lfr20's avatar
lfr20 committed
  };

  function handleSuccessDeleteComment(data) {
    props.rerenderCallback();
    props.handleSnackbar(3);
  }

  const deleteComment = () => {
    let url;

    if (props.isCollection)
      url = `/collections/${props.objectID}/reviews/${props.reviewID}`;
    else url = `/learning_objects/${props.objectID}/reviews/${props.reviewID}`;

    deleteRequest(url, handleSuccessDeleteComment, (error) => {
      console.log(error);
    });

    toggleModal(false);
  };
  if (props.authorID)
    return (
      <React.Fragment>
        <ModalExcluir
          open={modalOpen}
          handleClose={() => {
            toggleModal(false);
          }}
          handleConfirm={deleteComment}
        />
        <Grid container style={{ paddingLeft: "20px" }}>
          <Grid item xs={1}>
            {props.authorID && (
              <AvatarDiv>
                <Link to={"/usuario-publico/" + props.authorID}>
                  <img
                    src={
                      props.authorAvatar
                        ? apiDomain + props.authorAvatar
                        : noAvatar
                    }
                    alt="author avatar"
                  />
                </Link>
              </AvatarDiv>
            )}
          </Grid>

          <Grid item xs={10}>
            <Comentario contrast={state.contrast}>
              <div className="star-rating-container">
                <Rating
                  name="read-only"
                  value={props.rating}
                  readOnly
                  size="small"
                  style={
                    state.contrast === ""
                      ? { color: "#666" }
                      : { color: "yellow" }
                  }
                  emptyIcon={
                    <StarBorderIcon
                      fontSize="inherit"
                      style={
                        state.contrast === ""
                          ? { color: "#a5a5a5" }
                          : { color: "yellow" }
                      }
                    />
                  }
lfr20's avatar
lfr20 committed
                />
lfr20's avatar
lfr20 committed
              </div>

              {props.name && <strong>{props.name}</strong>}

              <div>
                {editando ? (
                  <React.Fragment>
                    <div style={{ marginTop: "5%", padding: "2px" }}>
                      <StyledTextField
                        contrast={props.contrast}
                        colecao={!props.recurso}
                        id="input-comentario"
                        label={"Editar Comentário"}
                        margin="normal"
                        value={comment.value}
                        InputProps={
                          props.contrast === ""
                            ? { className: classes.lightTextField }
                            : { className: classes.darkTextField }
lfr20's avatar
lfr20 committed
                        variant="outlined"
                        multiline={true}
                        rows="5"
                        onChange={(e) => {
                          handleChange(e);
                        }}
                        style={{ width: "100%" }}
                      />
                    </div>
                    <div style={{ float: "right" }}>
                      <StyledButton
                        contrast={state.contrast}
                        style={
                          state.contrast === ""
                            ? props.recurso
                              ? { backgroundColor: "#ff7f00" }
                              : { backgroundColor: "#673ab7" }
                            : {
                              backgroundColor: "black",
                              border: "1px solid white",
                              textDecoration: "underline",
lfr20's avatar
lfr20 committed
                            }
lfr20's avatar
lfr20 committed
                        }
                        onClick={() => {
                          setEditando(false);
                        }}
                      >
                        Fechar
                      </StyledButton>
                      <StyledButton
                        contrast={state.contrast}
                        style={
                          state.contrast === ""
                            ? props.recurso
                              ? { backgroundColor: "#ff7f00" }
                              : { backgroundColor: "#673ab7" }
                            : {
                              backgroundColor: "black",
                              border: "1px solid white",
                              textDecoration: "underline",
                            }
                        }
                        onClick={() => updateComment()}
                      >
                        Salvar
                      </StyledButton>
                    </div>
                  </React.Fragment>
                ) : (
                    <React.Fragment>
                      <p>
                        {props.authorID && (
                          <Link
                            to={"/usuario-publico/" + props.authorID}
                            style={{
                              fontWeight: "bolder",
                              color:
                                state.contrast === ""
                                  ? props.recurso
                                    ? "#ff7f00"
                                    : "#673ab7"
                                  : "white",
                            }}
                          >
                            {props.authorName}
                          </Link>
                        )}
                      : {displayedComment}
                      </p>
                      <span className="date">
                        {moment(props.createdAt).format("DD/MM/YYYY")}
                      </span>
                    </React.Fragment>
                  )}
              </div>
            </Comentario>
          </Grid>

          {props.authorID === state.currentUser.id && (
            <Grid item xs={1}>
              <StyledDiv>
                <Button onClick={handleClick}>
                  <EditIcon
                    style={state.contrast === "" ? {} : { color: "white" }}
                  />
                </Button>
                <Menu
                  id="simple-menu"
                  anchorEl={anchorEl}
                  keepMounted
                  open={Boolean(anchorEl)}
                  onClose={handleClose}
                >
                  <MenuItem
                    style={
                      state.contrast === ""
                        ? {}
                        : {
                          backgroundColor: "black",
                          color: "yellow",
                          textDecoration: "underline",
                        }
lfr20's avatar
lfr20 committed
                    }
lfr20's avatar
lfr20 committed
                    onClick={() => {
                      setEditando(true);
                      handleClose();
                    }}
                  >
                    Editar
                  </MenuItem>
                  <MenuItem
                    style={
                      state.contrast === ""
                        ? {}
                        : {
                          backgroundColor: "black",
                          color: "yellow",
                          textDecoration: "underline",
                        }
lfr20's avatar
lfr20 committed
                    }
lfr20's avatar
lfr20 committed
                    onClick={() => {
                      toggleModal(true);
                      handleClose();
                    }}
                  >
                    Excluir
                  </MenuItem>
                </Menu>
              </StyledDiv>
lfr20's avatar
lfr20 committed
            </Grid>
lfr20's avatar
lfr20 committed
          )}
        </Grid>
      </React.Fragment>
    );
  else
    return (
      <Grid
        container
        style={{ paddingLeft: "20px" }}
        justify="center"
        alignItems="center "
      >
        <Grid item xs={1}>
          {
            <AvatarDiv>
              <img src={noAvatar} alt="author avatar" />
            </AvatarDiv>
          }
        </Grid>

        <Grid item xs={10}>
          <Comentario contrast={state.contrast}>
            <p>O usuário que fez esse comentário deletou a conta.</p>
          </Comentario>
        </Grid>
      </Grid>
    );
Raul Almeida's avatar
Raul Almeida committed
}

const StyledTextField = styled(TextField)`
lfr20's avatar
lfr20 committed
  .MuiInputBase-root {
    margin-bottom: 5px;
  }

  .MuiOutlinedInput-root {
    &.Mui-focused fieldset {
      border-color: ${(props) =>
    props.contrast === ""
      ? props.colecao
        ? "#673ab7"
        : "rgb(255,127,0)"
      : "yellow"};
Raul Almeida's avatar
Raul Almeida committed
    }
lfr20's avatar
lfr20 committed
    fieldset {
      border-color: ${(props) => (props.contrast === "" ? "#666" : "white")};
Raul Almeida's avatar
Raul Almeida committed
    }
lfr20's avatar
lfr20 committed
  }
Raul Almeida's avatar
Raul Almeida committed

lfr20's avatar
lfr20 committed
  label {
    color: ${(props) => (props.contrast === "" ? "#666" : "white")};
  }
Raul Almeida's avatar
Raul Almeida committed

lfr20's avatar
lfr20 committed
  label.Mui-focused {
    color: ${(props) =>
    props.contrast === ""
      ? props.colecao
        ? "#673ab7"
        : "rgb(255,127,0)"
      : "yellow"};
  }
Raul Almeida's avatar
Raul Almeida committed

lfr20's avatar
lfr20 committed
  label.Mui-focused.Mui-error {
    color: red;
  }
Raul Almeida's avatar
Raul Almeida committed

lfr20's avatar
lfr20 committed
  width: 95%;
`;
Raul Almeida's avatar
Raul Almeida committed

lfr20's avatar
lfr20 committed
const StyledDiv = styled.div`
  text-align: center;
  .MuiButton-root {
    @media screen and (max-width: 990px) {
      padding-right: 35px !important;
Raul Almeida's avatar
Raul Almeida committed
    }
lfr20's avatar
lfr20 committed
  }
`;
const StyledButton = styled(Button)`
  color: ${(props) =>
    props.contrast === ""
      ? "rgba(255,255,255,0.87) !important"
      : "yellow !important"};
  box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26) !important;
  margin: 6px 8px !important;
  font-weight: 600 !important;
  :hover {
    background-color: ${(props) =>
    props.contrast === "" ? "" : "rgba(255,255,0,0.24) !important"};
  }
`;
Raul Almeida's avatar
Raul Almeida committed

lfr20's avatar
lfr20 committed
const Comentario = styled.div`
  padding-left: 55px !important;
  font-size: 14px;
  color: ${(props) => (props.contrast === "" ? "#ababab" : "white")};

  .star-rating-container {
    width: 100px;
  }

  p {
    margin: 0 0 10px;
    padding-left: 2px;
  }

  a {
    text-decoration: none !important;
  }

  .date {
    color: ${(props) => (props.contrast === "" ? "#ababab" : "white")};
    font-size: 12px;
    font-weight: lighter;
    padding-left: 3px;
  }
`;
Raul Almeida's avatar
Raul Almeida committed

const AvatarDiv = styled.div`
    text-align : center;
    float : left;
    position : relative;
    width : 65px;
    height : 65px;
    a {
        text-decoration : none !important;
    }

    img {
        width : 100% !important;
        height : 100% !important;
        border-radius : 100%
        vertical-align : middle;
    }
lfr20's avatar
lfr20 committed
`;