diff --git a/package-lock.json b/package-lock.json
index 3b45dc08..c1150518 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -24,7 +24,7 @@
"glob": "^11.0.0",
"lru-cache": "^11.0.1",
"postcss-resolve-url": "^0.0.1",
- "react": "^19.0.0",
+ "react": "^18.3.1",
"react-cookie": "^7.2.2",
"react-dom": "^18.3.1",
"react-hook-form": "^7.53.2",
@@ -14813,10 +14813,13 @@
}
},
"node_modules/react": {
- "version": "19.0.0",
- "resolved": "https://registry.npmjs.org/react/-/react-19.0.0.tgz",
- "integrity": "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==",
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
+ "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
"license": "MIT",
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ },
"engines": {
"node": ">=0.10.0"
}
diff --git a/package.json b/package.json
index 316999c0..85463313 100644
--- a/package.json
+++ b/package.json
@@ -19,7 +19,7 @@
"glob": "^11.0.0",
"lru-cache": "^11.0.1",
"postcss-resolve-url": "^0.0.1",
- "react": "^19.0.0",
+ "react": "^18.3.1",
"react-cookie": "^7.2.2",
"react-dom": "^18.3.1",
"react-hook-form": "^7.53.2",
diff --git a/src/App.tsx b/src/App.tsx
index 935bbffb..00eb59de 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -4,12 +4,12 @@ import "./style/App.css";
import Home from "./shared/pages/Home.tsx";
import PageNotFound from "./shared/pages/404.tsx";
import MainNavigation from "./shared/components/Navigation/MainNavigation.tsx";
-import Jobs from "./opportunities/pages/Jobs.js";
+import Jobs from "./opportunities/pages/Jobs.tsx";
import Departments from "./staff/pages/Departments.tsx";
import StaffPage from "./staff/pages/Staff.tsx";
import Department from "./staff/pages/Department.tsx";
import CreatePost from "./staff/pages/CreatePost.tsx";
-import IndividualPost from "./opportunities/pages/IndividualPost.js";
+import IndividualPost from "./opportunities/pages/IndividualPost.tsx";
import ProfilePage from "./shared/pages/Profile.tsx";
import LoginRedirection from "./auth/Login.tsx";
import LogoutRedirection from "./auth/Logout.tsx";
diff --git a/src/opportunities/components/FiltersField.js b/src/opportunities/components/FiltersField.js
deleted file mode 100644
index 23533487..00000000
--- a/src/opportunities/components/FiltersField.js
+++ /dev/null
@@ -1,42 +0,0 @@
-import React from "react";
-import SmallTextButton from "./SmallTextButton";
-import SearchBar from "./SearchBar";
-import GroupedComponents from "../../shared/components/UIElements/GroupedComponents";
-import HorizontalIconButton from "./HorizontalIconButton";
-import { PiSlidersHorizontal } from "react-icons/pi";
-import { MdCancel } from "react-icons/md";
-
-const FiltersField = ({ deleteFilter, filters }) => {
- return (
-
-
-
-
-
-
-
- {filters.map((filter) => {
- return (
- }
- key={filter}
- >
- {filter}
-
- );
- })}
-
-
-
-
-
- All Filters
-
-
-
-
- );
-};
-
-export default FiltersField;
diff --git a/src/opportunities/components/FiltersField.tsx b/src/opportunities/components/FiltersField.tsx
new file mode 100644
index 00000000..fae9ab58
--- /dev/null
+++ b/src/opportunities/components/FiltersField.tsx
@@ -0,0 +1,58 @@
+import React from "react";
+import SmallTextButton from "./SmallTextButton.tsx";
+import SearchBar from "./SearchBar.tsx";
+import GroupedComponents from "../../shared/components/UIElements/GroupedComponents";
+import HorizontalIconButton from "./HorizontalIconButton.tsx";
+import { PiSlidersHorizontal } from "react-icons/pi";
+import { MdCancel } from "react-icons/md";
+import PropTypes from "prop-types";
+
+const FiltersField = ({ resetFilters, deleteFilter, filters, setPopUpMenu }) => {
+
+ return (
+
+
+
+
+
+
+
+
+ Change Filters
+
+
+
+ {/* Fix rendering with new filters = [ [],[],[] ]*/}
+
+ {filters[1].map((filter) => {
+ return(
+ }
+ key={filter}
+ special={false}
+ >
+ {filter}
+
+ )
+ })}
+
+
+
+
+ Reset
+
+
+
+
+ );
+};
+
+FiltersField.propTypes = {
+ resetFilters: PropTypes.func.isRequired,
+ deleteFilter: PropTypes.func.isRequired,
+ filters: PropTypes.arrayOf(PropTypes.array),
+ setPopUpMenu: PropTypes.func.isRequired,
+};
+
+export default FiltersField;
diff --git a/src/opportunities/components/HorizontalIconButton.js b/src/opportunities/components/HorizontalIconButton.tsx
similarity index 66%
rename from src/opportunities/components/HorizontalIconButton.js
rename to src/opportunities/components/HorizontalIconButton.tsx
index 568211eb..001655fe 100644
--- a/src/opportunities/components/HorizontalIconButton.js
+++ b/src/opportunities/components/HorizontalIconButton.tsx
@@ -1,4 +1,5 @@
-import React, { Children } from "react";
+import React from "react";
+import PropTypes from "prop-types";
const HorizontalIconButton = ({ children, onClick, icon, special }) => {
return (
@@ -20,4 +21,11 @@ const HorizontalIconButton = ({ children, onClick, icon, special }) => {
);
};
+HorizontalIconButton.propTypes = {
+ children: PropTypes.node,
+ onClick: PropTypes.func.isRequired,
+ icon: PropTypes.node,
+ special: PropTypes.bool,
+}
+
export default HorizontalIconButton;
diff --git a/src/opportunities/components/Posts.js b/src/opportunities/components/Posts.js
deleted file mode 100644
index 0c299149..00000000
--- a/src/opportunities/components/Posts.js
+++ /dev/null
@@ -1,89 +0,0 @@
-import React from "react";
-import FiltersField from "../components/FiltersField";
-import PostsField from "./PostsField";
-import { useReducer } from "react";
-import { useCallback } from "react";
-import { useEffect } from "react";
-
-const Posts = () => {
- const reducer = (state, action) => {
- switch (action.type) {
- case "REMOVE_FILTER":
- if (action.filter) {
- state.filters = state.filters.filter((item) => item != action.filter);
- }
- return { ...state };
- case "ADD_FILTER":
- if (action.filter) {
- state.filters.push(action.filter);
- }
- return { ...state };
- case "SET_ACTIVE_ID":
- if (action.id) {
- if (state.jobs.find((job) => job.id === action.id)) {
- state.activeId = action.id;
- }
- }
- return { ...state };
- case "SET_JOBS":
- if (action.jobs) {
- state.jobs = action.jobs;
- }
- return { ...state };
- default:
- return state;
- }
- };
-
- var [jobState, dispatch] = useReducer(reducer, {
- filters: ["Fall", "Credit", "Remote"],
- activeId: "",
- jobs: [],
- });
-
- const removeFilter = useCallback((name) => {
- dispatch({ type: "REMOVE_FILTER", filter: name });
- });
-
- const addFilter = useCallback((name) => {
- dispatch({ type: "ADD_FILTER", filter: name });
- });
-
- const setActiveId = useCallback((val) => {
- console.log(val);
- dispatch({ type: "SET_ACTIVE_ID", id: val });
- });
-
- const fetchOpportunities = async () => {
- const url = `${process.env.REACT_APP_BACKEND_SERVER}/getOpportunityCards`;
-
- const response = await fetch(url);
-
- if (!response.ok) {
- console.log("Error fetching opportunities");
- } else {
- let data = await response.json();
- data = data.data;
- // console.log(data);
- dispatch({ type: "SET_JOBS", jobs: data });
- console.log(jobState.jobs);
- }
- };
-
- useEffect(() => {
- fetchOpportunities();
- }, []);
-
- return (
-
- );
-};
-
-export default Posts;
diff --git a/src/opportunities/components/Posts.tsx b/src/opportunities/components/Posts.tsx
new file mode 100644
index 00000000..959c8ab7
--- /dev/null
+++ b/src/opportunities/components/Posts.tsx
@@ -0,0 +1,260 @@
+import React from "react";
+import FiltersField from "./FiltersField.tsx";
+import PostsField from "./PostsField.tsx";
+import { useReducer } from "react";
+import { useCallback } from "react";
+import { useEffect } from "react";
+import { useForm } from "react-hook-form";
+import CheckBox from "../../staff/components/Checkbox.tsx";
+import PropTypes from "prop-types";
+import Input from "../../staff/components/Input";
+
+const PopUpMenu = ( {setFunction, validYears, clear, add, reset} ) => {
+ const checkboxes = [["Semester",["Summer","Fall","Spring"],"semesters"],
+ ["Eligible Years",validYears,"years"],
+ ["Credits", ["1","2","3","4"],"credits"]]
+ const majors = [["ARCH", "LGHT", "BMED", "CHME", "CIVL", "ECSE", "ENGR", "ENVE", "ECSI", "ISYE"],
+ ["MANE", "MTLE", "ARTS", "COMM", "IHSS", "INQR", "LANG", "LITR", "PHIL"],
+ ["STDO", "WRIT", "COGS", "ECON", "GSAS", "PSYC", "ITWS", "MGMT", "ASTR"],
+ ["BCBP", "BIOL", "CHEM", "CSCI", "ISCI", "ERTH", "MATH", "MATP", "PHYS"]]
+ const {
+ register,
+ handleSubmit,
+ formState: { errors },
+ } = useForm({
+ defaultValues: {
+ semesters: [],
+ years: [],
+ credits: [],
+ hourlyPay: 0,
+ majors: []
+ },
+ });
+
+ interface FormData {
+ semesters: string[],
+ years: string[],
+ credits: string[],
+ hourlyPay: string,
+ majors: string[]
+ }
+
+ function submitHandler(data: FormData) {
+ const { semesters, years, credits, hourlyPay, majors} = data;
+ clear();
+ add(semesters)
+ add(years)
+ add(credits)
+ if (hourlyPay == "0") {
+ add([])
+ } else {
+ add([hourlyPay])
+ }
+ add(majors)
+ setFunction()
+ };
+
+ return (
+
+ );
+}
+
+PopUpMenu.propTypes = {
+ setFunction: PropTypes.func.isRequired,
+ validYears: PropTypes.arrayOf(PropTypes.string),
+ clear: PropTypes.func.isRequired,
+ add: PropTypes.func.isRequired,
+ reset: PropTypes.func.isRequired
+};
+
+const Posts = ( {years} ) => {
+ const [popUpMenu, setPopUpMenu] = React.useState(false);
+
+ const date = new Date();
+ const month = date.getMonth();
+ const currSem = (0 <= month && month <= 5) ? "Spring" : (5 < month && month <= 8) ? "Summer" : "Fall";
+ const currYr = date.getFullYear();
+
+ const reducer = (state, action) => {
+ switch (action.type) {
+ case "CLEAR_FILTERS":
+ state.filters = [[],[]];
+ return { ...state };
+ case "RESET_FILTERS":
+ state.filters = [[[currSem],[currYr],[],[],[]],[currSem, currYr]];
+ return { ...state };
+ case "REMOVE_FILTER":
+ if (action.filter) {
+ state.filters[1] = state.filters[1].filter((item) => item !== action.filter);
+ state.filters[0].map((list, index) => {
+ state.filters[0][index] = list.filter((item) => item !== action.filter);
+ })
+ }
+ return { ...state };
+ case "ADD_FILTER":
+ if (action.filter) {
+ state.filters[0] = [...state.filters[0], action.filter];
+ state.filters[1] = [...state.filters[1], ...action.filter];
+ console.log(state.filters)
+ }
+ return { ...state };
+ case "SET_ACTIVE_ID":
+ if (action.id) {
+ if (state.jobs.find((job) => job.id === action.id)) {
+ state.activeId = action.id;
+ }
+ }
+ return { ...state };
+ case "SET_JOBS":
+ if (action.jobs) {
+ state.jobs = action.jobs;
+ }
+ return { ...state };
+ default:
+ return state;
+ }
+ };
+
+ const [jobState, dispatch] = useReducer(reducer, {
+ filters: [[[currSem],[currYr],[],[],[]],[currSem, currYr]],
+ activeId: "",
+ jobs: [],
+ });
+
+ const clearFilters = useCallback(() => {
+ dispatch({ type: "CLEAR_FILTERS"});
+ }, []);
+
+ const resetFilters = useCallback(() => {
+ dispatch({ type: "RESET_FILTERS"});
+ }, []);
+
+ const removeFilter = useCallback((name) => {
+ dispatch({ type: "REMOVE_FILTER", filter: name });
+ }, []);
+
+ const addFilter = useCallback((name) => {
+ dispatch({ type: "ADD_FILTER", filter: name });
+ }, []);
+
+ const setActiveId = useCallback((val) => {
+ dispatch({ type: "SET_ACTIVE_ID", id: val });
+ }, []);
+
+ const fetchOpportunities = async () => {
+ const url = `${process.env.REACT_APP_BACKEND_SERVER}/getOpportunityCards`;
+
+ const response = await fetch(url);
+
+ if (!response.ok) {
+ console.log("Error fetching opportunities");
+ } else {
+ let data = await response.json();
+ data = data.data;
+ dispatch({ type: "SET_JOBS", jobs: data });
+ console.log(jobState.jobs);
+ }
+ };
+
+ useEffect(() => {
+ fetchOpportunities();
+ }, []);
+
+ console.log()
+ return (
+
+ setPopUpMenu(!popUpMenu)} />
+ {popUpMenu && setPopUpMenu(!popUpMenu)} validYears={years} clear={clearFilters} add={addFilter} reset={resetFilters}/>}
+
+
+ );
+};
+
+Posts.propTypes = {
+ years: PropTypes.arrayOf(PropTypes.string),
+};
+
+export default Posts;
diff --git a/src/opportunities/components/PostsField.js b/src/opportunities/components/PostsField.js
deleted file mode 100644
index d23aaa69..00000000
--- a/src/opportunities/components/PostsField.js
+++ /dev/null
@@ -1,137 +0,0 @@
-import React, { useEffect } from "react";
-import { useState } from "react";
-import JobPost from "./JobPost";
-import JobDetails from "./JobDetails";
-
-let DUMMY_JOBS = [
- {
- title: "Software Engineer",
- professor: "Turner",
- id: "u1",
- location: "CII",
- season: "Spring",
- year: 2024,
- },
- {
- title: "Biology Researcher",
- professor: "Turner",
- id: "u2",
- location: "CII",
- season: "Spring",
- year: 2024,
- },
-];
-
-const DUMMY_DATA = [
- {
- title: "Software Engineer",
- description: "Lorem Ipsum",
- author: "John Smith",
- id: "u1",
- authorProfile:
- "https://thedailyq.org/wp-content/uploads/2018/02/H-Menge-Torsten-900x600.jpg",
- department: "Computer Science",
- aboutSection: [
- {
- title: "Application Deadline",
- description: "July 1, 2024, 12pm",
- },
- {
- title: "Application Deadline",
- description: "July 1, 2024, 12pm",
- },
- {
- title: "Application Deadline",
- description: "July 1, 2024, 12pm",
- },
- {
- title: "Application Deadline",
- description: "July 1, 2024, 12pm",
- },
- {
- title: "Application Deadline",
- description: "July 1, 2024, 12pm",
- },
- ],
- },
- {
- title: "Biology Reseacher",
- description: "Lorem Ipsum",
- author: "Turner",
- id: "u2",
- authorProfile:
- "https://thedailyq.org/wp-content/uploads/2018/02/H-Menge-Torsten-900x600.jpg",
- department: "Biology",
- aboutSection: [
- {
- title: "Application Deadline",
- description: "July 1, 2024, 12pm",
- },
- {
- title: "Application Deadline",
- description: "July 1, 2024, 12pm",
- },
- {
- title: "Application Deadline",
- description: "July 1, 2024, 12pm",
- },
- {
- title: "Application Deadline",
- description: "July 1, 2024, 12pm",
- },
- {
- title: "Application Deadline",
- description: "July 1, 2024, 12pm",
- },
- ],
- },
-];
-
-const PostsField = ({ activeId, setActive, opportunities }) => {
- const findJobDetails = (id) => {
- return DUMMY_DATA.find((item) => item.id === id);
- };
-
- var [activeOpportunity, setActiveOpportunity] = useState(null);
-
- const fetchOpportunity = async (id) => {
- const url = `${process.env.REACT_APP_BACKEND_SERVER}/getOpportunity/${id}`;
- const response = await fetch(url);
- if (!response.ok) {
- console.log("Error fetching opportunity");
- setActiveOpportunity(null);
- } else {
- let data = await response.json();
- data = data.data;
- setActiveOpportunity(data);
- }
- };
-
- useEffect(() => {
- fetchOpportunity(activeId);
- }, [activeId]);
-
- return (
-
-
- {opportunities &&
- opportunities.map((job) => {
- return (
-
- );
- })}
-
- {activeId != "" && activeOpportunity && (
-
- )}
- {(activeId === "" || !activeOpportunity) && "Opportunity not found."}
-
- );
-};
-
-export default PostsField;
diff --git a/src/opportunities/components/PostsField.tsx b/src/opportunities/components/PostsField.tsx
new file mode 100644
index 00000000..c155c3ef
--- /dev/null
+++ b/src/opportunities/components/PostsField.tsx
@@ -0,0 +1,57 @@
+import React, { useEffect } from "react";
+import { useState } from "react";
+import JobPost from "./JobPost";
+import JobDetails from "./JobDetails";
+import PropTypes from "prop-types";
+
+
+const PostsField = ({ activeId, setActive, opportunities }) => {
+ const [activeOpportunity, setActiveOpportunity] = useState(null);
+
+ const fetchOpportunity = async (id) => {
+ const url = `${process.env.REACT_APP_BACKEND_SERVER}/getOpportunity/${id}`;
+ const response = await fetch(url);
+ if (!response.ok) {
+ console.log("Error fetching opportunity");
+ setActiveOpportunity(null);
+ } else {
+ let data = await response.json();
+ data = data.data;
+ setActiveOpportunity(data);
+ }
+ };
+
+ useEffect(() => {
+ fetchOpportunity(activeId);
+ }, [activeId]);
+
+ return (
+
+
+ {opportunities &&
+ opportunities.map((job) => {
+ return (
+
+ );
+ })}
+
+ {activeId != "" && activeOpportunity && (
+
+ )}
+ {(activeId === "" || !activeOpportunity) && "Opportunity not found."}
+
+ );
+};
+
+PostsField.propTypes = {
+ activeId: PropTypes.string,
+ setActive: PropTypes.func.isRequired,
+ opportunities: PropTypes.array,
+}
+
+export default PostsField;
diff --git a/src/opportunities/components/SearchBar.js b/src/opportunities/components/SearchBar.tsx
similarity index 84%
rename from src/opportunities/components/SearchBar.js
rename to src/opportunities/components/SearchBar.tsx
index 55636fef..0fce79f6 100644
--- a/src/opportunities/components/SearchBar.js
+++ b/src/opportunities/components/SearchBar.tsx
@@ -3,7 +3,7 @@ import { CiSearch } from "react-icons/ci";
const SearchBar = () => {
return (
-
diff --git a/src/opportunities/components/SmallTextButton.js b/src/opportunities/components/SmallTextButton.js
deleted file mode 100644
index 53872ccb..00000000
--- a/src/opportunities/components/SmallTextButton.js
+++ /dev/null
@@ -1,18 +0,0 @@
-import React, { Children } from "react";
-
-const SmallTextButton = ({ children, onClick, icon, special, className }) => {
- return (
-
-
-
- );
-};
-
-export default SmallTextButton;
diff --git a/src/opportunities/components/SmallTextButton.tsx b/src/opportunities/components/SmallTextButton.tsx
new file mode 100644
index 00000000..2ac9f08a
--- /dev/null
+++ b/src/opportunities/components/SmallTextButton.tsx
@@ -0,0 +1,26 @@
+import React from "react";
+import PropTypes from "prop-types";
+
+const SmallTextButton = ({ children, onClick, special, className }) => {
+ return (
+
+
+
+ );
+};
+
+SmallTextButton.propTypes = {
+ children: PropTypes.node,
+ onClick: PropTypes.func.isRequired,
+ special: PropTypes.bool,
+ className: PropTypes.string,
+}
+
+export default SmallTextButton;
diff --git a/src/opportunities/pages/IndividualPost.js b/src/opportunities/pages/IndividualPost.js
deleted file mode 100644
index 8dd55bb1..00000000
--- a/src/opportunities/pages/IndividualPost.js
+++ /dev/null
@@ -1,108 +0,0 @@
-import React, { useState } from "react";
-import JobDetails from "../components/JobDetails";
-import { useParams } from "react-router";
-import { useEffect } from "react";
-import { set } from "react-hook-form";
-
-const DUMMY_DATA = [
- {
- title: "Software Engineer",
- description: "Lorem Ipsum",
- author: "John Smith",
- id: "u1",
- authorProfile:
- "https://thedailyq.org/wp-content/uploads/2018/02/H-Menge-Torsten-900x600.jpg",
- department: "Computer Science",
- aboutSection: [
- {
- title: "Application Deadline",
- description: "July 1, 2024, 12pm",
- },
- {
- title: "Application Deadline",
- description: "July 1, 2024, 12pm",
- },
- {
- title: "Application Deadline",
- description: "July 1, 2024, 12pm",
- },
- ],
- },
- {
- title: "Biology Reseacher",
- description: "Lorem Ipsum",
- author: "Turner",
- id: "u2",
- authorProfile:
- "https://thedailyq.org/wp-content/uploads/2018/02/H-Menge-Torsten-900x600.jpg",
- department: "Biology",
- aboutSection: [
- {
- title: "Application Deadline",
- description: "July 1, 2024, 12pm",
- },
- {
- title: "Application Deadline",
- description: "July 1, 2024, 12pm",
- },
- {
- title: "Application Deadline",
- description: "July 1, 2024, 12pm",
- },
- {
- title: "Application Deadline",
- description: "July 1, 2024, 12pm",
- },
- {
- title: "Application Deadline",
- description: "July 1, 2024, 12pm",
- },
- ],
- },
-];
-
-const IndividualPost = () => {
- const { postID } = useParams();
-
- var [details, setDetails] = useState("Searching");
-
- const fetchOpportunities = async () => {
- // Consider moving the base URL to a configuration
- const baseURL = `${process.env.REACT_APP_BACKEND_SERVER}`;
- const url = `${baseURL}/getOpportunity/${postID}`;
-
- const response = await fetch(url);
-
- if (!response.ok) {
- return false;
- }
-
- const data = await response.json();
- console.log(data);
- return data["data"];
- };
-
- async function findDetails() {
- var data = await fetchOpportunities();
- details = data || "Nothing found";
- setDetails(details);
- }
-
- useEffect(() => {
- findDetails();
- }, []);
-
- return (
-
- {details === "Searching" ? (
-
- ) : details === "Nothing found" ? (
-
No post found
- ) : (
-
- )}
-
- );
-};
-
-export default IndividualPost;
diff --git a/src/opportunities/pages/IndividualPost.tsx b/src/opportunities/pages/IndividualPost.tsx
new file mode 100644
index 00000000..95eaef1d
--- /dev/null
+++ b/src/opportunities/pages/IndividualPost.tsx
@@ -0,0 +1,50 @@
+import React, { useState } from "react";
+import JobDetails from "../components/JobDetails";
+import { useParams } from "react-router";
+import { useEffect } from "react";
+
+const IndividualPost = () => {
+ const { postID } = useParams();
+
+ const [details, setDetails] = useState("Searching");
+
+ const fetchOpportunities = async () => {
+ // Consider moving the base URL to a configuration
+ const baseURL = `${process.env.REACT_APP_BACKEND_SERVER}`;
+ const url = `${baseURL}/getOpportunity/${postID}`;
+
+ const response = await fetch(url);
+
+ if (!response.ok) {
+ return false;
+ }
+
+ const data = await response.json();
+ console.log(data);
+ return data["data"];
+ };
+
+ async function findDetails() {
+ const data = await fetchOpportunities();
+ details = data || "Nothing found";
+ setDetails(details);
+ }
+
+ useEffect(() => {
+ findDetails();
+ }, []);
+
+ return (
+
+ {details === "Searching" ? (
+
+ ) : details === "Nothing found" ? (
+
No post found
+ ) : (
+
+ )}
+
+ );
+};
+
+export default IndividualPost;
diff --git a/src/opportunities/pages/Jobs.js b/src/opportunities/pages/Jobs.js
deleted file mode 100644
index 2d33cfb3..00000000
--- a/src/opportunities/pages/Jobs.js
+++ /dev/null
@@ -1,24 +0,0 @@
-import React, { useState } from "react";
-import JobsNavigation from "../components/JobsNavigation";
-import Posts from "../components/Posts";
-import SavedJobs from "../components/SavedJobs";
-import PageNavigation from "../../shared/components/Navigation/PageNavigation";
-import usePageNavigation from "../../shared/hooks/page-navigation-hook";
-
-const Jobs = () => {
- var [pages, switchPage] = usePageNavigation(["Search", "Saved"], "Search");
-
- return (
-
-
-
-
-
- {pages.activePage === "Search" && }
-
-
-
- );
-};
-
-export default Jobs;
diff --git a/src/opportunities/pages/Jobs.tsx b/src/opportunities/pages/Jobs.tsx
new file mode 100644
index 00000000..c6319b27
--- /dev/null
+++ b/src/opportunities/pages/Jobs.tsx
@@ -0,0 +1,41 @@
+import React, { useState } from "react";
+import Posts from "../components/Posts.tsx";
+import PageNavigation from "../../shared/components/Navigation/PageNavigation";
+import usePageNavigation from "../../shared/hooks/page-navigation-hook";
+
+const Jobs = () => {
+ const [loading, setLoading] = useState(false);
+ const [years, setYears] = useState([]);
+
+ async function fetchYears() {
+ const response = await fetch(`${process.env.REACT_APP_BACKEND_SERVER}/years`);
+
+ if (response.ok) {
+ const data = await response.json();
+ setYears(data);
+ } else {
+ console.log("No response for years");
+ setLoading("no response");
+ }
+ }
+ fetchYears()
+
+ const [pages, switchPage] = usePageNavigation(["Search", "Saved"], "Search");
+
+ return loading === false && years != null ? (
+
+
+
+
+ {pages.activePage === "Search" && }
+
+
+
+ ) : loading === "no response" ? (
+ There was no response
+ ) : (
+ Loading...
+ );
+};
+
+export default Jobs;
diff --git a/src/style/general.css b/src/style/general.css
index 3fd7a061..9f9c55dd 100644
--- a/src/style/general.css
+++ b/src/style/general.css
@@ -16,9 +16,6 @@
.about-head {@apply flex flex-col gap-1;}
.about-title {@apply text-gray-500 text-base;}
.about-description {@apply font-extrabold;}
-.filters-template { @apply px-3 overflow-x-scroll max-h-20 flex gap-3;}
-.filters-search {@apply flex gap-2 w-full;}
-.all-filters-btn {@apply justify-end w-full;}
.horizontal-btn {@apply flex gap-1 align-items-center p-2 px-2.5 rounded-3xl border;}
.job-desc-header {@apply flex flex-col gap-2;}
.job-desc-title {@apply font-extrabold text-xl;}