Skip to content
Snippets Groups Projects
ResourceCardFunction.js 13 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/>.*/

import React, { useState, useContext, useEffect } from 'react';
import { Store } from '../Store.js'
import Card from '@material-ui/core/Card';
import { apiDomain } from '../env';
import ResourceCardOptions from './ResourceCardOptions'
import Button from '@material-ui/core/Button';
import styled from 'styled-components'
import Rating from '@material-ui/lab/Rating';
import StarBorderIcon from '@material-ui/icons/StarBorder';
import FavoriteIcon from '@material-ui/icons/Favorite';
import ButtonGuardarColecao from './ButtonGuardarColecao.js'
import Grid from '@material-ui/core/Grid';
import { Link } from 'react-router-dom';
import { getDefaultThumbnail } from './HelperFunctions/getDefaultThumbnail'
import GetIconByName from './UploadPageComponents/GetIconByName'
import "./ResourceCard.css";
import { putRequest } from './HelperFunctions/getAxiosConfig'
vgm18's avatar
vgm18 committed
import SignUpModal from './SignUpModal'
import LoginModal from './LoginModal.js'
import Snackbar from '@material-ui/core/Snackbar';
import MuiAlert from '@material-ui/lab/Alert';
import { noAvatar } from "ImportImages.js";
import { IcDefault } from "ImportImages.js";
export default function ResourceCardFunction(props) {
    const { state } = useContext(Store)
    const [thumbnail, setThumbnail] = useState(null)
    // eslint-disable-next-line
    const [label, setLabel] = useState(props.type)
    const [userAvatar, setUserAvatar] = useState(noAvatar)
    const [slideIn, setSlide] = useState(false)
    const controlSlide = () => { setSlide(!slideIn) }
    const [liked, toggleLiked] = useState(props.liked)
    const [likesCount, setLikesCount] = useState(props.likeCount)
vgm18's avatar
vgm18 committed
    const [signUpOpen, setSignUp] = useState(false)
    const [loginOpen, setLogin] = useState(false)
    const [successfulLoginOpen, handleSuccessfulLogin] = useState(false)

    function Alert(props) {
        return <MuiAlert elevation={6} variant="filled" {...props} />;
    }

    useEffect(() => {
        //decide which thumbnail to use
        if (props.thumbnail) {
            setThumbnail(`${apiDomain}` + props.thumbnail)
        }
        else {
            setThumbnail(getDefaultThumbnail(label))  
        }

        if (props.avatar) {
            setUserAvatar(`${apiDomain}` + props.avatar)
        }
    function handleSuccessLike(data) {
        toggleLiked(!liked)
        setLikesCount(data.count)
    }
        if (state.currentUser.id)
            putRequest(`/learning_objects/${props.id}/like/`, {}, handleSuccessLike, (error) => { console.log(error) })
        else
            handleLogin()
vgm18's avatar
vgm18 committed
    const handleLogin = () => {
        setLogin(!loginOpen)
    }

    const handleSignUp = () => {
        setSignUp(!signUpOpen)
    }

    function toggleLoginSnackbar(reason) {
        if (reason === 'clickaway') {
            return;
        }
        handleSuccessfulLogin(false);
    }

    const SlideAnimationContent = () => {
        return (
            <SlideContentDiv>
                <div style={{ padding: 7 }}>
lfr20's avatar
lfr20 committed
                    <HeaderContainer container="row" justify="flex-start" alignItems="center" >{/*marginBottom:10px*/}
                        <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
                    }
vgm18's avatar
vgm18 committed
        <React.Fragment>
            <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>
                        <Link to={props.href}>
                            <Header onMouseEnter={controlSlide} onMouseLeave={controlSlide}>
                                <div className={`slideContentLinkBeforeActive${slideIn}`} style={{ height: '189px' }}>
                                    <img className="img-cover" src={thumbnail} alt="learning object thumbnail" style={{ width: "272.5px" }} />
vgm18's avatar
vgm18 committed
                                {
                                    <div className={`slideContentLinkAfterActive${slideIn}`}>
                                        <div className="text" >
                                            {SlideAnimationContent()}
                                        </div>
                                    </div>
                                }
                            </Header>
Lucas Eduardo Schoenfelder's avatar
Lucas Eduardo Schoenfelder committed
                        </Link>
vgm18's avatar
vgm18 committed
                        <Description>
                            <Link to={props.href} className="text" style={{ height: '45px' }}> {/*add link to learningObject*/}
                                <Title>
                                    {props.title}
                                </Title>
                            </Link>
                            <Rating
                                name="customized-empty"
                                value={props.rating}
                                readOnly
                                style={{ color: "#666" }}
                                emptyIcon={<StarBorderIcon fontSize="inherit" />}
                            />
                            <Footer>
                                <Type>
                                    {GetIconByName(label)}
                                    <span>{label}</span>
                                </Type>
                                <LikeCounter>
                                    <span>{likesCount}</span>
                                    <ButtonNoWidth onClick={handleLike}>
                                        <FavoriteIcon style={{ color: liked ? "red" : "#666" }} />
                                    </ButtonNoWidth>
                                </LikeCounter>
                            </Footer>
                        </Description>
                    </CardReaDiv>
                    <CardReaFooter>
                        <div style={{ display: "flex", height: "100%" }}>
                            <ButtonGuardarColecao thumb={props.thumbnail} title={props.title} learningObjectId={props.id}
                            />
                        </div>
                        <ResourceCardOptions
                            learningObjectId={props.id}
                            downloadableLink={props.downloadableLink}
                            thumb={props.thumbnail}
                            title={props.title}
                            handleLogin={handleLogin}
vgm18's avatar
vgm18 committed
                    </CardReaFooter>
                </CardDiv>
            </StyledCard>
        </React.Fragment>
    )
}
/*---------- USED IN SLIDE DIV ONLY -----------*/
lfr20's avatar
lfr20 committed
export const HeaderContainer = styled(Grid)`
lfr20's avatar
lfr20 committed
export const TagContainer = styled(Grid)`
    margin-top: 0.5em;
lfr20's avatar
lfr20 committed
    height : 120px ;
    overflow-y : hidden;
    ${'' /* border : 2px solid red; */}
        word-wrap: break-word;
        display : flex;
        justify-content : center;
        align-items : center;
        height : 22px;
        tet-align : center;
        margin: 3px;
        -webkit-box-direction: normal;
        padding : 1px 8px;
lfr20's avatar
lfr20 committed
export const EnviadoPor = styled(Grid)`
    display : inline-block;
    padding-left : 10px;
    overflow : hidden;
    color : #fff;
    padding-right : 1em;

    p {
        margin : 0;
        display: -webkit-box;
        -webkit-line-clamp: 1;
        -webkit-box-orient: vertical;
        overflow: hidden;
lfr20's avatar
lfr20 committed
export const AvatarDiv = styled(Grid)`
lfr20's avatar
lfr20 committed
    width : 40px;
    height : 40px;
lfr20's avatar
lfr20 committed
        max-height: 100%;
        max-width: 100%;
        border : 0;
        vertical-align : middle;
        border-radius : 50%;
    }
`

const SlideContentDiv = styled.div`
    background-color : #ff9226;
lfr20's avatar
lfr20 committed
    ${'' /* padding : 10px; */}
    width : 272.5px;
    height : 189px;
`
/*--------------------------------------------*/

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

export const ButtonNoWidth = styled(Button)`
    max-width : 24px !important;
    width : 24px !important;
    min-width : 24px !important;
    max-height : 24px !important;
    padding : 0 !important;
    background-color : #fff !important;
    color : #a5a5a5 !important;
    border : 0 !important;

    .MuiButton-root {
        width : 24px !important;
        min-width : 12px !important;
    }

    .MuiSvgIcon-root {
        padding-right : 0 !important;
    }

    .MuiButton-label {
        padding-left : 4px !important;
    }
`

export const LikeCounter = styled.div`
    font-size : 14px;

    .btn-like {
        padding : 0 !important;
        background-color : #fff !important;
        border : 0 !important;
        min-width : min-content;
    }

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

const Type = styled.div`
    line-height : 1;

    .icon {
        height : 27px;
        width : 27px;
        vertical-align : middle
        align-self : center;

        .st1 {
            fill : #ff7f00;
        }
    }
`

export const Footer = styled.div`
    display : flex;
    flex-direction : row;
    justify-content : space-between;
`

const Description = styled.div`
    display : flex;
    flex : 1;
    background-color : #fff;
    flex-direction : column;
    justify-content: space-between;
    padding : 15px;

    a {
        text-decoration : none !important;
        color : inherit;
    }
`
const Title = styled.span`
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    color : #666;
`

export const Header = styled.div`
    display : flex;
    flex : 2;
    position : relative;
    overflow : hidden;
`

export const CardReaDiv = styled.div`
    display : flex;
    flex-direction : column;
    height : 320px;
lfr20's avatar
lfr20 committed
    ${'' /* width : 272.5px; */}
    margin : 0 auto;

    .img-cover {
        background-color : #e5e5e5;
        height : 100%;
        object-fit : cover;
        overflow : hidden;
        display : block;
        background-position : center;
        background-size : cover;
lfr20's avatar
lfr20 committed
        ${'' /* width : 100%; */}
    }
`

export const CardDiv = styled.div`
    background-color : #fff;
    text-align : start;
    font-family : 'Roboto', sans serif;
    color : #666;
`

export const StyledCard = styled(Card)`
    width : 272.5px;
    max-height : 380px;
    margin-top : 10px;
    margin-bottom : 10px;
lfr20's avatar
lfr20 committed
    ${'' /* max-width : 345px; */}
    border-radius : 0;
    box-shadow : 0 0 5px 0 rgba(0,0,0,.25);
`