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: ,