Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • portalmec/portalmec-react
  • rfhferreira/cleaning-portal-mec-react
2 results
Show changes
Commits on Source (18)
Showing
with 661 additions and 710 deletions
/*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 axios from 'axios';
export function Delete(api) {
return new Promise(resolve => {
axios({
method: 'delete',
url: api,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json; charset=utf-8',
'access-token': sessionStorage.getItem('@portalmec/accessToken'),
'client': sessionStorage.getItem('@portalmec/clientToken'),
'uid': sessionStorage.getItem('@portalmec/uid'),
'If-None-Match': null
},
}).then(response => {
if (response.status === 200) {
resolve(true);
} else {
resolve(false);
}
SaveNewHeaders(response)
}).catch(err =>{
resolve(false)
})
})
}
export function SendEmail(api, body) {
return new Promise(resolve => {
axios({
method: 'post',
url: api,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json; charset=utf-8',
'access-token': sessionStorage.getItem('@portalmec/accessToken'),
'client': sessionStorage.getItem('@portalmec/clientToken'),
'uid': sessionStorage.getItem('@portalmec/uid'),
'If-None-Match': null
},
data: JSON.stringify(body)
}).then(response => {
console.log(response)
if (response.status === 200) {
resolve(true);
} else {
resolve(false);
}
SaveNewHeaders(response)
}).catch(err =>{
resolve(false)
})
})
}
export function Edit(api, body) {
return new Promise(resolve => {
axios({
method: 'put',
url: api,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json; charset=utf-8',
'access-token': sessionStorage.getItem('@portalmec/accessToken'),
'client': sessionStorage.getItem('@portalmec/clientToken'),
'uid': sessionStorage.getItem('@portalmec/uid'),
'If-None-Match': null
},
data: JSON.stringify(body)
}).then(response => {
console.log(response)
if (response.status === 200) {
resolve(true)
} else {
resolve(false)
}
SaveNewHeaders(response)
}).catch(err =>{
resolve(false)
})
})
}
export function Create(api, body) {
return new Promise(resolve => {
axios({
method: 'post',
url: api,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json; charset=utf-8',
'access-token': sessionStorage.getItem('@portalmec/accessToken'),
'client': sessionStorage.getItem('@portalmec/clientToken'),
'uid': sessionStorage.getItem('@portalmec/uid'),
'If-None-Match': null
},
data: JSON.stringify(body)
}).then(response => {
if (response.status === 201) {
resolve(true)
} else {
resolve(false)
}
SaveNewHeaders(response)
}).catch(err =>{
resolve(false)
})
})
}
export function HandleComplain(api) {
return new Promise(resolve => {
axios({
method: 'post',
url: api,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json; charset=utf-8',
'access-token': sessionStorage.getItem('@portalmec/accessToken'),
'client': sessionStorage.getItem('@portalmec/clientToken'),
'uid': sessionStorage.getItem('@portalmec/uid'),
'If-None-Match': null
},
}).then(response => {
if (response.status === 200) {
resolve(true)
} else {
resolve(false)
}
SaveNewHeaders(response)
}).catch(err =>{
resolve(false)
})
})
}
export function GetFullList(api, headers) {
return new Promise(resolve => {
axios({
method: 'get',
url: api,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json; charset=utf-8',
'access-token': sessionStorage.getItem('@portalmec/accessToken'),
'client': sessionStorage.getItem('@portalmec/clientToken'),
'uid': sessionStorage.getItem('@portalmec/uid'),
'If-None-Match': null
},
}).then((res) => {
console.log(res)
if (res.status === 200) {
resolve({
state: true,
data: res.data
})
} else {
resolve({
state: false,
data: {}
})
}
SaveNewHeaders(res)
}).catch((err) => {
resolve({
state: false,
data: {}
})
})
}, []);
}
export function GetSpecificData(api, headers) {
return new Promise(resolve => {
axios({
method: 'get',
url: api,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json; charset=utf-8',
'access-token': sessionStorage.getItem('@portalmec/accessToken'),
'client': sessionStorage.getItem('@portalmec/clientToken'),
'uid': sessionStorage.getItem('@portalmec/uid'),
'If-None-Match': null
},
}).then((res) => {
console.log(res)
if (res.status === 200) {
resolve({
state: true,
data: res.data
})
} else {
resolve({
state: false,
data: {}
})
}
SaveNewHeaders(res)
}).catch((err) => {
resolve({
state: false,
data: {}
})
})
}, []);
}
const SaveNewHeaders = (response) => {
if (
(response.headers['access-token'] === undefined || response.headers['access-token'] === null) &&
(response.headers.client === undefined || response.headers.client === null)
) {
} else {
sessionStorage.setItem('@portalmec/accessToken', response.headers['access-token'])
sessionStorage.setItem('@portalmec/clientToken', response.headers.client)
console.log('saved')
}
}
......@@ -25,13 +25,14 @@ import OpenIcon from '@material-ui/icons/OpenInNew';
import { Link } from 'react-router-dom'
import MoreVertIcon from '@material-ui/icons/MoreVert';
import styled from 'styled-components'
import ErrorIcon from '@material-ui/icons/Error';
import FavoriteIcon from '@material-ui/icons/Favorite';
import ReportModal from './ReportModal.js'
import ReportProblemIcon from '@material-ui/icons/ReportProblem';
import OpenInBrowserIcon from '@material-ui/icons/OpenInBrowser';
import { deleteRequest } from '../Components/HelperFunctions/getAxiosConfig'
import AddIcon from '@material-ui/icons/Add';
import ExitToAppIcon from '@material-ui/icons/ExitToApp';
export default function ColCardPublicOptions(props) {
export default function ColCardPublicOptions({ id, userFollowingCol, handleLike, handleFollow, currentUserId, handleLogin, liked }) {
const [anchorEl, setAnchorEl] = React.useState(null);
function handleClick(event) {
......@@ -45,20 +46,13 @@ export default function ColCardPublicOptions(props) {
const [reportModalOpen, toggleReportModal] = useState(false)
const handleReportModal = (value) => { toggleReportModal(value) }
const handleUnfollow = () => {
if (props.currentUserId)
deleteRequest(`/collections/${props.id}/follow`, (data) => { console.log(data) }, (error) => { console.log(error) })
else
props.handleLogin()
}
return (
<>
<ReportModal
open={reportModalOpen}
handleClose={() => handleReportModal(false)}
form="colecao"
complainableId={props.id}
complainableId={id}
complainableType={"Collection"}
/>
<div style={{ fontSize: "12px" }}>
......@@ -78,7 +72,7 @@ export default function ColCardPublicOptions(props) {
onClose={handleClose}
>
<StyledMenuItem>
<Link to={"/colecao-do-usuario/" + props.id}>
<Link to={"/colecao-do-usuario/" + id}>
<ListItemIcon>
<OpenIcon />
</ListItemIcon>
......@@ -88,7 +82,7 @@ export default function ColCardPublicOptions(props) {
<StyledMenuItem
onClick={() =>
window.open("/colecao-do-usuario/" + props.id, "_blank")
window.open("/colecao-do-usuario/" + id, "_blank")
}
>
<ListItemIcon>
......@@ -97,19 +91,38 @@ export default function ColCardPublicOptions(props) {
Abrir em nova guia
</StyledMenuItem>
<StyledMenuItem onClick={handleUnfollow}>
<StyledMenuItem onClick={handleLike}>
<ListItemIcon>
{
liked ?
<FavoriteIcon style={{ fill: 'red' }} /> : <FavoriteIcon style={{ fill: '#666' }} />
}
</ListItemIcon>
{
liked ?
"Desfavoritar" : "Favoritar"
}
</StyledMenuItem>
<StyledMenuItem onClick={handleFollow}>
<ListItemIcon>
<ErrorIcon />
{
userFollowingCol ?
<ExitToAppIcon /> : <AddIcon />
}
</ListItemIcon>
Deixar de Seguir
{
userFollowingCol ?
"Deixar de seguir" : "Seguir"
}
</StyledMenuItem>
<StyledMenuItem
onClick={() => {
if (props.currentUserId)
if (currentUserId)
handleReportModal(true);
else
props.handleLogin()
handleLogin()
}}
>
<ListItemIcon>
......
......@@ -46,7 +46,7 @@ export default function CollectionCardFunction(props) {
// eslint-disable-next-line
const [userAvatar] = useState(props.avatar ? (`${apiDomain}` + props.avatar) : noAvatar)
const [userFollowingCol, toggleUserFollowingCol] = useState(props.followed ? props.followed : false)
const [userFollowingCol, toggleUserFollowingCol] = useState(props.followed)
const handleToggleUserFollowingCol = () => { toggleUserFollowingCol(!userFollowingCol) }
const [name, setName] = useState(props.name)
......@@ -297,6 +297,10 @@ export default function CollectionCardFunction(props) {
}
<ColCardPublicOptions
id={props.id}
userFollowingCol={userFollowingCol}
handleLike={handleLike}
handleFollow={handleFollow}
liked={liked}
handleLogin={handleLogin}
currentUserId={state.currentUser.id}
/>
......
......@@ -16,7 +16,7 @@ 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, { useRef, useState, useEffect } from 'react';
import React, { useRef, useState, useEffect, Fragment } from 'react';
import { Grid } from '@material-ui/core';
import Card from '@material-ui/core/Card';
import Button from '@material-ui/core/Button';
......@@ -27,12 +27,27 @@ import Comment from './Comment.js';
import Snackbar from '@material-ui/core/Snackbar';
import MuiAlert from '@material-ui/lab/Alert';
import Comentario from '../img/comentarios.png';
import {getRequest} from '../Components/HelperFunctions/getAxiosConfig'
import { getRequest } from '../Components/HelperFunctions/getAxiosConfig'
import ExitToAppIcon from '@material-ui/icons/ExitToApp';
import SignUpModal from './SignUpModal.js';
import LoginModal from './LoginModal.js';
import SnackBarComponent from './SnackbarComponent';
import CircularProgress from '@material-ui/core/CircularProgress';
export default function CollectionCommentSection(props) {
const [post_snack_open, setPostSnackOpen] = useState(false);
const [delete_snack_open, setDeleteSnackOpen] = useState(false);
const [render_state, setRenderState] = useState(false);
const [sign_up_open, setSignUpOpen] = useState(false);
const [log_in_open, setLoginOpen] = useState(false);
const [is_loading, setIsLoading] = useState(false);
const [snackInfo, setSnackInfo] = useState({
open: false,
text: '',
severity: '',
color: ''
});
const [reviews, setReviews] = useState([]);
const comment_ref = useRef(null);
......@@ -50,30 +65,60 @@ export default function CollectionCommentSection(props) {
window.scrollTo(0, comment_ref.current.offsetTop);
}
function handleOpenSnackSignIn() {
const info = {
open: true,
text: 'Você foi logado com sucesso!',
severity: 'success',
color: '',
}
handleSnackInfo(info)
}
function handleSnackInfo(info) {
setSnackInfo({
...info
})
}
function handleCloseSnack() {
setSnackInfo({
open: false,
text: '',
severity: '',
color: '',
})
}
function handleOpenSignUp() {
setSignUpOpen(true)
}
function Alert(props) {
return <MuiAlert elevation={6} variant="filled" {...props} />;
}
const NoCommentsMessage = () => {
const NoCommentsContainer=styled.div`
const NoCommentsContainer = styled.div`
text-align: center;
margin-left: 9vw;
margin-right: 9vw;
`
const BlueTitle=styled.h2`
const BlueTitle = styled.h2`
color: #673ab7;
`
const Secondary=styled.h3`
const Secondary = styled.h3`
font-weight: 100;
`
const ButtonText=styled.span`
const ButtonText = styled.span`
font-weight: 900;
`
const Image=styled.img`
const Image = styled.img`
`
return (
<NoCommentsContainer>
<Image src={Comentario} style={{width:"100%", maxWidth:234}}/>
<Image src={Comentario} style={{ width: "100%", maxWidth: 234 }} />
<BlueTitle>Compartilhe sua opinião com a rede!</BlueTitle>
<Secondary>Gostou desta coleção? Comente e compartilhe com a rede sua opinião. Interagindo com a rede, você contribui para que mais coleções como esta sejam criadas.</Secondary>
<Button
......@@ -94,6 +139,7 @@ export default function CollectionCommentSection(props) {
{reviews.map(r => {
return (
<Comment
isCollection={false}
rerenderCallback={forceUpdate}
objectID={props.id}
reviewID={r.id}
......@@ -105,62 +151,136 @@ export default function CollectionCommentSection(props) {
description={r.description}
createdAt={r.created_at}
handleSnackbar={handleDeleteSnackbar}
handlePost={handlePostSnackbar}
recurso={false}
/>
);})}
);
})}
</div>
);
}
useEffect(() => {
getRequest(`/collections/${props.id}/reviews`, (data) => {setReviews(data)}, (error) => {console.log(error)})
setIsLoading(true)
getRequest(`/collections/${props.id}/reviews`, (data) => { setReviews(data); setIsLoading(false) }, (error) => { console.log(error); setIsLoading(false) })
}, [render_state]);
return (
<CommentAreaContainer container xs={12} direction="row" justify="center" alignItems="center">
<SnackBarComponent
snackbarOpen={snackInfo.open}
handleClose={handleCloseSnack}
severity={snackInfo.severity}
text={snackInfo.text}
color={snackInfo.color}
/>
<SignUpModal
open={sign_up_open}
handleClose={() => setSignUpOpen(false)}
openLogin={() => setLoginOpen(true)}
/>
<LoginModal
openSnackbar={handleOpenSnackSignIn}
open={log_in_open}
handleClose={() => setLoginOpen(false)}
openSignUp={handleOpenSignUp}
/>
<Grid item xs={12} ref={comment_ref}>
<CommentAreaCard>
<Title>Conte sua experiência com a coleção</Title>
<CommentForm colecao recursoId={props.id}
handleSnackbar={handlePostSnackbar}
rerenderCallback={forceUpdate}
/>
{reviews.length ? CollectionComments() : NoCommentsMessage()}
{
props.currentUserId ?
<Fragment>
<Title>Conte sua experiência com a coleção</Title>
<CommentForm
colecao
recursoId={props.id}
handleSnackbar={handlePostSnackbar}
rerenderCallback={forceUpdate}
/>
</Fragment>
:
<Grid item xs={12}>
<LogInToComment>
<span className="span-purple">Você precisa entrar para comentar</span>
<Button onClick={() => setSignUpOpen(true)} style={{ textTransform: "uppercase", color: "#666", fontWeight: "700" }}>
<ExitToAppIcon />ENTRAR
</Button>
</LogInToComment>
</Grid>
}
{
is_loading ?
<LoadingDiv>
<CircularProgress className="loading" />
</LoadingDiv>
:
reviews.length ? CollectionComments() : NoCommentsMessage()
}
</CommentAreaCard>
</Grid>
<Snackbar
open={post_snack_open}
autoHideDuration={6000}
onClose={handlePostSnackbar}
anchorOrigin={{vertical: 'top', horizontal: 'right'}}
anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
>
<Alert onClose={handlePostSnackbar} severity="info">
<Alert onClose={handlePostSnackbar} severity="info">
Seu comentário foi publicado com sucesso!
</Alert>
</Snackbar>
</Snackbar>
<Snackbar
open={delete_snack_open}
autoHideDuration={6000}
onClose={handleDeleteSnackbar}
anchorOrigin={{vertical: 'top', horizontal: 'right'}}
anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
>
<Alert onClose={handleDeleteSnackbar} severity="info">
<Alert onClose={handleDeleteSnackbar} severity="info">
Comentário deletado com sucesso.
</Alert>
</Snackbar>
</Snackbar>
</CommentAreaContainer>
);
}
const LoadingDiv = styled.div`
margin: 1em;
display: flex;
justify-content: center;
align-items: center;
.loading{
color: #673ab7;
size: 24px;
}
`
const LogInToComment = styled.div`
display : flex;
flex-direction : column;
text-align : center;
padding : 20px;
align-items : center;
.span-purple {
font-size : 24px;
font-weight : 700;
padding-bottom : 5px;
color : #673ab7;
}
img {
object-fit : contain !important;
background-color : transparent !important;
}
`
const CommentAreaContainer=styled(Grid)`
const CommentAreaContainer = styled(Grid)`
margin-left: 10%;
margin-right: 10%;
`
const CommentAreaCard=styled(Card)`
const CommentAreaCard = styled(Card)`
padding: 45px;
`
const Title=styled.h1`
const Title = styled.h1`
font-weight: 100;
color: #666;
`
......@@ -30,35 +30,40 @@ export default function CollectionDescription(props) {
useEffect(() => {
const body = {
"package": {
"object": [{"type": "Collection", "id": props.collection_id}]
}};
"object": [{ "type": "Collection", "id": props.collection_id }]
}
};
axios
.post(apiUrl+'/package', body)
.post(apiUrl + '/package', body)
.catch(err => {
if (err.response && err.response.status === 302) {
setDownloadUrl(apiDomain+'/'+err.response.data.url);
setDownloadUrl(apiDomain + '/' + err.response.data.url);
}
});}, [props.collection_id]);
});
}, [props.collection_id]);
return (
<Grid container direction="column" justify="center" alignItems="center" spacing={5}>
<Grid
item
<Grid
item
justify="center"
alignItems="center"
>
<Title>{props.title}</Title>
</Grid>
<Grid
<Grid
item
direction="row"
justify="center"
direction="row"
justify="center"
alignItems="center"
>
<Grid item>
<CollectionReview
<CollectionReview
stars={props.stars}
liked={props.liked}
likes={props.likes}
scrollToComment={props.scrollToComments}
id={props.collection_id}/>
id={props.collection_id} />
</Grid>
{/* <Grid item container sm={8}
direction="column" justify="center" alignItems="flex-end"
......@@ -85,7 +90,7 @@ export default function CollectionDescription(props) {
);
}
const Title=styled.h1`
const Title = styled.h1`
font-size: 2.5em;
color: rgb(102, 102, 102);
text-align: center
......
......@@ -27,31 +27,30 @@ import { Store } from '../Store.js'
import ReportModal from './ReportModal.js';
import SignUpModal from './SignUpModal.js';
import LoginModal from './LoginModal.js';
import { putRequest, getRequest } from './HelperFunctions/getAxiosConfig.js'
import { putRequest } from './HelperFunctions/getAxiosConfig.js'
import SnackBarComponent from './SnackbarComponent';
export default function CollectionReview(props) {
const [likes, setLikes] = useState(0);
const [liked, setLiked] = useState(false);
const [stars, setStars] = useState(0);
const { state } = useContext(Store);
const [likes, setLikes] = useState();
const [liked, setLiked] = useState();
const [stars, setStars] = useState();
const [reportOpen, setReportOpen] = useState(false);
const [sign_up_open, setSignUpOpen] = useState(false);
const [log_in_open, setLoginOpen] = useState(false);
const { state } = useContext(Store);
function handleSuccessfulGet(data) {
setLikes(Number(data.likes_count));
setLiked(data.liked);
}
useEffect(() => {
const url = `/collections/${props.id}`
getRequest(url, handleSuccessfulGet, (error) => { console.log(error) })
}, [props.id, state.currentUser.id]);
const [snackInfo, setSnackInfo] = useState({
open: false,
text: '',
severity: '',
color: ''
});
const handleClickReport = () => {
setReportOpen(true);
if (state.currentUser.id)
setReportOpen(true);
else
setSignUpOpen(true)
}
function handleSuccess(data) {
......@@ -67,24 +66,62 @@ export default function CollectionReview(props) {
setSignUpOpen(true);
}
const handleSetStars = (value) => {
setStars(value);
props.scrollToComment();
}
const handleCloseModal = () => {
setReportOpen(false);
}
function handleOpenSnackSignIn() {
const info = {
open: true,
text: 'Você foi logado com sucesso!',
severity: 'success',
color: '',
}
handleSnackInfo(info)
}
function handleSnackInfo(info) {
setSnackInfo({
...info
})
}
function handleCloseSnack() {
setSnackInfo({
open: false,
text: '',
severity: '',
color: '',
})
}
function handleOpenSignUp() {
setSignUpOpen(true)
}
useEffect(() => {
setLiked(props.liked)
setLikes(props.likes)
setStars(props.stars)
}, [props])
return (
<Grid container direction="column">
<SnackBarComponent
snackbarOpen={snackInfo.open}
handleClose={handleCloseSnack}
severity={snackInfo.severity}
text={snackInfo.text}
color={snackInfo.color}
/>
<Grid sm={12} container direction="row" alignItems="center">
<Grid item>
<Rating
name="customized-empty"
value={stars}
onChange={(e, value) => handleSetStars(value)}
precision={0.5}
value={Number(stars)}
readOnly
onClick={props.scrollToComment}
style={{ color: "#666" }}
emptyIcon={<StarBorderIcon fontSize="inherit" />}
/>
......@@ -116,8 +153,10 @@ export default function CollectionReview(props) {
openLogin={() => setLoginOpen(true)}
/>
<LoginModal
openSnackbar={handleOpenSnackSignIn}
open={log_in_open}
handleClose={() => setLoginOpen(false)}
openSignUp={handleOpenSignUp}
/>
</Grid>
);
......
......@@ -16,13 +16,13 @@ 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} from 'react'
import {Store} from '../Store.js'
import React, { useState, useContext } from 'react'
import { Store } from '../Store.js'
import styled from 'styled-components'
import Grid from '@material-ui/core/Grid';
import { Button } from '@material-ui/core';
import {Link} from 'react-router-dom'
import {apiDomain} from '../env';
import { Link } from 'react-router-dom'
import { apiDomain } from '../env';
import noAvatar from "../img/default_profile.png";
import Rating from '@material-ui/lab/Rating';
import StarBorderIcon from '@material-ui/icons/StarBorder';
......@@ -31,9 +31,9 @@ import TextField from "@material-ui/core/TextField";
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 { putRequest, deleteRequest } from './HelperFunctions/getAxiosConfig'
export default function Comment (props) {
export default function Comment(props) {
/*
Required props:
......@@ -52,7 +52,7 @@ export default function Comment (props) {
*/
var moment = require('moment')
const {state} = useContext(Store)
const { state } = useContext(Store)
const [displayedComment, setDisplayedComment] = useState(props.description)
const [editando, setEditando] = useState(false)
const [anchorEl, setAnchorEl] = React.useState(null);
......@@ -65,47 +65,57 @@ export default function Comment (props) {
const [modalOpen, toggleModal] = useState(false)
const [comment, setComment] = useState({
error : false,
value : props.description
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})
setComment({ ...comment, error: flag, value: userInput })
}
function handleOnSuccessfulComment (data) {
function handleOnSuccessfulComment(data) {
setDisplayedComment(comment.value)
setEditando(false)
props.handleSnackbar(2)
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" : {
"name":null,
"description":finalComment.value,
"pros":null,
"cons":null,
"review_ratings_attributes" : props.reviewRatings
"review": {
"description": finalComment.value,
"review_ratings_attributes": props.reviewRatings
}
}
putRequest(`/learning_objects/${props.objectID}/reviews/`, payload, handleOnSuccessfulComment, (error) => {console.log(error)})
putRequest(url, payload, handleOnSuccessfulComment, (error) => { console.log(error) })
}
}
function handleSuccessDeleteComment (data) {
function handleSuccessDeleteComment(data) {
props.rerenderCallback()
props.handleSnackbar(3)
props.handleSnackbar()
}
const deleteComment = () => {
let url;
deleteRequest(`/learning_objects/${props.objectID}/reviews/${props.reviewID}`, handleSuccessDeleteComment, (error) => {console.log(error)})
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)
......@@ -113,113 +123,112 @@ export default function Comment (props) {
return (
<React.Fragment>
<ModalExcluir
open={modalOpen} handleClose={() => {toggleModal(false)}}
handleConfirm={deleteComment}
<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>
<div className="star-rating-container">
<Rating
name="read-only"
value={props.rating}
readOnly
size="small"
style={{color:"#666"}}
emptyIcon={<StarBorderIcon fontSize="inherit" style={{color : "#a5a5a5"}} />}
/>
</div>
<Grid container style={{ paddingLeft: "20px" }}>
<Grid item xs={1}>
{
props.name &&
<strong>{props.name}</strong>
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>
<div className="star-rating-container">
<Rating
name="read-only"
value={props.rating}
readOnly
size="small"
style={{ color: "#666" }}
emptyIcon={<StarBorderIcon fontSize="inherit" style={{ color: "#a5a5a5" }} />}
/>
</div>
<div>
{
editando ?
(
<React.Fragment>
<div style={{marginTop : "5%", padding : "2px"}}>
<StyledTextField
colecao={!props.recurso}
id = "input-comentario"
label = {"Editar Comentário"}
margin = "normal"
value = {comment.value}
multiline={true}
rows="5"
onChange = {(e) => {handleChange(e)}}
style={{width:"100%"}}
/>
</div>
<div style={{float : "right"}}>
<StyledButton
style={props.recurso ? {backgroundColor : "#ff7f00"} : {backgroundColor : "#673ab7"}}
onClick={() => {setEditando(false)}}
>
Fechar
</StyledButton>
<StyledButton
style={props.recurso ? {backgroundColor : "#ff7f00"} : {backgroundColor : "#673ab7"}}
onClick={() => updateComment()}
>
Salvar
props.name &&
<strong>{props.name}</strong>
}
<div>
{
editando ?
(
<React.Fragment>
<div style={{ marginTop: "5%", padding: "2px" }}>
<StyledTextField
colecao={!props.recurso}
id="input-comentario"
label={"Editar Comentário"}
margin="normal"
value={comment.value}
multiline={true}
rows="5"
onChange={(e) => { handleChange(e) }}
style={{ width: "100%" }}
/>
</div>
<div style={{ float: "right" }}>
<StyledButton
style={props.recurso ? { backgroundColor: "#ff7f00" } : { backgroundColor: "#673ab7" }}
onClick={() => { setEditando(false) }}
>
Fechar
</StyledButton>
</div>
</React.Fragment>
)
:
(
<React.Fragment>
<p>
{
props.authorID &&
<Link
to={'/usuario-publico/' + props.authorID}
style={{
fontWeight : "bolder",
color : props.recurso ? "#ff7f00" : "#673ab7"
}}
<StyledButton
style={props.recurso ? { backgroundColor: "#ff7f00" } : { backgroundColor: "#673ab7" }}
onClick={() => updateComment()}
>
{props.authorName}
</Link>
}
Salvar
</StyledButton>
</div>
</React.Fragment>
)
:
(
<React.Fragment>
<p>
{
props.authorID &&
<Link
to={'/usuario-publico/' + props.authorID}
style={{
fontWeight: "bolder",
color: props.recurso ? "#ff7f00" : "#673ab7"
}}
>
{props.authorName}
</Link>
}
: {displayedComment}
</p>
{
props.authorID !== state.currentUser.id &&
<span className="date">
{moment(props.createdAt).format("DD/MM/YYYY")}
</span>
}
</React.Fragment>
)
}
</div>
</Comentario>
</Grid>
</p>
{
props.authorID !== state.currentUser.id &&
<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/></Button>
{
props.authorID === state.currentUser.id &&
<Grid item xs={1}>
<StyledDiv>
<Button onClick={handleClick}><EditIcon /></Button>
<Menu
id="simple-menu"
anchorEl={anchorEl}
......@@ -227,13 +236,13 @@ export default function Comment (props) {
open={Boolean(anchorEl)}
onClose={handleClose}
>
<MenuItem onClick={() => {setEditando(true); handleClose()}}>Editar</MenuItem>
<MenuItem onClick={() => {toggleModal(true);handleClose()}}>Excluir</MenuItem>
<MenuItem onClick={() => { setEditando(true); handleClose() }}>Editar</MenuItem>
<MenuItem onClick={() => { toggleModal(true); handleClose() }}>Excluir</MenuItem>
</Menu>
</StyledDiv>
</Grid>
}
</Grid>
</StyledDiv>
</Grid>
}
</Grid>
</React.Fragment>
)
}
......
......@@ -16,7 +16,7 @@ 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, useEffect, useContext } from 'react';
import React, { useState, useEffect } from 'react';
import Button from '@material-ui/core/Button';
import CheckIcon from '@material-ui/icons/Check';
import AddIcon from '@material-ui/icons/Add';
......@@ -24,13 +24,12 @@ import styled from 'styled-components';
import SignUpModal from './SignUpModal.js';
import LoginModal from './LoginModal';
import SnackBarComponent from './SnackbarComponent';
import { getRequest, putRequest } from './HelperFunctions/getAxiosConfig'
import { Store } from '../Store'
import { putRequest } from './HelperFunctions/getAxiosConfig'
export default function FollowCollectionButton(props) {
const { state } = useContext(Store)
const [icon, setIcon] = useState(<AddIcon fontSize="large" />);
const [button_text, setButtonText] = useState("Seguir Coleção");
const [button_text, setButtonText] = useState("Seguir coleção");
const [variant, setVariant] = useState("outlined");
const [sign_up_open, setSignUpOpen] = useState(false);
const [open_login, setOpenLogin] = useState(false);
......@@ -42,51 +41,20 @@ export default function FollowCollectionButton(props) {
});
const [following, setFollowing] = useState(false); //user following collection
function handleSuccessGet(data) {
if (!data.errors)
data.map((e) => {
if (e["followable"]["id"] === Number(props.collection_id)) {
setVariant("contained");
setButtonText("Seguindo");
setIcon(<CheckIcon fontSize="large" />)
setFollowing(true);
}
return undefined
})
else {
const info = {
open: true,
text: 'Falha ao verificar se o usuário segue a coleção!',
severity: 'error',
color: 'red'
}
handleSnackInfo(info)
}
}
useEffect(() => {
if (state.currentUser.id) {
const url = `/users/${props.user_id}/following/Collection`
getRequest(
url,
handleSuccessGet,
(error) => {
const info = {
open: true,
text: 'Falha ao verificar se o usuário segue a coleção!',
severity: 'error',
color: 'red'
}
handleSnackInfo(info)
})
if (props.followed) {
setFollowing(true)
setButtonText("Seguindo")
setVariant("contained")
setIcon(<CheckIcon fontSize="large" />);
}
else {
setIcon(<AddIcon fontSize="large" />)
setButtonText("Seguir Coleção")
setVariant("outlined")
setFollowing(false)
setButtonText("Seguir coleção")
setVariant("outlined")
setIcon(<AddIcon fontSize="large" />);
}
}, [state.currentUser.id]);
}, [props])
//handleMouse{Enter, Leave} only do anything when user follows given collection:
const handleMouseEnter = () => {
......
......@@ -54,7 +54,7 @@ export default function Header(props) {
}
useEffect(() => {
if (sessionStorage.getItem('@portalmec/auth_headers')) {
if (localStorage.getItem('@portalmec/auth_headers')) {
const url = `/auth/validate_token/`
getRequest(url, handleSuccessValidateToken, (error) => { console.log(error) })
}
......
......@@ -2,16 +2,18 @@ import {apiUrl} from '../../env.js'
export function getAxiosConfigFromJSON () {
let config = {
headers : JSON.parse(sessionStorage.getItem('@portalmec/auth_headers'))
headers : JSON.parse(localStorage.getItem('@portalmec/auth_headers'))
}
return config
}
export function updateHeaders (newHeaders) {
sessionStorage.setItem('@portalmec/accessToken', newHeaders['access-token'])
let newToken = getNewAccessToken(newHeaders['access-token'])
let auth_headers = JSON.parse(sessionStorage.getItem('@portalmec/auth_headers'))
localStorage.setItem('@portalmec/accessToken', newToken)
let auth_headers = JSON.parse(localStorage.getItem('@portalmec/auth_headers'))
/*const auth_headers = {
client: newHeaders.get('client'),
"access-token": newHeaders.get('access-token'),
......@@ -20,7 +22,7 @@ export function updateHeaders (newHeaders) {
"token-type": "Bearer"
}
sessionStorage.setItem('@portalmec/auth_headers', JSON.stringify(auth_headers))*/
localStorage.setItem('@portalmec/auth_headers', JSON.stringify(auth_headers))*/
if (auth_headers) {
auth_headers['access-token'] = newHeaders['access-token']
}
......@@ -33,11 +35,11 @@ export function updateHeaders (newHeaders) {
"token-type": "Bearer"
}
}
sessionStorage.setItem('@portalmec/auth_headers', JSON.stringify(auth_headers))
localStorage.setItem('@portalmec/auth_headers', JSON.stringify(auth_headers))
}
function fetchHeaders () {
let auth_headers = JSON.parse(sessionStorage.getItem('@portalmec/auth_headers'))
let auth_headers = JSON.parse(localStorage.getItem('@portalmec/auth_headers'))
var myHeaders = undefined
if (auth_headers) {
......@@ -58,12 +60,12 @@ function fetchHeaders () {
function checkPreviousTokens (new_token) {
let prev_tokens = JSON.parse(sessionStorage.getItem('@portalmec/tokens'))
let prev_tokens = JSON.parse(localStorage.getItem('@portalmec/tokens'))
if (prev_tokens) {
if (!prev_tokens.hasOwnProperty(new_token)) {
prev_tokens[new_token] = 1
sessionStorage.setItem('@portalmec/tokens', JSON.stringify(prev_tokens))
localStorage.setItem('@portalmec/tokens', JSON.stringify(prev_tokens))
return true
}
else {
......@@ -73,25 +75,36 @@ function checkPreviousTokens (new_token) {
else {
let tokens = {}
tokens[new_token] = 1
sessionStorage.setItem('@portalmec/tokens', JSON.stringify(tokens))
localStorage.setItem('@portalmec/tokens', JSON.stringify(tokens))
return true
}
}
function getNewAccessToken (newAccessToken) {
if (!newAccessToken || newAccessToken.trim().length === 0) {
return localStorage.getItem('@portalmec/accessToken')
}
else {
return newAccessToken
}
}
function updateAccessToken (newAccessToken) {
let newToken = getNewAccessToken(newAccessToken)
if (checkPreviousTokens(newAccessToken)) {
if (checkPreviousTokens(newToken)) {
sessionStorage.setItem('@portalmec/accessToken', newAccessToken)
localStorage.setItem('@portalmec/accessToken', newToken)
let auth_headers = JSON.parse(sessionStorage.getItem('@portalmec/auth_headers'))
let auth_headers = JSON.parse(localStorage.getItem('@portalmec/auth_headers'))
if (auth_headers) {
auth_headers['access-token'] = newAccessToken
auth_headers['access-token'] = newToken
}
sessionStorage.setItem('@portalmec/auth_headers', JSON.stringify(auth_headers))
localStorage.setItem('@portalmec/auth_headers', JSON.stringify(auth_headers))
}
}
......@@ -263,7 +276,8 @@ export const validateGoogleLoginToken = (url, config, onSuccess, onError) => {
"token-type": "Bearer"
}
sessionStorage.setItem('@portalmec/auth_headers', JSON.stringify(auth_headers))
localStorage.setItem('@portalmec/auth_headers', JSON.stringify(auth_headers))
localStorage.setItem('@portalmec/accessToken', auth_headers["access-token"])
return response.json().catch(err => {
return {};
......@@ -297,7 +311,8 @@ export async function authentication (url, payload, onSuccess, onError) {
"token-type": "Bearer"
}
sessionStorage.setItem('@portalmec/auth_headers', JSON.stringify(auth_headers))
localStorage.setItem('@portalmec/auth_headers', JSON.stringify(auth_headers))
localStorage.setItem('@portalmec/accessToken', auth_headers["access-token"])
let json = await response.json().catch(err => {
return {};
......@@ -317,7 +332,7 @@ export async function authentication (url, payload, onSuccess, onError) {
// "token-type": "Bearer"
// }
//
// sessionStorage.setItem('@portalmec/auth_headers', JSON.stringify(auth_headers))
// localStorage.setItem('@portalmec/auth_headers', JSON.stringify(auth_headers))
//
// return response.json().catch(err => {
// return {};
......
......@@ -16,34 +16,36 @@ 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 React, { useState, useContext, useEffect } from 'react'
import { Store } from '../../Store.js'
import styled from 'styled-components'
import Grid from '@material-ui/core/Grid';
import { Button } from '@material-ui/core';
import ExitToAppIcon from '@material-ui/icons/ExitToApp';
import Comentarios from '../../img/comentarios.png'
import {apiDomain} from '../../env';
import { apiDomain } from '../../env';
import CommentForm from './CommentForm.js'
import Comment from '../Comment.js'
import {getRequest} from '../HelperFunctions/getAxiosConfig'
import { getRequest } from '../HelperFunctions/getAxiosConfig'
import LoginModal from './../LoginModal.js'
import Snackbar from '@material-ui/core/Snackbar';
import SignUpModal from './../SignUpModal'
import MuiAlert from '@material-ui/lab/Alert';
import CircularProgress from '@material-ui/core/CircularProgress';
function Alert(props) {
return <MuiAlert elevation={6} variant="filled" {...props} />;
}
export default function CommentsArea (props) {
const {state} = useContext(Store)
export default function CommentsArea(props) {
const { state } = useContext(Store)
const [comentarios, setComentarios] = useState([])
const [gambiarra, setState] = useState(0)
const forceUpdate = () => {setState(gambiarra + 1)}
const forceUpdate = () => { setState(gambiarra + 1) }
const [loginOpen, setLogin] = useState(false)
const [successfulLoginOpen, handleSuccessfulLogin] = useState(false)
const [signUpOpen, setSignUp] = useState(false)
const [isLoading, setIsLoading] = useState(false)
const handleSignUp = () => {
setSignUp(!signUpOpen)
......@@ -57,18 +59,19 @@ export default function CommentsArea (props) {
if (reason === 'clickaway') {
return;
}
handleSuccessfulLogin(false);
handleSuccessfulLogin(false);
}
function handleSuccess (data) {
function handleSuccess(data) {
setIsLoading(false)
setComentarios(data.sort((a, b) => a.updated_at > b.updated_at ? -1 : 1))
}
useEffect( () => {
useEffect(() => {
setIsLoading(true)
const url = `/learning_objects/${props.recursoId}/reviews`
getRequest(url, handleSuccess, (error) => {console.log(error)})
getRequest(url, handleSuccess, (error) => { console.log(error); setIsLoading(false) })
}, [gambiarra])
return (
......@@ -83,17 +86,17 @@ export default function CommentsArea (props) {
openSnackbar={() => { handleSuccessfulLogin(true) }}
/>
<SignUpModal open={signUpOpen} handleClose={handleSignUp} openLogin={handleLogin} />
{/*----------------------------------------------------------------------------*/}
<Grid container spacing={2} style={{padding : "10px"}}>
{/*----------------------------------------------------------------------------*/}
<Grid container spacing={2} style={{ padding: "10px" }}>
{
(state.currentUser.id !== '') ?
(
(
<Grid item xs={12} >
<GrayContainer>
<h3>Conte sua experiência com o Recurso</h3>
<Grid container style={{paddingTop : "20px"}}>
<Grid item xs={2} style={{paddingLeft : "15px", paddingRight : "15px"}}>
<img src={apiDomain + state.currentUser.avatar} className="minha-imagem" alt="user avatar"/>
<Grid container style={{ paddingTop: "20px" }}>
<Grid item xs={2} style={{ paddingLeft: "15px", paddingRight: "15px" }}>
<img src={apiDomain + state.currentUser.avatar} className="minha-imagem" alt="user avatar" />
</Grid>
<Grid item xs={10}>
<CommentForm
......@@ -101,70 +104,86 @@ export default function CommentsArea (props) {
handleSnackbar={props.handleSnackbar}
rerenderCallback={forceUpdate}
recurso={props.recurso}
/>
/>
</Grid>
</Grid>
</GrayContainer>
</Grid>
)
:
(
)
:
(
<Grid item xs={12}>
<LogInToComment>
<span className="span-laranja">Você precisa entrar para comentar</span>
<Button onClick={() => handleLogin(true)} style={{textTransform : "uppercase", color : "#666", fontWeight : "700"}}>
<ExitToAppIcon/>ENTRAR
<Button onClick={() => handleLogin(true)} style={{ textTransform: "uppercase", color: "#666", fontWeight: "700" }}>
<ExitToAppIcon />ENTRAR
</Button>
</LogInToComment>
</Grid>
)
)
}
{
comentarios.length !== 0 ?
(
isLoading ?
<LoadingDiv>
<CircularProgress className="loading" />
</LoadingDiv>
:
comentarios.length !== 0 ?
(
<ComentariosBox>
<h3>{comentarios.length} {comentarios.length !== 1 ? 'Relatos' : 'Relato'} sobre o uso do Recurso</h3>
{
comentarios.map( comentario =>
<div className="comentario-template" key={comentario.id}>
<Comment
authorID={comentario.user ? comentario.user.id : null}
authorAvatar={comentario.user ? comentario.user.avatar : null}
authorName={comentario.user ? comentario.user.name : null}
name={comentario.name}
rating={comentario.rating_average}
reviewRatings = {comentario.review_ratings}
description={comentario.description}
createdAt={comentario.created_at}
recurso={true}
reviewID={comentario.id}
objectID={props.recursoId}
rerenderCallback={forceUpdate}
handleSnackbar={props.handleSnackbar}
/>
</div>
comentarios.map(comentario =>
<div className="comentario-template" key={comentario.id}>
<Comment
isCollection={false}
authorID={comentario.user ? comentario.user.id : null}
authorAvatar={comentario.user ? comentario.user.avatar : null}
authorName={comentario.user ? comentario.user.name : null}
name={comentario.name}
rating={comentario.rating_average}
reviewRatings={comentario.review_ratings}
description={comentario.description}
createdAt={comentario.created_at}
recurso={true}
reviewID={comentario.id}
objectID={props.recursoId}
rerenderCallback={forceUpdate}
handleSnackbar={props.handleSnackbar}
/>
</div>
)
}
</ComentariosBox>
)
:
(
<Grid item xs={12}>
<LogInToComment>
<img alt="" src={Comentarios} />
<span className="span-laranja">Compartilhe sua experiência com a Rede!</span>
<AoRelatar>
Ao relatar sua experiência de uso do Recurso você estará auxiliando professores de todo país.
)
:
(
<Grid item xs={12}>
<LogInToComment>
<img alt="" src={Comentarios} />
<span className="span-laranja">Compartilhe sua experiência com a Rede!</span>
<AoRelatar>
Ao relatar sua experiência de uso do Recurso você estará auxiliando professores de todo país.
</AoRelatar>
</LogInToComment>
</Grid>
)
</LogInToComment>
</Grid>
)
}
</Grid>
</React.Fragment>
)
}
const LoadingDiv = styled.div`
margin: 1em;
display: flex;
justify-content: center;
align-items: center;
.loading{
color: #ff7f00;
size: 24px;
}
`
const ComentariosBox = styled.div`
display : flex;
......@@ -221,18 +240,15 @@ const GrayContainer = styled.div`
display : flex;
flex-direction : column;
justify-content : space-between;
<<<<<<< HEAD
font-size : 14px;
padding-bottom : 20px;
@media screen and (min-width : 990px) {
padding-right : 15px;
padding-left : 15px;
}
=======
padding-right : 15px;
padding-left : 15px;
padding-bottom : 20px;
>>>>>>> fead909286087ce07b01b25f6d8f46f74dc494c8
h3 {
font-family : 'Roboto Light','Roboto Regular',Roboto;
......
......@@ -19,58 +19,61 @@ along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>
import React from 'react'
import styled from 'styled-components'
function GetEmbeddedLink (link) {
function GetEmbeddedLink(link) {
var embed = undefined
var link_id = undefined
if (link.indexOf("youtube") !== -1) { //plain youtebe.com/ link
if(link.indexOf("embed/") !== -1) { //if it's already an embedded link, return it
if (link.indexOf("embed/") !== -1) { //if it's already an embedded link, return it
return link
}
link = link.split("&")[0] //else remove features and other queries
link_id = link.split("v=")[1] //get video id
embed = "https://www.youtube.com/embed/" + link_id; //create embedded link
}
else if (link.indexOf("youtu.be") !== -1) { //if it's a youtu.be link
link = link.split("&")[0].split("?")[0] //remove queries and features if existent
link_id = link.split(".be/")[1] //get video id
embed = "https://www.youtube.com/embed/" + link_id; //create embedded link
}
else if (link.indexOf("vimeo") !== -1) { //if the 13th character = o (vimeo videos)
link_id = link.split("?")[0].split("/")
console.log(link_id) //key # = from 19th character on
embed = "https://player.vimeo.com/video/" + link_id.pop(); //Add vimeo link before key #
}
return embed
}
else if (link.indexOf("youtu.be") !== -1) { //if it's a youtu.be link
link = link.split("&")[0].split("?")[0] //remove queries and features if existent
link_id = link.split(".be/")[1] //get video id
embed = "https://www.youtube.com/embed/" + link_id; //create embedded link
}
else if (link.indexOf("vimeo") !== -1) { //if the 13th character = o (vimeo videos)
link_id = link.split("?")[0].split("/")
console.log(link_id) //key # = from 19th character on
embed = "https://player.vimeo.com/video/" + link_id.pop(); //Add vimeo link before key #
}
return embed
}
export default function VideoPlayer (props) {
export default function VideoPlayer(props) {
return (
<>
{
props.urlVerified ?
(
<VideoContainer>
<iframe
title="Video Player"
src={GetEmbeddedLink(props.link)}
frameBorder="0" allowFullScreen className="video"
/>
</VideoContainer>
)
:
(
<VideoContainer>
<video controls className="video">
<source src={props.videoUrl} type="video/webm"/>
<source src={props.videoUrl} type="video/mp4"/>
<p>Seu navegador não permite a exibição deste vídeo. É necessário baixar o vídeo para poder visualizá-lo.</p>
</video>
</VideoContainer>
)
}
{
props.urlVerified ?
(
<VideoContainer>
<iframe
title="Video Player"
src={GetEmbeddedLink(props.link)}
frameBorder="0" allowFullScreen className="video"
/>
</VideoContainer>
)
:
(
props.videoType === "video/mp4" ?
<VideoContainer>
<video controls className="video">
<source src={props.videoUrl} type="video/webm" />
<source src={props.videoUrl} type="video/mp4" />
</video>
</VideoContainer>
:
<ErrorParagraph>
Seu navegador não permite a exibição deste vídeo. É necessário baixar o vídeo para poder visualizá-lo.
</ErrorParagraph>
)
}
</>
)
}
......@@ -89,3 +92,7 @@ const VideoContainer = styled.div`
left : 0;
}
`
const ErrorParagraph = styled.p`
text-align: center;
`
......@@ -29,16 +29,15 @@ export function ButtonsAreaRecurso(props) {
</p>
{
props.end ?
null :
<React.Fragment>
<ButtonMostrarMaisRecurso onClick={() => props.showMore(4)}>
<span style={{ color: "#fff", fontSize: "14px", fontWeight: "500" }}>MOSTRAR MAIS 4</span>
</ButtonMostrarMaisRecurso>
<ButtonMostrarTodos onClick={() => { props.showMore(20) }}>
<span style={{ color: "#666", fontSize: "14px", fontWeight: "500" }}>MOSTRAR MAIS 20</span>
</ButtonMostrarTodos>
</React.Fragment>
!props.end &&
<React.Fragment>
<ButtonMostrarMaisRecurso onClick={() => props.showMore(4)}>
<span style={{ color: "#fff", fontSize: "14px", fontWeight: "500" }}>MOSTRAR MAIS 4</span>
</ButtonMostrarMaisRecurso>
<ButtonMostrarTodos onClick={() => { props.showMore(20) }}>
<span style={{ color: "#666", fontSize: "14px", fontWeight: "500" }}>MOSTRAR MAIS 20</span>
</ButtonMostrarTodos>
</React.Fragment>
}
</Carregados>
......@@ -52,18 +51,16 @@ export function ButtonsAreaColecao(props) {
{props.sliceLength} coleções carregadas de {props.total}
</p>
{
props.end ?
null
:
<React.Fragment>
<ButtonMostrarMaisColecao onClick={() => { props.showMore(4) }}>
<span style={{ color: "#fff", fontSize: "14px", fontWeight: "500" }}>MOSTRAR MAIS 4</span>
</ButtonMostrarMaisColecao>
<ButtonMostrarTodos onClick={() => { props.showMore(20) }}>
<span style={{ color: "#666", fontSize: "14px", fontWeight: "500" }}>MOSTRAR MAIS 20</span>
</ButtonMostrarTodos>
</React.Fragment>
!props.end &&
<React.Fragment>
<ButtonMostrarMaisColecao onClick={() => { props.showMore(4) }}>
<span style={{ color: "#fff", fontSize: "14px", fontWeight: "500" }}>MOSTRAR MAIS 4</span>
</ButtonMostrarMaisColecao>
<ButtonMostrarTodos onClick={() => { props.showMore(20) }}>
<span style={{ color: "#666", fontSize: "14px", fontWeight: "500" }}>MOSTRAR MAIS 20</span>
</ButtonMostrarTodos>
</React.Fragment>
}
</Carregados>
)
......@@ -77,18 +74,16 @@ export function ButtonsAreaRede(props) {
</p>
{
props.end ?
null
:
<React.Fragment>
<ButtonMostrarMaisRede onClick={() => { props.showMore(4) }}>
<span style={{ color: "#fff", fontSize: "14px", fontWeight: "500" }}>MOSTRAR MAIS 4</span>
</ButtonMostrarMaisRede>
<ButtonMostrarTodos onClick={() => { props.showMore(20) }}>
<span style={{ color: "#666", fontSize: "14px", fontWeight: "500" }}>MOSTRAR MAIS 20</span>
</ButtonMostrarTodos>
</React.Fragment>
!props.end &&
<React.Fragment>
<ButtonMostrarMaisRede onClick={() => { props.showMore(4) }}>
<span style={{ color: "#fff", fontSize: "14px", fontWeight: "500" }}>MOSTRAR MAIS 4</span>
</ButtonMostrarMaisRede>
<ButtonMostrarTodos onClick={() => { props.showMore(20) }}>
<span style={{ color: "#666", fontSize: "14px", fontWeight: "500" }}>MOSTRAR MAIS 20</span>
</ButtonMostrarTodos>
</React.Fragment>
}
</Carregados>
......
......@@ -18,13 +18,21 @@ along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>
import React from 'react'
import styled from 'styled-components'
import defaultNoContent from '../../../img/img-16.png'
export default function NoContent (props) {
export default function NoContent({text, image}) {
return (
<DivTextoNoPublications>
<InnerDiv>
<NoPubSpan>{props.text}</NoPubSpan>
<ImgDiv>
<img alt="" src={image || defaultNoContent } style={{ width: "130px", verticalAlign: "middle", border: "0" }} />
</ImgDiv>
<TextDiv>
<NoPubSpan>{text}</NoPubSpan>
</TextDiv>
</InnerDiv>
</DivTextoNoPublications>
)
......@@ -44,11 +52,18 @@ const InnerDiv = styled.div`
transform : translateY(-50%);
`
const ImgDiv = styled.div`
margin-bottom: 25px;
`
const TextDiv = styled.div`
`
export const DivTextoNoPublications = styled.div`
height : 360px;
text-align : center;
padding-left : 15px;
padding-right : 15px;
text-align : center;
`
// {/*const DivConteudoNaoPublicado = styled.div`
......
......@@ -24,6 +24,7 @@ import Title from './PanelTitle.js'
import { WhiteContainer, StyledGrid } from '../StyledComponents.js'
import { ButtonsAreaColecao } from './ButtonsArea'
import LoadingSpinner from '../../LoadingSpinner.js'
import noCollFound from '../../../img/Pagina_vazia_colecao.png'
export default function PanelTemplateColecao(props) {
const RenderFollowedColCard = (card, followerBoolean) => {
......@@ -86,7 +87,10 @@ export default function PanelTemplateColecao(props) {
:
props.length === 0 ?
(
<NoContent text={props.noContentText} />
<NoContent
text={props.noContentText}
image={noCollFound}
/>
)
:
(
......@@ -109,7 +113,7 @@ export default function PanelTemplateColecao(props) {
length={props.length}
showMore={props.showMore}
total={props.end}
end={String(props.sliceArr.length) === props.end}
end={String(props.sliceArr.length) === props.end || Number(props.sliceArr.length) === props.end}
/>
}
</React.Fragment>
......
......@@ -83,7 +83,7 @@ export default function Template(props) {
sliceLength={props.sliceArr.length}
length={props.length}
showMore={props.showMore}
end={String(props.sliceArr.length) === props.end}
end={String(props.sliceArr.length) === props.end || Number(props.sliceArr.length) === props.end}
total={props.end}
/>
}
......
......@@ -24,6 +24,7 @@ import Title from './PanelTitle.js'
import { WhiteContainer, StyledGrid } from '../StyledComponents.js'
import { ButtonsAreaRecurso } from './ButtonsArea'
import LoadingSpinner from '../../LoadingSpinner.js'
import noLearnObjFound from '../../../img/Pagina_vazia_Sem_publicar.png'
export default function Template(props) {
......@@ -44,7 +45,10 @@ export default function Template(props) {
:
props.length === 0 ?
(
<NoContent text={props.noContentText} />
<NoContent
text={props.noContentText}
image={noLearnObjFound}
/>
)
:
(
......@@ -82,7 +86,7 @@ export default function Template(props) {
length={props.length}
showMore={props.showMore}
total={props.end}
end={String(props.slice.length) === props.end}
end={Number(props.slice.length) === props.end || String(props.slice.length) === props.end}
/>
}
......
......@@ -94,7 +94,7 @@ export default function PanelTemplateRede(props) {
length={props.length}
showMore={props.showMore}
total={props.end}
end={String(props.sliceArr.length) === props.end}
end={String(props.sliceArr.length) === props.end || Number(props.sliceArr.length) === props.end}
/>
}
</React.Fragment>
......
......@@ -21,7 +21,7 @@ import { fetchAllRequest, getRequest } from '../../HelperFunctions/getAxiosConfi
import PanelTemplateColecao from '../PanelComponents/TemplateColecao.js'
import LoadingSpinner from '../../LoadingSpinner.js'
export default function TabColecoes(props) {
export default function TabColecoes({id, username}) {
const [loading, handleLoading] = useState(true)
const [errorInUserColl, setErrorInUserColl] = useState(false)
......@@ -52,7 +52,7 @@ export default function TabColecoes(props) {
const getInfo = () => {
const urls = [
`/users/${props.id}/collections?offset=0&limit=4`,
`/users/${id}/collections?offset=0&limit=4`,
]
fetchAllRequest(urls, handleSuccess, handleError)
}
......@@ -66,7 +66,7 @@ export default function TabColecoes(props) {
const limit = limite;
setLoadingMoreUserColl(true);
setCurrLimitUserColl(currLimitUserColl + limit)
const url = `/users/${props.id}/collections?offset=${currLimitUserColl}&limit=${limit}`;
const url = `/users/${id}/collections?offset=${currLimitUserColl}&limit=${limit}`;
getRequest(url,
(data) => {
if (data.errors) {
......@@ -98,14 +98,14 @@ export default function TabColecoes(props) {
{
loading ?
(
<LoadingSpinner text={'CARREGANDO COLEÇÕES'} />
<LoadingSpinner text={`Carregando coleções de ${username}`} />
)
:
(
<PanelTemplateColecao
title={"Coleções Públicas"}
length={userCollections.length}
noContentText={props.username + " não possui nenhuma coleção."}
noContentText={username + " não possui nenhuma coleção."}
sliceArr={userCollections}
showMore={showMoreUserCollections}
loadingMore={loadingMoreUserColl}
......
......@@ -19,11 +19,8 @@ along with Plataforma Integrada MEC. If not, see <http://www.gnu.org/licenses/>
import React from 'react'
import styled from 'styled-components'
import UserDescription from './UserDescription.js'
import NoContentImage from '../../../img/img-16.png'
import Grid from '@material-ui/core/Grid';
import LastLearnObjs from './LastLearnObj.js'
import LastCols from './LastCollections.js'
import {ContainerStyled} from '../StyledComponents.js'
import Template from '../PanelComponents/TemplateRecurso'
import PanelTemplateColecao from '../PanelComponents/TemplateColecao.js'
const NoContentContainer = styled.div`
height : 250px;
......@@ -46,11 +43,11 @@ const NoContentContainer = styled.div`
}
`
/*Displays given image and text saying user hasn't posted anything yet*/
export function NoContent (props) {
export function NoContent(props) {
return (
<NoContentContainer>
<div style={{paddingTop : "1em"}}>
<img alt="" src={props.image} style={{width : "130px", verticalAlign : "middle", border : "0"}}/>
<div style={{ paddingTop: "1em" }}>
<img alt="" src={props.image} style={{ width: "130px", verticalAlign: "middle", border: "0" }} />
<h3>
{props.text1}
</h3>
......@@ -63,55 +60,36 @@ export function NoContent (props) {
)
}
export default function TabInicio (props) {
export default function TabInicio({ id, user, learningObjs, collections }) {
return (
<React.Fragment>
{/*display user description*/}
{props.user.description &&
<UserDescription text={props.user.description}/>
}
{
props.user.learning_objects_count === 0 && props.user.collections_count === 0 ?
(
[
<ContainerStyled>
<Grid container>
<Grid item xs={12}>
<NoContent
image={NoContentImage}
text1={props.user.name + " ainda não disponibilizou nenhum recurso ou coleção."}
text2={"Quando disponibilizar, eles aparecerão aqui."}
/>
</Grid>
</Grid>
</ContainerStyled>
]
)
:
(
[
<React.Fragment>
<ContainerStyled style={{flexDirection : "column"}}>
<LastLearnObjs
count={props.user.learning_objects_count}
username={props.user.name}
learningObjs={props.learningObjs}
/>
</ContainerStyled>
<ContainerStyled style={{flexDirection : "column", paddingTop : "1em"}}>
<LastCols
count={props.user.collections_count}
username={props.user.name}
collections={props.collections}
/>
</ContainerStyled>
</React.Fragment>
]
)
user.description &&
<UserDescription text={user.description} />
}
{/*display last published learning objects and last alterations in user collections*/}
<Template
length={learningObjs.length}
titleText={learningObjs.length === 1 ? `Último Recurso de ${user.name}` : `Últimos recursos de ${user.name}`}
noContentText={`${user.name} não publicou nenhum recursos ainda`}
slice={learningObjs}
showMore={() => { }} // there is no function here, because we don't want to display more resources in this tab
loadingMore={false}
end={learningObjs.length}
error={false}
/>
<PanelTemplateColecao
title={`Últimas coleçoes de ${user.name}`}
length={collections.length}
noContentText={`${user.name} não publicou nenhuma coleção ainda`}
sliceArr={collections}
showMore={() => { }} // there is no function here, because we don't want to display more collections in this tab
loadingMore={false}
end={collections.length}
followed={false}
error={false}
/>
</React.Fragment>
......