diff --git a/src/Pages/CollectionPage.js b/src/Pages/CollectionPage.js index 3ccb5ab1929d32cc3be204d59fa939664b85596f..0777872e95dc28388eb8f44fda972f7f9d21f95a 100644 --- a/src/Pages/CollectionPage.js +++ b/src/Pages/CollectionPage.js @@ -28,11 +28,13 @@ import DowloadButton from '../Components/CollectionDowloadButton.js'; import Breadcrumbs from "@material-ui/core/Breadcrumbs"; import { Link } from 'react-router-dom'; import FollowCollectionButton from '../Components/FollowCollectionButton'; -import { Store } from '../Store.js' -import { getRequest } from '../Components/HelperFunctions/getAxiosConfig.js' +import { Store } from '../Store.js'; +import Button from '@material-ui/core/Button'; +import { getRequest } from '../Components/HelperFunctions/getAxiosConfig.js'; export default function CollectionPage(props) { const { state } = useContext(Store); + const [error, setError] = useState(false) const [collection, setCollection] = useState({ name: '', @@ -44,81 +46,103 @@ export default function CollectionPage(props) { useEffect(() => { const url = `/collections/${collection_id}` - getRequest(url, (data) => { setCollection(Object.assign({}, data)) }, (error) => { console.log(error) }) + getRequest(url, (data) => { setCollection(Object.assign({}, data)) }, (error) => { setError(true) }) }, []); const handleScrollToComments = () => { comment_ref.current.scrollIntoView({ behavior: 'smooth' }) } - return ( - <> - <BreadCrumbsDiv> - <StyledBreadCrumbs> - <Link to="/">Página Inicial</Link> - <span>Coleções</span> - </StyledBreadCrumbs> - </BreadCrumbsDiv> - <Grid container direction="row" justify="center" alignItems="center"> - <Grid item md={3}> - <CollectionAuthor - author_id={collection.owner ? collection.owner.id : 0} - name={collection.owner ? collection.owner.name : ""} - imgsrc={collection.owner ? apiDomain + collection.owner.avatar : ''} /> - </Grid> - - <Grid item md={5}> - <CollectionDescription - scrollToComments={handleScrollToComments} - title={collection.name ? collection.name : ""} - collection_id={collection.id ? collection.id : 0} /> + if (error) + return <CollectionNotFound> + <Grid container direction='column' justify='center' alignItems='center' spacing={1}> + <Grid item> + <p className="not-found"> + A coleção não foi encontrado em nossa base de dados. + </p> </Grid> - - <Grid item md={3}> - <DowloadButton - id={collection.id ? collection.id : 0} - /> - <div style={{ height: 12 }}></div> - <FollowCollectionButton - user_id={state.currentUser.id} - collection_id={collection_id} /> + <Grid item> + <Link className="link" to="/busca?query=*&search_class=Collection"> + <Button + variant='contained' + className="back-button" + > + Voltar para a busca de coleções. + </Button> + </Link> </Grid> </Grid> - - <VerticalRuler width={1} height={100} color="rgb(238, 238, 238)" /> - - <Grid container justify="center" style={{ backgroundColor: '#f4f4f4' }}> - {/* <Grid item xs={1}/> */} - <Grid item xs={10}> - <ResourceList resources={ - collection.collection_items ? - collection.collection_items.map(i => { - return { - type: i.collectionable.object_type, - author: i.collectionable.author, - title: i.collectionable.name, - rating: i.collectionable.review_average, - likeCount: i.collectionable.likes_count, - liked: i.collectionable.liked, - avatar: i.collectionable.publisher.avatar, - thumbnail: i.collectionable.thumbnail, - tags: i.collectionable.tags.map(t => t), - id: i.collectionable.id, - downloadableLink: i.collectionable.default_attachment_location, - publisher: i.collectionable.publisher.name, - published: i.collectionable.state - } - }) - : [] - } /> - + </CollectionNotFound> + else + return ( + <> + <BreadCrumbsDiv> + <StyledBreadCrumbs> + <Link to="/">Página Inicial</Link> + <span>Coleções</span> + </StyledBreadCrumbs> + </BreadCrumbsDiv> + <Grid container direction="row" justify="center" alignItems="center"> + <Grid item md={3}> + <CollectionAuthor + author_id={collection.owner ? collection.owner.id : 0} + name={collection.owner ? collection.owner.name : ""} + imgsrc={collection.owner ? apiDomain + collection.owner.avatar : ''} /> + </Grid> + + + <Grid item md={5}> + <CollectionDescription + scrollToComments={handleScrollToComments} + title={collection.name ? collection.name : ""} + collection_id={collection.id ? collection.id : 0} /> + </Grid> + + <Grid item md={3}> + <DowloadButton + id={collection.id ? collection.id : 0} + /> + <div style={{ height: 12 }}></div> + <FollowCollectionButton + user_id={state.currentUser.id} + collection_id={collection_id} /> + </Grid> </Grid> - <Grid container item xs={12} style={{ marginTop: 40, paddingBottom: 40 }} ref={comment_ref}> - <CollectionCommentSection id={collection_id} /> + + <VerticalRuler width={1} height={100} color="rgb(238, 238, 238)" /> + + <Grid container justify="center" style={{ backgroundColor: '#f4f4f4' }}> + {/* <Grid item xs={1}/> */} + <Grid item xs={10}> + <ResourceList resources={ + collection.collection_items ? + collection.collection_items.map(i => { + return { + type: i.collectionable.object_type, + author: i.collectionable.author, + title: i.collectionable.name, + rating: i.collectionable.review_average, + likeCount: i.collectionable.likes_count, + liked: i.collectionable.liked, + avatar: i.collectionable.publisher.avatar, + thumbnail: i.collectionable.thumbnail, + tags: i.collectionable.tags.map(t => t), + id: i.collectionable.id, + downloadableLink: i.collectionable.default_attachment_location, + publisher: i.collectionable.publisher.name, + published: i.collectionable.state + } + }) + : [] + } /> + + </Grid> + <Grid container item xs={12} style={{ marginTop: 40, paddingBottom: 40 }} ref={comment_ref}> + <CollectionCommentSection id={collection_id} /> + </Grid> </Grid> - </Grid> - </> - ); + </> + ); } const StyledBreadCrumbs = styled(Breadcrumbs)` @@ -133,6 +157,27 @@ const StyledBreadCrumbs = styled(Breadcrumbs)` } `; +const CollectionNotFound = styled.div` + margin: 1em; + + .not-found{ + font-family: 'Roboto', sans-serif; + font-weight: 500; + text-align: left; + padding: 0; + margin: 0; + } + + .back-button{ + background-color: #673ab7; + color: whitesmoke; + } + + .link{ + text-decoration: none; + } +` + const BreadCrumbsDiv = styled.div` padding: 10px; display: flex; diff --git a/src/Pages/PublicUserPage.js b/src/Pages/PublicUserPage.js index fa2818c2d994f455d83a25a2337f9db8cfeea654..9b561ab6c4fd473bbcd734cb2cf80f8f0a83756b 100644 --- a/src/Pages/PublicUserPage.js +++ b/src/Pages/PublicUserPage.js @@ -38,6 +38,8 @@ import { fetchAllRequest } from '../Components/HelperFunctions/getAxiosConfig' import Typography from '@material-ui/core/Typography'; import CircularProgress from '@material-ui/core/CircularProgress'; import LoadingSpinner from '../Components/LoadingSpinner'; +import Button from '@material-ui/core/Button' +import { Link } from 'react-router-dom' function RenderFollowContainer(props) { const { state } = useContext(Store) @@ -115,10 +117,11 @@ export default function PublicUserPage(props) { /*---------------------------------------------------------*/ const [following, setFollowing] = useState(0); const fillFollowing = (data) => { - if (data.errors) - setFollowing('Você precisa logar para ver o que usuário está '); - else - setFollowing(data.length); + if (data) + if (data.errors) + setFollowing('Você precisa logar para ver o que usuário está '); + else + setFollowing(data.length); } /*content control variables--------------------------------*/ @@ -146,7 +149,7 @@ export default function PublicUserPage(props) { handleCollections(responseArr[2]) - fillFollowing(responseArr[3]); + fillFollowing(responseArr[3]) setLoading(false); } @@ -156,14 +159,34 @@ export default function PublicUserPage(props) { setId(id) const urls = [`/users/${id}`, `/users/${id}/learning_objects`, `/users/${id}/collections`, `/users/${id}/following/User`] setLoading(true); - fetchAllRequest(urls, handleSuccess, (error) => { console.log(error); setLoading(false) }) + fetchAllRequest(urls, handleSuccess, (error) => { console.log(error) }) }, [state.currentUser.id, props.match.params.userId]) /*---------------------------------------------------------*/ - return loading ? - <LoadingSpinner text="Carregando dados do usuário..."/> - : - <React.Fragment> + if (loading) + return <LoadingSpinner text="Carregando dados do usuário..." /> + else if (!userData && !following && !learningObjArr && !collectionsArr) + return <UserNotFoundDiv> + <Grid container direction='column' justify='center' alignItems='center' spacing={1}> + <Grid item> + <p className="not-found"> + O usuário não foi encontrado em nossa base de dados. + </p> + </Grid> + <Grid item> + <Link className="link" to="/busca?query=*&search_class=User"> + <Button + variant='contained' + className="back-button" + > + Voltar para a busca de usuários. + </Button> + </Link> + </Grid> + </Grid> + </UserNotFoundDiv> + else + return <React.Fragment> <link href="https://fonts.googleapis.com/css?family=Roboto:100,400,500&display=swap" rel="stylesheet" /> <BackgroundDiv> <CustomizedBreadcrumbs @@ -288,6 +311,26 @@ const ProfileAvatarDiv = styled.div` } ` +const UserNotFoundDiv = styled.div` + margin: 1em; + + .not-found{ + font-family: 'Roboto', sans-serif; + font-weight: 500; + text-align: left; + padding: 0; + margin: 0; + } + + .back-button{ + background-color: #00bcd4; + color: whitesmoke; + } + + .link{ + text-decoration: none; + } +` const FollowContainer = styled.div` padding : 4px 10px; diff --git a/src/Pages/ResourcePage.js b/src/Pages/ResourcePage.js index 34eea68e8ceca548e6c82f726ed536c9a71da3e6..de617c87b18f62af0c7455b16896ace3a2211ec9 100644 --- a/src/Pages/ResourcePage.js +++ b/src/Pages/ResourcePage.js @@ -36,6 +36,8 @@ import ButtonAvaliarRecurso from "../Components/ButtonAvaliarRecurso"; import ModalAvaliarRecurso from "../Components/ModalAvaliarRecurso"; import ModalConfirmarCuradoria from "../Components/ModalConfirmarCuradoria"; import { getRequest } from "../Components/HelperFunctions/getAxiosConfig"; +import Button from '@material-ui/core/Button'; +import { Link } from 'react-router-dom'; function urlVerify(url) { return url @@ -47,6 +49,7 @@ export default function LearningObjectPage(props) { const { state } = useContext(Store); const id = props.match.params.recursoId; const [carregando, toggle] = useState(true); + const [erro, setErro] = useState(false); const [recurso, setRecurso] = useState({}); function handleSuccessfulGet(data) { @@ -60,6 +63,7 @@ export default function LearningObjectPage(props) { url, handleSuccessfulGet, (error) => { + setErro(true) toggle(false); handleSnackbar(7) } @@ -137,179 +141,200 @@ export default function LearningObjectPage(props) { ); }; - return ( - <React.Fragment> - <Snackbar - open={snackbarOpen} - autoHideDuration={6000} - onClose={toggleSnackbar} - anchorOrigin={{ vertical: "top", horizontal: "right" }} - > - <Alert severity="info" - style={{ backgroundColor: "#00acc1" }}> - {snackbarText[snackbarIndex]} - </Alert> - </Snackbar> - - <ModalAvaliarRecurso - open={modalCuradoriaOpen} - handleClose={() => { - handleModalCuradoria(false); - }} - title={recurso.name} - confirm={handleConfirm} - setCriteria={setReportCriteria} - /> - <ModalConfirmarCuradoria - aceito={submissionAccepted} - reportCriteria={reportCriteria} - justificativa={justificativa} - open={modalConfirmarCuradoriaOpen} - handleClose={() => { - handleModalConfirmarCuradoria(false); - }} - cancel={() => { - handleModalCuradoria(true); - }} - recursoId={recurso.submission_id} - finalizeCuratorshipFlow={finalizeCuratorshipFlow} - handleErrorAprove={() => { - handleSnackbar(6) - }} - /> - <Background> - {carregando ? ( - <LoadingSpinner text={"Carregando Recurso"} /> - ) : ( - <> - <Grid container spacing={2}> - {recurso.object_type === "Vídeo" && !recurso.link ? ( + if (erro) + return <LearnObjectNotFound> + <Grid container direction='column' justify='center' alignItems='center' spacing={1}> + <Grid item> + <p className="not-found"> + O recurso não foi encontrado em nossa base de dados. + </p> + </Grid> + <Grid item> + <Link className="link" to="/busca?query=*&search_class=LearningObject"> + <Button + variant='contained' + className="back-button" + > + Voltar para a busca de recursos. + </Button> + </Link> + </Grid> + </Grid> + </LearnObjectNotFound> + else + return ( + <React.Fragment> + <Snackbar + open={snackbarOpen} + autoHideDuration={6000} + onClose={toggleSnackbar} + anchorOrigin={{ vertical: "top", horizontal: "right" }} + > + <Alert severity="info" + style={{ backgroundColor: "#00acc1" }}> + {snackbarText[snackbarIndex]} + </Alert> + </Snackbar> + + <ModalAvaliarRecurso + open={modalCuradoriaOpen} + handleClose={() => { + handleModalCuradoria(false); + }} + title={recurso.name} + confirm={handleConfirm} + setCriteria={setReportCriteria} + /> + <ModalConfirmarCuradoria + aceito={submissionAccepted} + reportCriteria={reportCriteria} + justificativa={justificativa} + open={modalConfirmarCuradoriaOpen} + handleClose={() => { + handleModalConfirmarCuradoria(false); + }} + cancel={() => { + handleModalCuradoria(true); + }} + recursoId={recurso.submission_id} + finalizeCuratorshipFlow={finalizeCuratorshipFlow} + handleErrorAprove={() => { + handleSnackbar(6) + }} + /> + <Background> + {carregando ? ( + <LoadingSpinner text={"Carregando Recurso"} /> + ) : ( + <> + <Grid container spacing={2}> + {recurso.object_type === "Vídeo" && !recurso.link ? ( + <Grid item xs={12}> + <Card> + <VideoPlayer + link={recurso.link} + urlVerified={false} + videoUrl={recurso.default_attachment_location} + videoType={recurso.default_mime_type} + /> + </Card> + </Grid> + ) : ( + urlVerify(recurso.link) && ( + <Grid item xs={12}> + <Card> + <VideoPlayer link={recurso.link} urlVerified={true} /> + </Card> + </Grid> + ) + )} + <Grid item xs={12}> <Card> - <VideoPlayer - link={recurso.link} - urlVerified={false} - videoUrl={recurso.default_attachment_location} - videoType={recurso.default_mime_type} - /> - </Card> - </Grid> - ) : ( - urlVerify(recurso.link) && ( - <Grid item xs={12}> - <Card> - <VideoPlayer link={recurso.link} urlVerified={true} /> - </Card> - </Grid> - ) - )} + <div> + {recurso.thumbnail && ( + <img alt="" src={apiDomain + recurso.thumbnail} /> + )} - <Grid item xs={12}> - <Card> - <div> - {recurso.thumbnail && ( - <img alt="" src={apiDomain + recurso.thumbnail} /> - )} + <TextoObjeto + name={recurso.name} + rating={recurso.review_average} + recursoId={id} + likesCount={recurso.likes_count} + likedBool={recurso.liked} + objType={recurso.object_type} + subjects={recurso.subjects} + educationalStages={recurso.educational_stages} + viewCount={recurso.views_count} + downloadCount={recurso.downloads_count} + id={recurso.publisher ? recurso.publisher.id : undefined} + stateRecurso={recurso.state} + attachments={recurso.attachments} + audioUrl={recurso.default_attachment_location} + /> + </div> - <TextoObjeto - name={recurso.name} - rating={recurso.review_average} + <Footer recursoId={id} - likesCount={recurso.likes_count} - likedBool={recurso.liked} - objType={recurso.object_type} - subjects={recurso.subjects} - educationalStages={recurso.educational_stages} - viewCount={recurso.views_count} - downloadCount={recurso.downloads_count} - id={recurso.publisher ? recurso.publisher.id : undefined} - stateRecurso={recurso.state} - attachments={recurso.attachments} - audioUrl={recurso.default_attachment_location} + downloadableLink={recurso.default_attachment_location} + handleSnackbar={handleSnackbar} + link={recurso.link} + title={recurso.name} + thumb={recurso.thumbnail} + currPageLink={window.location.href} + complained={recurso.complained} /> - </div> - - <Footer - recursoId={id} - downloadableLink={recurso.default_attachment_location} - handleSnackbar={handleSnackbar} - link={recurso.link} - title={recurso.name} - thumb={recurso.thumbnail} - currPageLink={window.location.href} - complained={recurso.complained} - /> - </Card> - </Grid> - - <Grid item xs={12}> - <Card> - {/*todo: change render method on additional item info*/} - <Sobre - avatar={ - recurso.publisher - ? recurso.publisher.avatar - ? apiDomain + recurso.publisher.avatar - : noAvatar - : noAvatar - } - publisher={ - recurso.publisher ? recurso.publisher.name : undefined - } - id={recurso.publisher ? recurso.publisher.id : undefined} - description={recurso.description} - author={recurso.author} - tags={recurso.tags} - attachments={recurso.attachments} - language={recurso.language} - mimeType={recurso.default_mime_type} - createdAt={recurso.created_at} - updatedAt={recurso.updated_at} - license={recurso.license} - followed={recurso.publisher.followed} - /> - </Card> - </Grid> + </Card> + </Grid> - {recurso.state !== "submitted" && ( <Grid item xs={12}> <Card> - {/*adicionar funcionalidade ao botao de entrar*/} - <CommentsArea - recursoId={id} - handleSnackbar={handleSnackbar} - objType={recurso.object_type} - recurso={true} + {/*todo: change render method on additional item info*/} + <Sobre + avatar={ + recurso.publisher + ? recurso.publisher.avatar + ? apiDomain + recurso.publisher.avatar + : noAvatar + : noAvatar + } + publisher={ + recurso.publisher ? recurso.publisher.name : undefined + } + id={recurso.publisher ? recurso.publisher.id : undefined} + description={recurso.description} + author={recurso.author} + tags={recurso.tags} + attachments={recurso.attachments} + language={recurso.language} + mimeType={recurso.default_mime_type} + createdAt={recurso.created_at} + updatedAt={recurso.updated_at} + license={recurso.license} + followed={recurso.publisher.followed} /> </Card> </Grid> - )} - </Grid> - - {recurso.state === "submitted" && checkAccessLevel("curator") && ( - <AppBar - position="fixed" - color="primary" - className={classes.appBar} - > - <StyledAppBarContainer> - <div className="container"> - <div className="botoes"> - <ButtonAvaliarRecurso - callback={() => { - handleModalCuradoria(true); - }} + + {recurso.state !== "submitted" && ( + <Grid item xs={12}> + <Card> + {/*adicionar funcionalidade ao botao de entrar*/} + <CommentsArea + recursoId={id} + handleSnackbar={handleSnackbar} + objType={recurso.object_type} + recurso={true} /> + </Card> + </Grid> + )} + </Grid> + + {recurso.state === "submitted" && checkAccessLevel("curator") && ( + <AppBar + position="fixed" + color="primary" + className={classes.appBar} + > + <StyledAppBarContainer> + <div className="container"> + <div className="botoes"> + <ButtonAvaliarRecurso + callback={() => { + handleModalCuradoria(true); + }} + /> + </div> </div> - </div> - </StyledAppBarContainer> - </AppBar> - )} - </> - )} - </Background> - </React.Fragment> - ); + </StyledAppBarContainer> + </AppBar> + )} + </> + )} + </Background> + </React.Fragment> + ); } const useStyles = makeStyles((theme) => ({ @@ -354,6 +379,27 @@ const Background = styled.div` padding-top: 30px; `; +const LearnObjectNotFound = styled.div` + margin: 1em; + + .not-found{ + font-family: 'Roboto', sans-serif; + font-weight: 500; + text-align: left; + padding: 0; + margin: 0; + } + + .back-button{ + background-color: #ff7f00; + color: whitesmoke; + } + + .link{ + text-decoration: none; + } +` + const Card = styled.div` background-color: #fff; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);