Skip to content
Snippets Groups Projects
CollectionCardFunction.js 20.2 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, apiUrl } from '../env';
import noAvatar from "../img/default_profile.png";
import Button from '@material-ui/core/Button';
import styled from 'styled-components'
import Slide from '@material-ui/core/Slide';
import Grid from '@material-ui/core/Grid';
lfr20's avatar
lfr20 committed
import { StyledCard, CardDiv, CardReaDiv, Footer, LikeCounter, ButtonNoWidth, EnviadoPor, TagContainer } 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 { getAxiosConfig } from '../Components/HelperFunctions/getAxiosConfig'
import { saveHeaders } from '../Components/HelperFunctions/saveTokens';
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) {
    // console.log(props);
lfr20's avatar
lfr20 committed
    const { state } = useContext(Store)
    // eslint-disable-next-line
    const [userAvatar] = useState(props.avatar ? (`${apiDomain}` + props.avatar) : noAvatar)
lfr20's avatar
lfr20 committed
    const [userFollowingCol, toggleUserFollowingCol] = useState(props.followed ? props.followed : false)
    const handleToggleUserFollowingCol = () => { toggleUserFollowingCol(!userFollowingCol) }
    const [likesCount, setLikesCount] = useState(props.likeCount)
    const [liked, toggleLiked] = useState(props.liked)
lfr20's avatar
lfr20 committed

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

    const handleLike = () => {
        let payload = {}
        let config = getAxiosConfig()

lfr20's avatar
lfr20 committed
        if (state.currentUser.id) {
            axios({
                method: 'put',
                url: `${apiUrl}/collections/` + props.id + '/like',
                headers: config.headers
            }).then(
                (response) => {
                    toggleLiked(!liked)
                    setLikesCount(response.data.count)
                    saveHeaders(response)
                },
                (error) => { console.log(error) }
            )
        }
        else {
            setLogin(!loginOpen)
        }
    const [followingHover, handleFollowingHover] = useState(false)
lfr20's avatar
lfr20 committed
    const toggleFollowingHover = (value) => { handleFollowingHover(value) }
lfr20's avatar
lfr20 committed
    const controlSlide = () => { setSlide(!slideIn) }
    const handleFollow = () => {
        let config = getAxiosConfig()
        let payload = {}

lfr20's avatar
lfr20 committed
        if (state.currentUser.id) {
            axios.put((`${apiUrl}/collections/` + props.id + '/follow'), payload, config).then(
                (response) => {
                    saveHeaders(response)
                    handleToggleUserFollowingCol()
                },
                (error) => { console.log(error) }
            )
        }
        else {
            setLogin(!loginOpen)
        }
            <FollowButton onClick={handleFollow}>
lfr20's avatar
lfr20 committed
                <AddIcon /><span>SEGUIR</span>
lfr20's avatar
lfr20 committed
    useEffect(() => {
        // setTimeout(function () {
        //     if (state.currentUser.id) {
        //         const config = getAxiosConfig();
        //         axios({
        //             method: 'get',
        //             url: `${apiUrl}/users/${state.currentUser.id}/following/Collection`,
        //             headers: config.headers
        //         }).then(
        //             (response) => {
        //                 const data = response.data
        //                 for (let i = 0; i < data.length; i++)
        //                     if (data[i].followable.id === props.id)
        //                         toggleUserFollowingCol(true)
        //                 saveHeaders(response)
        //             })
        //     }
        //     else {
        //         toggleLiked(false);
        //         toggleUserFollowingCol(false);
        //     }
        // }, 1000);
        
        // setTimeout(function () {
        //     if (state.currentUser.id) {
        //         const config = getAxiosConfig();
        //         axios({
        //             method: 'get',
        //             url: `${apiUrl}/users/${state.currentUser.id}/collections/liked`,
        //             headers: config.headers
        //         }).then(
        //             (response) => {
        //                 const data = response.data
        //                 for (let i = 0; i < data.length; i++)
        //                     if (data[i].id === props.id)
        //                         toggleLiked(true)
        //                 saveHeaders(response)
        //             })
        //     }
        //     else {
        //         toggleLiked(false);
        //         toggleUserFollowingCol(false);
        //     }
        // }, 2000);
        if(!state.currentUser.id)
        {
            toggleLiked(false);
            toggleUserFollowingCol(false);
        }
lfr20's avatar
lfr20 committed
    }, [state.currentUser.id])

    const RenderFollowingButton = () => {
        return (
            <FollowingButton onMouseOver={() => toggleFollowingHover(true)}
                onMouseLeave={() => toggleFollowingHover(false)} onClick={handleFollow}>
lfr20's avatar
lfr20 committed
                        (
                            [
                                <span>DEIXAR DE SEGUIR</span>
                            ]
                        )
                        :
                        (
                            [
                                <React.Fragment>
                                    <CheckIcon /><span>SEGUINDO</span>
                                </React.Fragment>
                            ]
                        )
                }
            </FollowingButton>
        )
    }

    const SlideAnimationContent = () => {
        return (
            // <SlideContentDiv>
            //     <HeaderContainer>{/*marginBottom:10px*/}
            //         <AvatarDiv>
            //             <img className="img" src={userAvatar} alt="user avatar" />
            //         </AvatarDiv>
            //         <EnviadoPor>
            //             Enviado por:
            //             <br />
            //             <p>{props.author}</p>
            //         </EnviadoPor>
            //     </HeaderContainer>
            //     <TagContainer>
            //         {
            //             props.tags.map((tag) =>
            //                 <span key={tag.id}>{tag.name}</span>

            //             )
            //         }
            //     </TagContainer>
            // </SlideContentDiv>
lfr20's avatar
lfr20 committed
                <div style={{ display: "flex", flex: "1" }}>{/*marginBottom:10px*/}
lfr20's avatar
lfr20 committed
                        <img className="img" src={userAvatar} alt="user avatar" />
lfr20's avatar
lfr20 committed
                    <br />
lfr20's avatar
lfr20 committed
                    props.tags &&
                    <TagContainer>
                        {
                            props.tags.map((tag) =>
lfr20's avatar
lfr20 committed
                            )
                        }
                    </TagContainer>
lfr20's avatar
lfr20 committed
    const handleSignUp = () => {
        setSignUp(!signUpOpen)
    }
lfr20's avatar
lfr20 committed
    const handleLogin = () => {
        setLogin(!loginOpen)
    }
lfr20's avatar
lfr20 committed
    function Alert(props) {
        return <MuiAlert elevation={6} variant="filled" {...props} />;
    }
lfr20's avatar
lfr20 committed
    function toggleLoginSnackbar(reason) {
        if (reason === 'clickaway') {
            return;
        }
        handleSuccessfulLogin(false);
    }
lfr20's avatar
lfr20 committed
    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>
                        <Header onMouseEnter={controlSlide} onMouseLeave={controlSlide}>
                            {/*slide animation and content*/}
                            <Slide direction="right" in={slideIn} timeout={1000}>
                                <Link to={"/colecao-do-usuario/" + props.id} className="text">
                                    {SlideAnimationContent()}
                                </Link>
                            </Slide>
                            <div className={`slideContentLinkBeforeActive${slideIn}`} style={{ width: '100%', height: '100%' }}>
                                <a href={"/colecao-do-usuario/" + props.id}>
                                    <UserInfo>
                                        <AvatarDiv>
                                            <img src={userAvatar} alt="user avatar" />
                                        </AvatarDiv>
                                        <UserAndTitle>
                                            <span>{props.author}</span>
                                            <span className={"col-name"}>{props.name}</span>
                                        </UserAndTitle>
                                    </UserInfo>
                                    <StyledGrid container direction="row">
                                        {
                                            props.thumbnails.map((thumb) =>
                                                <Grid item xs={props.thumbnails <= 4 && props.thumbnails > 0 ? 12 / props.thumbnails.length : 6}>
                                                    <div style={{ backgroundImage: `url(${`${apiDomain}` + thumb})`, height: "100%", width: "100%", backgroundSize: "cover", backgroundPosition: "center" }} />
                                                </Grid>
                                            )
                                        }
                                    </StyledGrid>
                                </a>
                            </div>
                        </Header>
lfr20's avatar
lfr20 committed
                        <Description> {/*renders rating, number of learning objects and likes count*/}
                            {
                                props.authorID !== state.currentUser.id &&
                                <Rating
                                    name="customized-empty"
                                    value={props.rating * 10}
                                    precision={0.5}
                                    readOnly
                                    style={{ color: "#666" }}
                                    emptyIcon={<StarBorderIcon fontSize="inherit" />}
                                />
                            }
lfr20's avatar
lfr20 committed
                            <Footer>
                                <Type>
                                    <FolderIcon />
                                    <span style={{ fontWeight: "bold" }}>{props.collections.length} </span>
                                    <span>{props.collections.length !== 1 ? "Recursos" : "Recurso"}</span>
                                </Type>
                                <LikeCounter>
                                    <span>{likesCount}</span>
                                    <ButtonNoWidth onClick={handleLike}>
                                        <FavoriteIcon style={{ color: liked ? "red" : "#666" }} />
                                    </ButtonNoWidth>
                                </LikeCounter>
                            </Footer>
                        </Description>
lfr20's avatar
lfr20 committed
                    </CardReaDiv>
lfr20's avatar
lfr20 committed
                    {
                        props.authorID === state.currentUser.id ?
lfr20's avatar
lfr20 committed
                                <CardReaFooter style={{ justifyContent: "space-between" }}> {/*renders following/unfollow and follow button*/}
                                    <Grid container>
                                        <Grid item xs={6} style={{ display: "flex", justifyContent: "center" }}>
                                            {
                                                props.privacy === 'private' &&
                                                <LockIcon style={{ color: "#666" }} />
                                            }
                                        </Grid>
                                        <Grid item xs={6} style={{ display: "flex", justifyContent: "flex-end" }}>
                                            <ColCardOwnerOptions
                                                id={props.id}
                                            />
                                        </Grid>
                                    </Grid>
                                </CardReaFooter>
lfr20's avatar
lfr20 committed
                                <CardReaFooter> {/*renders following/unfollow and follow button*/}
                                    {
                                        userFollowingCol ?
                                            (
                                                [
                                                    RenderFollowingButton()
                                                ]
                                            )
                                            :
                                            (
                                                [
                                                    RenderFollowButton()
                                                ]
                                            )
                                    }
                                    <ColCardPublicOptions
                                        id={props.id}
                                    />
                                </CardReaFooter>
lfr20's avatar
lfr20 committed
                    }
lfr20's avatar
lfr20 committed
                </CardDiv>
            </StyledCard>
        </>
    )
}

const SlideAvatarDiv = styled.div`
    vertical-align : middle;
    border : 0;

        height : 40px !important;
        width : 40px !important;
        border : 0;
        vertical-align : middle;
        border-radius : 50%;
    }
`

const SlideContentDiv = styled.div`
    background-color : #7e57c2;
    padding : 10px;
    width : 100%;
    height : 100%;
    position : absolute;
    display : flex;
    flex-direction : column;
`

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 AvatarDiv = styled.div`
    z-index : 5;
    overflow : hidden;

    img {
        border-radius : 50%;
        height : 70px;
        width : 70px;
        border : 2px solid #fff !important;
        background-color : #fff;
        box-shadow : 0 1px 3px rgba(0,0,0,.45);
    }
`

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;
    }

`