frontend/src/views/project.js (144 lines of code) (raw):

import React, { Suspense } from 'react'; import { useSelector } from 'react-redux'; import ReactPlaceholder from 'react-placeholder'; import { ProjectNav } from '../components/projects/projectNav'; import { MyProjectNav } from '../components/projects/myProjectNav'; import { MoreFiltersForm } from '../components/projects/moreFiltersForm'; import { ProjectDetail } from '../components/projectDetail/index'; import { ProjectCardPaginator } from '../components/projects/projectCardPaginator'; import { ProjectSearchResults } from '../components/projects/projectSearchResults'; import { ProjectsMap } from '../components/projects/projectsMap'; import { useProjectsQueryAPI, useExploreProjectsQueryParams, stringify, } from '../hooks/UseProjectsQueryAPI'; import { useTagAPI } from '../hooks/UseTagAPI'; import useForceUpdate from '../hooks/UseForceUpdate'; import { useFetch } from '../hooks/UseFetch'; import { useSetTitleTag } from '../hooks/UseMetaTags'; import { NotFound } from './notFound'; const ProjectCreate = React.lazy(() => import('../components/projectCreate/index')); export const CreateProject = (props) => { return ( <Suspense fallback={<div>Loading...</div>}> <ProjectCreate {...props} /> </Suspense> ); }; export const ProjectsPage = (props) => { useSetTitleTag('Explore projects'); const initialData = { mapResults: { features: [], type: 'FeatureCollection', }, results: [], pagination: { hasNext: false, hasPrev: false, page: 1 }, }; const [fullProjectsQuery, setProjectQuery] = useExploreProjectsQueryParams(); const [forceUpdated, forceUpdate] = useForceUpdate(); const [state] = useProjectsQueryAPI(initialData, fullProjectsQuery, forceUpdated); const isMapShown = useSelector((state) => state.preferences['mapShown']); const searchResultWidth = isMapShown ? 'w-60-l w-100' : 'w-100'; return ( <div className="pull-center"> <ProjectNav location={props.location}> { props.children /* This is where the MoreFilters component is rendered using the router, as a child route. */ } </ProjectNav> <section className="cf"> <ProjectSearchResults state={state} retryFn={forceUpdate} className={`${searchResultWidth} pl3 fl`} /> {isMapShown && ( <ProjectsMap state={state} fullProjectsQuery={fullProjectsQuery} setQuery={setProjectQuery} className={`dib w-40-l w-100 fl`} /> )} </section> <ProjectCardPaginator projectAPIstate={state} setQueryParam={setProjectQuery} /> </div> ); }; export const UserProjectsPage = (props) => { useSetTitleTag(props.management ? 'Manage projects' : 'My projects'); const userToken = useSelector((state) => state.auth.get('token')); const initialData = { mapResults: { features: [], type: 'FeatureCollection', }, results: [], pagination: { hasNext: false, hasPrev: false, page: 1 }, }; const [fullProjectsQuery, setProjectQuery] = useExploreProjectsQueryParams(); const [forceUpdated, forceUpdate] = useForceUpdate(); const [state] = useProjectsQueryAPI(initialData, fullProjectsQuery, forceUpdated); const [orgAPIState] = useTagAPI([], 'organisations'); const isMapShown = useSelector((state) => state.preferences['mapShown']); const searchResultWidth = isMapShown ? 'w-60-l w-100' : 'w-100'; if (!userToken) { /* use replace to so the back button does not get interrupted */ props.navigate('/login', { replace: true }); } if ( !fullProjectsQuery.createdByMe && !fullProjectsQuery.managedByMe && !fullProjectsQuery.mappedByMe && !fullProjectsQuery.favoritedByMe && !fullProjectsQuery.status ) { setProjectQuery({ managedByMe: true }); } return ( <div className="pull-center bg-tan"> <MyProjectNav location={props.location} orgAPIState={orgAPIState} management={props.management} > { props.children /* This is where the MoreFilters component is rendered using the router, as a child route. */ } </MyProjectNav> <section className="cf"> <ProjectSearchResults state={state} retryFn={forceUpdate} className={`${searchResultWidth} fl`} showBottomButtons={props.location && props.location.pathname.startsWith('/manage/')} management={props.management} /> {isMapShown && ( <ProjectsMap state={state} fullProjectsQuery={fullProjectsQuery} setQuery={setProjectQuery} className={`dib w-40-l w-100 fl`} /> )} </section> <ProjectCardPaginator projectAPIstate={state} setQueryParam={setProjectQuery} /> </div> ); }; export const ProjectsPageIndex = (props) => { return null; }; export const MoreFilters = (props) => { const [fullProjectsQuery] = useExploreProjectsQueryParams(); const currentUrl = `/explore${ stringify(fullProjectsQuery) ? ['?', stringify(fullProjectsQuery)].join('') : '' }`; return ( <> <div className="absolute left-0 z-4 mt1 w-40-l w-100 h-100 bg-white h4 ph1 ph5-l"> <MoreFiltersForm currentUrl={currentUrl} /> {props.children} </div> <div onClick={() => props.navigate(currentUrl)} className="absolute right-0 z-4 br w-60-l w-0 h-100 bg-blue-dark o-70 h6" ></div> </> ); }; export const ProjectDetailPage = (props) => { const [error, loading, data] = useFetch(`projects/${props.id}/`, props.id); return ( <ReactPlaceholder showLoadingAnimation={true} rows={30} delay={1000} ready={loading === false}> {!error ? ( <ProjectDetail project={data} projectLoading={loading} tasksError={error} tasks={data.tasks} navigate={props.navigate} type="detail" /> ) : ( <NotFound projectId={props.id} /> )} </ReactPlaceholder> ); }; export const ManageProjectsPage = (props) => <UserProjectsPage {...props} management={true} />;