diff --git a/src/components/pages/ModuleResources/index.tsx b/src/components/pages/ModuleResources/index.tsx index 47b343049b21c8454000ea1594dfe701680eff81..b5082888638ea5dab102da76a0f07376b32f444f 100644 --- a/src/components/pages/ModuleResources/index.tsx +++ b/src/components/pages/ModuleResources/index.tsx @@ -1,8 +1,8 @@ -import React, { useEffect, useState } from "react"; +import React from "react"; import styles from "./style.module.scss"; -import { request } from "../../../utils/api" -import { api } from "../../../constants/routes" +import { request } from "../../../utils/api"; +import { api } from "../../../constants/routes"; import MyBreadcrumbs from "components/atoms/MyBreadcrumbs"; import InputGroup from "react-bootstrap/InputGroup"; @@ -13,9 +13,8 @@ import { faInfoCircle } from "@fortawesome/free-solid-svg-icons"; import QuickAccessView from "components/molecules/QuickAccessView"; import ResourcesFolderView from "components/molecules/ResourcesFolderView"; import CurrentDirectoryView from "components/molecules/CurrentDirectoryView"; -import { useParams } from "react-router-dom"; -export interface Resource { +interface Resource { title: string; type: string; tags: string[]; @@ -23,41 +22,39 @@ export interface Resource { id: number; } -const ModuleResources: React.FC<{ year: string}> = ({year}) => { - let {id, scope } = useParams(); - scope = scope === undefined ? "" : scope; - - const module_code = id.startsWith("CO") ? id.slice(2) : id; - - //maybe refactor into class? - const [error, setError] = useState(null); - const [isLoaded, setIsLoaded] = useState(false); - const [resources, setResources] = useState<Resource[]>([]); - - let quickAccessItems = resources.filter( - ({ tags, folder }) => - tags.includes("new") && (scope === "" || scope === folder) - ); +export interface ResourcesProps { + year: string; + moduleID: string; + scope?: string; +} - let currentDirectoryFiles = resources.filter( - ({ folder }) => folder === scope - ); +export interface ResourceState { + error: any; + isLoaded: Boolean; + resources: Resource[]; +} - let folders: { title: string; id: number;}[] = Array.from(new Set<string>(resources.map((res: Resource) => { - return res.folder; }))).map((title: string) => { - return { - title: title, - id: 0, - }; - }) +class ModuleResources extends React.Component<ResourcesProps, ResourceState> { + constructor(props: ResourcesProps) { + super(props); + this.state = { + error: null, + isLoaded: false, + resources: [], + }; + } - useEffect(() => { - setIsLoaded(false); - const onSuccess = (data: { json: () => Promise<any>; }) => { - let resourceArr : Resource[] = []; - data.json().then(json => { + componentDidMount() { + this.setState({ isLoaded: false }); + let moduleCode = this.props.moduleID.startsWith("CO") + ? this.props.moduleID.slice(2) + : this.props.moduleID; + const onSuccess = (data: { json: () => Promise<any> }) => { + let resourceArr: Resource[] = []; + + data.json().then((json) => { for (const key in json) { - let resource = json[key] + let resource = json[key]; resourceArr.push({ title: resource.title, type: resource.type, @@ -65,48 +62,79 @@ const ModuleResources: React.FC<{ year: string}> = ({year}) => { folder: resource.category, id: resource.id, } as Resource); - } - setResources(resourceArr); - setIsLoaded(true); + } + this.setState({ resources: resourceArr, isLoaded: true }); }); - } - const onFailure = (error: { text: () => Promise<any>; }) => { - error.text().then(errorText => { - setError(errorText); - setIsLoaded(true); + }; + const onFailure = (error: { text: () => Promise<any> }) => { + error.text().then((errorText) => { + this.setState({ error: errorText, isLoaded: true }); }); - } + }; request(api.MATERIALS_RESOURCES, "GET", onSuccess, onFailure, { - "year": year, - "course": module_code - }) - }, [year, module_code]); + year: this.props.year, + course: moduleCode, + }); + } + + render() { + let scope = this.props.scope === undefined ? "" : this.props.scope; + let resources = this.state.resources; - - return ( - <> - <MyBreadcrumbs /> - <InputGroup> - <FormControl - className={styles.searchBar} - aria-label="Search" - placeholder="Search..." - /> - <InputGroup.Append> - <Button variant="secondary" className={styles.searchBarIcon}> - <FontAwesomeIcon size="1x" icon={faInfoCircle} /> - </Button> - </InputGroup.Append> - </InputGroup> - {isLoaded ? ( - error ? <> Error retrieving data: {error} </> : <> - {scope === "" && folders.length > 0 ? <ResourcesFolderView folderItems={folders} /> : null} - {scope !== "" && currentDirectoryFiles.length > 0 ? <CurrentDirectoryView documentItems={currentDirectoryFiles} /> : null} - {scope === "" && quickAccessItems.length > 0 ? <QuickAccessView quickAccessItems={quickAccessItems} /> : null} - </>) : <>Loading...</>} - </> - ); -}; + let quickAccessItems = resources.filter( + ({ tags, folder }) => + tags.includes("new") && (scope === "" || scope === folder) + ); + + let currentDirectoryFiles = resources.filter( + ({ folder }) => folder === scope + ); + + let folders: { title: string; id: number }[] = Array.from( + new Set<string>(resources.map((res: Resource) => res.folder)) + ).map((title: string) => ({ + title: title, + id: 0, + })); + + return ( + <> + <MyBreadcrumbs /> + <InputGroup> + <FormControl + className={styles.searchBar} + aria-label="Search" + placeholder="Search..." + /> + <InputGroup.Append> + <Button variant="secondary" className={styles.searchBarIcon}> + <FontAwesomeIcon size="1x" icon={faInfoCircle} /> + </Button> + </InputGroup.Append> + </InputGroup> + {this.state.isLoaded ? ( + this.state.error ? ( + <> Error retrieving data: {this.state.error} </> + ) : ( + <> + {scope === "" && folders.length > 0 ? ( + <ResourcesFolderView folderItems={folders} /> + ) : null} + {scope !== "" && currentDirectoryFiles.length > 0 ? ( + <CurrentDirectoryView documentItems={currentDirectoryFiles} /> + ) : null} + {scope === "" && quickAccessItems.length > 0 ? ( + <QuickAccessView quickAccessItems={quickAccessItems} /> + ) : null} + </> + ) + ) : ( + <>Loading...</> + )} + </> + ); + } +} export default ModuleResources; diff --git a/src/components/pages/StandardView/index.tsx b/src/components/pages/StandardView/index.tsx index 9311dd86c7cf14b96c1e72138618fe54466d66c7..6a8f3e0a8f38e22471b3447b80b19110e89642ea 100644 --- a/src/components/pages/StandardView/index.tsx +++ b/src/components/pages/StandardView/index.tsx @@ -31,8 +31,8 @@ const StandardView: React.FC<StandardViewProps> = ({ toggledLeft, toggledRight, onOverlayClick, -}: StandardViewProps) => { - const [modulesFilter, setModulesFilter] = useState("In Progress"); +}: StandardViewProps) => { + const [modulesFilter, setModulesFilter] = useState("In Progress"); return ( <div @@ -48,7 +48,10 @@ const StandardView: React.FC<StandardViewProps> = ({ </Route> <Route exact path="/modules"> - <LeftBarModuleList modulesFilter={modulesFilter} setModulesFilter={setModulesFilter}/> + <LeftBarModuleList + modulesFilter={modulesFilter} + setModulesFilter={setModulesFilter} + /> </Route> <Route path="/exams"> @@ -68,21 +71,28 @@ const StandardView: React.FC<StandardViewProps> = ({ </Route> <Route exact path="/modules"> - <ModuleList modulesFilter={modulesFilter}/> + <ModuleList modulesFilter={modulesFilter} /> </Route> <Route path="/modules/:id/overview"> <ModuleOverview /> </Route> - <Route path="/modules/:id/resources/:scope?"> - <ModuleResources year="2021"/> - </Route> + <Route + path="/modules/:id/resources/:scope?" + render={(props) => ( + <ModuleResources + year="1819" + moduleID={props.match.params.id} + scope={props.match.params.scope} + /> + )} + /> <Route path="/modules/:id/feedback" component={ModuleFeedback} /> <Route path="/timeline"> - <Timeline/> + <Timeline /> </Route> <Route path="/exams/overview"> @@ -95,7 +105,10 @@ const StandardView: React.FC<StandardViewProps> = ({ <Redirect to={`/modules/${props.match.params.id}/overview`} /> )} /> - <Route path="/exams" render={() => <Redirect to="/exams/overview" />} /> + <Route + path="/exams" + render={() => <Redirect to="/exams/overview" />} + /> <Route path="/" render={() => <Redirect to="/dashboard" />} /> </Switch> </Container>