From 6f6b565d0f580a9619d6f912e10d415516826c0a Mon Sep 17 00:00:00 2001 From: Beiming Zhang Date: Wed, 11 Sep 2024 12:53:48 +0800 Subject: [PATCH] Add favorites page --- src/Components/Favorites/Favorites.jsx | 66 ++++++++++++++++++ src/Components/Favorites/ProgramCard.jsx | 68 +++++++++++++++++++ .../SideBar/SearchBar/SearchBar.jsx | 8 +-- src/Components/router.jsx | 18 +++++ 4 files changed, 156 insertions(+), 4 deletions(-) create mode 100644 src/Components/Favorites/Favorites.jsx create mode 100644 src/Components/Favorites/ProgramCard.jsx diff --git a/src/Components/Favorites/Favorites.jsx b/src/Components/Favorites/Favorites.jsx new file mode 100644 index 0000000..2331b1d --- /dev/null +++ b/src/Components/Favorites/Favorites.jsx @@ -0,0 +1,66 @@ +import { Container } from "@mui/material"; +import Grid from "@mui/material/Unstable_Grid2"; +import { Outlet, useLoaderData } from "react-router-dom"; +import { getMetaData } from "../../Data/UserData"; +import { loader as ProgramPageLoader } from "../ProgramPage/ProgramPage"; +import SearchBar from "../ProgramPage/SideBar/SearchBar/SearchBar"; +import { getQuery } from "../ProgramPage/SideBar/SideBar"; +import ProgramCard from "./ProgramCard"; + +function filterProgramsById(programs, programIDs) { + let filtered = {}; + for (const university in programs) { + const filteredPrograms = programs[university].filter((program) => + programIDs.includes(program.ProgramID) + ); + if (filteredPrograms.length > 0) { + filtered[university] = filteredPrograms; + } + } + return filtered; +} + +function flattenPrograms(programs) { + let flattened = []; + for (const university in programs) { + flattened.push(...programs[university]); + } + return flattened; +} + +export async function loader({ request }) { + const metaData = await getMetaData(); + const programPageData = await ProgramPageLoader({ request }); + programPageData.programs = filterProgramsById( + programPageData.programs, + metaData.ProgramCollection || [] + ); + return { programPageData }; +} + +export default function Favorites() { + let { programPageData } = useLoaderData(); + + return ( + + + + + + {flattenPrograms(programPageData.programs).map((program) => ( + + ))} + + + + ); +} diff --git a/src/Components/Favorites/ProgramCard.jsx b/src/Components/Favorites/ProgramCard.jsx new file mode 100644 index 0000000..9825a2c --- /dev/null +++ b/src/Components/Favorites/ProgramCard.jsx @@ -0,0 +1,68 @@ +import { useTheme } from "@mui/material"; +import Paper from "@mui/material/Paper"; +import Typography from "@mui/material/Typography"; +import Grid from "@mui/material/Unstable_Grid2"; +import { grey } from "@mui/material/colors"; +import { useNavigate } from "react-router-dom"; +import { regionFlagMapping } from "../../Data/Schemas"; + +const ProgramCard = ({ program }) => { + const darkMode = useTheme().palette.mode === "dark"; + + const navigate = useNavigate(); + + const flags = program.Region.map((r) => regionFlagMapping[r]).reduce( + (prev, curr) => prev + " " + curr, + "" + ); + + return ( + + + navigate( + `/favorites/${program.ProgramID}${window.location.search}` + ) + } + > + + {flags} + + + {program.ProgramID} + + + + ); +}; + +export default ProgramCard; diff --git a/src/Components/ProgramPage/SideBar/SearchBar/SearchBar.jsx b/src/Components/ProgramPage/SideBar/SearchBar/SearchBar.jsx index ce65e4e..881e725 100644 --- a/src/Components/ProgramPage/SideBar/SearchBar/SearchBar.jsx +++ b/src/Components/ProgramPage/SideBar/SearchBar/SearchBar.jsx @@ -22,7 +22,7 @@ export default function SearchBar({query, pageName}) { const [searchParams, setSearchParams] = useSearchParams(); const [timeoutId, setTimeoutId] = useState(null); useEffect(() => { - if (pageName === 'program') { + if (pageName === 'program' || pageName === 'favories') { document.getElementById('u').value = query.u; document.getElementById('d').value = query.d?.split(','); document.getElementById('m').value = query.m?.split(','); @@ -53,7 +53,7 @@ export default function SearchBar({query, pageName}) { const defaultRegion = regionList.filter(x => query.r?.split(',').includes(x)); return ( - + - {pageName === 'program' ? } - {pageName === 'program' ? <> + {pageName === 'program' || pageName === 'favorites' ? <> , + loader: FavoritesLoader, + children: [ + { + errorElement: , + children: [ + { + path: '/favorites/:programId', + element: , + loader: programContentLoader, + action: programContentAction + } + ] + } + ] }, { path: '/posts', element: ,