Skip to content
Snippets Groups Projects
CollectionCardFunction.js 15.1 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, useContext, useEffect } from 'react';
import { Store } from '../Store.js'
import { apiDomain } from '../env';
import noAvatar from "../img/default_profile.png";
import Button from '@material-ui/core/Button';
import styled from 'styled-components'
import Grid from '@material-ui/core/Grid';
import { StyledCard, CardDiv, CardReaDiv, Footer, LikeCounter, ButtonNoWidth, EnviadoPor, TagContainer, HeaderContainer, AvatarDiv } from './ResourceCardFunction.js'
import Rating from '@material-ui/lab/Rating';
import StarBorderIcon from '@material-ui/icons/StarBorder';
import FolderIcon from '@material-ui/icons/Folder';
import FavoriteIcon from '@material-ui/icons/Favorite';
import AddIcon from '@material-ui/icons/Add';
import CheckIcon from '@material-ui/icons/Check';
import LockIcon from '@material-ui/icons/Lock';
import ColCardOwnerOptions from './ColCardOwnerOptions.js'
import ColCardPublicOptions from './ColCardPublicOptions'
lfr20's avatar
lfr20 committed
import { Link } from 'react-router-dom';
lfr20's avatar
lfr20 committed
import { putRequest } from '../Components/HelperFunctions/getAxiosConfig'
lfr20's avatar
lfr20 committed
import SignUpModal from './SignUpModal'
import LoginModal from './LoginModal.js'
import Snackbar from '@material-ui/core/Snackbar';
import MuiAlert from '@material-ui/lab/Alert';
lfr20's avatar
lfr20 committed
export default function CollectionCardFunction(props) {
  const { state } = useContext(Store)

  // eslint-disable-next-line
  const [userAvatar] = useState(props.avatar ? (`${apiDomain}` + props.avatar) : noAvatar)
  const [userFollowingCol, toggleUserFollowingCol] = useState(props.followed)
  const handleToggleUserFollowingCol = () => { toggleUserFollowingCol(!userFollowingCol) }

  const [name, setName] = useState(props.name)
  const changeColName = (newName) => { setName(newName) }

  const [privacy, setPrivacy] = useState(props.privacy)
  const changeColPrivacy = (newPrivacy) => { setPrivacy(newPrivacy) }

  const [likesCount, setLikesCount] = useState(props.likeCount)
  const [liked, toggleLiked] = useState(props.liked)

  const [signUpOpen, setSignUp] = useState(false)
  const [loginOpen, setLogin] = useState(false)
  const [successfulLoginOpen, handleSuccessfulLogin] = useState(false)


  function handleSuccessLike(data) {
    toggleLiked(!liked)
    setLikesCount(data.count)
  }
  const handleLike = () => {
    if (state.currentUser.id)
      putRequest(`/collections/${props.id}/like`, {}, handleSuccessLike, (error) => { console.log(error) })
    else
      handleLogin()
  }

  const [followingHover, handleFollowingHover] = useState(false)
  const toggleFollowingHover = (value) => { handleFollowingHover(value) }

  const [slideIn, setSlide] = useState(false)
  const controlSlide = () => { setSlide(!slideIn) }

  function handleSuccessFollow(data) {
    handleToggleUserFollowingCol()
  }
  const handleFollow = () => {
    if (state.currentUser.id)
      putRequest(`/collections/${props.id}/follow`, {}, handleSuccessFollow, (error) => { console.log(error) })
    else
      handleLogin()
  }

  const RenderFollowButton = () => {
    return (
      <FollowButton onClick={handleFollow}>
        <AddIcon /><span>SEGUIR</span>
      </FollowButton>
    )
  }
  useEffect(() => {
    if (!state.currentUser.id) {
      toggleLiked(false);
      toggleUserFollowingCol(false);
  }, [state.currentUser.id])
  const RenderFollowingButton = () => {
    return (
      <FollowingButton onMouseOver={() => toggleFollowingHover(true)}
        onMouseLeave={() => toggleFollowingHover(false)} onClick={handleFollow}>
        {
          followingHover ?
            (
              [
                <span>DEIXAR DE SEGUIR</span>
              ]
            )
            :
            (
              [
                <React.Fragment>
                  <CheckIcon /><span>SEGUINDO</span>
                </React.Fragment>
              ]
            )
      </FollowingButton>
    )
  }
  const SlideAnimationContent = () => {
    return (
      <SlideContentDiv>
        <HeaderContainer container="row" justify="flex-start" alignItems="center">
          <AvatarDiv item xs={2}>
            <img className="img" src={userAvatar} alt="user avatar" />
          </AvatarDiv>
          <EnviadoPor item xs={10}>
            Enviado por:
            <p>{props.author}</p>
          </EnviadoPor>
        </HeaderContainer>
        {
          props.tags ?
            <TagContainer container direction="row">
              {
                props.tags.map((tag) =>
                  <Grid item key={tag.id}>
                    <span >{tag.name}</span>
                  </Grid>
                )
              }
            </TagContainer> :
            null
        }
      </SlideContentDiv>
    )
  }
  const handleSignUp = () => {
    setSignUp(!signUpOpen)
  }
  const handleLogin = () => {
    setLogin(!loginOpen)
  }
  function Alert(props) {
    return <MuiAlert elevation={6} variant="filled" {...props} />;
  }
  function toggleLoginSnackbar(reason) {
    if (reason === 'clickaway') {
      return;
lfr20's avatar
lfr20 committed
    }
    handleSuccessfulLogin(false);
  }

  return (
    <>
      <SignUpModal open={signUpOpen} handleClose={handleSignUp} openLogin={handleLogin}
      />
      <LoginModal open={loginOpen} handleClose={() => setLogin(false)} openSignUp={handleSignUp}
        openSnackbar={() => { handleSuccessfulLogin(true) }}
      />
      <Snackbar open={successfulLoginOpen} autoHideDuration={1000} onClose={toggleLoginSnackbar}
        anchorOrigin={{ vertical: 'top', horizontal: 'center' }}
      >
        <Alert severity="success" style={{ backgroundColor: "#00acc1" }}>Você está conectado(a)!</Alert>
      </Snackbar>
      <StyledCard>
        <CardDiv>
          <CardReaDiv>
vgm18's avatar
vgm18 committed
            <Link to={"/colecao-do-usuario/" + props.id}>
              <Header onMouseEnter={controlSlide} onMouseLeave={controlSlide}>
                <div className={`slideContentLinkBeforeActive${slideIn}`} style={{ width: '272.5px', height: '230px' }}>
                  <UserInfo style={{ width: '272.5px'}}>
                    {/* I(Luis) dont know why, but if i use styled components, sometimes the avatar will be deconfigured */}
                    <img src={userAvatar} alt="user avatar" style={{
                      height: "70px", width: "70px", borderRadius: "50%",
                      zIndex: 1, border: "2px solid white",
                      boxShadow: "0 1px 3px rgba(0,0,0,.45)"
                    }} />
                    <UserAndTitle>
                      <span>{props.author}</span>
                      <span className={"col-name"}>{name}</span>
                    </UserAndTitle>
                  </UserInfo>
                  <StyledGrid container direction="row" style={{ width: '272.5px' }}>
vgm18's avatar
vgm18 committed
                    {
                      props.thumbnails.map((thumb) =>
                        <Grid item xs={props.thumbnails.length <= 3 && props.thumbnails.length > 0 ? 12 / props.thumbnails.length : 6}>
                          <div style={{ backgroundImage: `url(${`${apiDomain}` + thumb})`, height: `${props.thumbnails.length <= 3 ? '230px' : '100%'}`, width: "100%", backgroundSize: "cover", backgroundPosition: "center" }} />
vgm18's avatar
vgm18 committed
                        </Grid>
                      )
                    }
                  </StyledGrid>
                </div>
vgm18's avatar
vgm18 committed
                {
                  <div className={`slideContentLinkAfterActive${slideIn}`} style={{ width: '272.5px', height: '230px' }}>
                    <div className="text" >
                      {SlideAnimationContent()}
                    </div>
                  </div>
                }
              </Header>
            </Link>

            <Description> {/*renders rating, number of learning objects and likes count*/}
              {
                props.authorID !== state.currentUser.id &&
                <Rating
                  name="customized-empty"
                  value={props.rating}
                  readOnly
                  style={{ color: "#666" }}
                  emptyIcon={<StarBorderIcon fontSize="inherit" />}
                />
              }

              <Footer>
                <Type>
                  <FolderIcon />
lfr20's avatar
lfr20 committed
                  <span style={{ fontWeight: "bold" }}>{props.collections ? props.collections.length : 0} </span>
                  <span>{props.collections ? props.collections.length !== 1 ? "Recursos" : "Recurso" : 0}</span>
                </Type>
                <LikeCounter>
                  <span>{likesCount}</span>
                  <ButtonNoWidth onClick={handleLike}>
                    <FavoriteIcon style={{ color: liked ? "red" : "#666" }} />
                  </ButtonNoWidth>
                </LikeCounter>
              </Footer>
            </Description>

          </CardReaDiv>

          {
            props.authorID === state.currentUser.id ?
              (
                <CardReaFooter style={{ justifyContent: "space-between" }}> {/*renders following/unfollow and follow button*/}
                  <Grid container>
                    <Grid item xs={6} style={{ display: "flex", justifyContent: "center" }}>
                      {
                        privacy === 'private' &&
                        <LockIcon style={{ color: "#666" }} />
                      }
                    </Grid>
                    <Grid item xs={6} style={{ display: "flex", justifyContent: "flex-end" }}>
                      <ColCardOwnerOptions
                        id={props.id}
                        changeColName={changeColName}
                        changeColPrivacy={changeColPrivacy}
                      />
                    </Grid>
                  </Grid>
                </CardReaFooter>
              )
              :
              (
                <CardReaFooter> {/*renders following/unfollow and follow button*/}
                  {
                    userFollowingCol ?
                      (
                        [
                          RenderFollowingButton()
                        ]
                      )
                      :
                      (
                        [
                          RenderFollowButton()
                        ]
                      )
                  }
                  <ColCardPublicOptions
                    id={props.id}
                    userFollowingCol={userFollowingCol}
                    handleLike={handleLike}
                    handleFollow={handleFollow}
                    liked={liked}
                    handleLogin={handleLogin}
                    currentUserId={state.currentUser.id}
                  />
                </CardReaFooter>
              )
          }

        </CardDiv>
      </StyledCard>
    </>
  )
}



const SlideContentDiv = styled.div`
    background-color : #7e57c2;
    padding : 10px;
vgm18's avatar
vgm18 committed
    width : 272.5px;
    height : 230px;
`

const UserAndTitle = styled.div`
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    -webkit-box-orient: vertical;
    -webkit-box-direction: normal;
    -ms-flex-direction: column;
    flex-direction: column;
    width: 100%;
    -webkit-box-align: center;
    -ms-flex-align: center;
    align-items: center;
    padding: 30px 10px 10px 10px;
    margin-top: -25px;
    background-color: rgba(0,0,0,.5);
    color: #fff;

    .col-name {
        padding-top: 5px;
        font-size: 17px;
        font-weight: 500;
        text-overflow: ellipsis;
        overflow: hidden;
        text-align: center;
        width: 100%;
    }
`

const UserInfo = styled.div`
    position : absolute;
    display : flex;
    flex-direction : column;
    width : 100%;
    height : 100%;
    justify-content : flex-end;
    align-items : center;

`

const CardReaFooter = styled.div`
    height : 60px;
    display : flex;
    justify-content : center;
    align-items : center;
    border-top : 1px solid #e5e5e5;

    .MuiSvgIcon-root {
        font-family: 'Material Icons';
        color : inherit;
        font-weight: normal;
        font-style: normal;
        font-size: 24px;
        line-height: 1;
        letter-spacing: normal;
        text-transform: none;
        display: inline-block;
        white-space: nowrap;
        word-wrap: normal;
        direction: ltr;
    }
`

const Type = styled.div`
    line-height : 1;
    font-size : .85em;

    .MuiSvgIcon-root {
        font-size : 21px;
        color : #673ab7;
        vertical-align : middle;
        padding-right : .4em;
    }
`

const StyledGrid = styled(Grid)`
    .MuiGrid-item {
        height : 136px;
        width 130px;
        background : #f9f9f9;
        border : 1px solid #f4f4f4;
        border-color : #f4f4f4;
    }
`

const Header = styled.div`
    display : flex;
    height : 230px;
    position : relative;
    overflow : hidden;
`

const Description = styled.div`
    display : flex;
    height : 60px
    background-color : #fff;
    flex-direction : column;
    justify-content: space-between;
    padding : 15px;
`
const FollowButton = styled(Button)`
    border : 2px solid #503096 !important;
    border-radius : 5px !important;
    margin : 10px !important;
    color :#503096 !important;
    min-width : 150px !important;
    min-height : 36px !important;
    text-align : center !important;
    vertical-align : middle !important;
    background : transparent !important;
    text-transform : uppercase !important;
    font-family : inherit !important;
    overflow : hidden !important;
    font-weight : normal !important;
    text-decoration : none !important;
    letter-spacing: .01em !important;
    white-space : nowrap !important;
    font-weight: 500;

    &:hover {
        background-color : rgba(158,158,158,0.2) !important;

    }

`
const FollowingButton = styled(Button)`
    border : 2px solid #503096 !important;
    border-radius : 5px !important;
    margin : 10px !important;
    color :#fff !important;
    min-width : 150px !important;
    min-height : 36px !important;
    text-align : center !important;
    vertical-align : middle !important;
    background-color : #503096 !important;
    text-transform : uppercase !important;
    font-family : inherit !important;
    overflow : hidden !important;
    font-weight : normal !important;
    text-decoration : none !important;
    letter-spacing: .01em !important;
    white-space : nowrap !important;
    font-weight: 500;

    &:hover {
        background-color : rgba(158,158,158,0.2) !important;
        color : #503096 !important;
        box-shadow : none !important;
    }

`