diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index d74e05d..b76376c 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -9,7 +9,8 @@
"version": "0.0.0",
"dependencies": {
"react": "^18.2.0",
- "react-dom": "^18.2.0"
+ "react-dom": "^18.2.0",
+ "react-router-dom": "^6.22.3"
},
"devDependencies": {
"@types/react": "^18.2.64",
@@ -569,6 +570,14 @@
"node": ">= 8"
}
},
+ "node_modules/@remix-run/router": {
+ "version": "1.15.3",
+ "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.15.3.tgz",
+ "integrity": "sha512-Oy8rmScVrVxWZVOpEF57ovlnhpZ8CCPlnIIumVcV9nFdiSIrus99+Lw78ekXyGvVDlIsFJbSfmSovJUhCWYV3w==",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
"node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.13.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.13.0.tgz",
@@ -2373,6 +2382,36 @@
"react": "^18.2.0"
}
},
+ "node_modules/react-router": {
+ "version": "6.22.3",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.22.3.tgz",
+ "integrity": "sha512-dr2eb3Mj5zK2YISHK++foM9w4eBnO23eKnZEDs7c880P6oKbrjz/Svg9+nxqtHQK+oMW4OtjZca0RqPglXxguQ==",
+ "dependencies": {
+ "@remix-run/router": "1.15.3"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8"
+ }
+ },
+ "node_modules/react-router-dom": {
+ "version": "6.22.3",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.22.3.tgz",
+ "integrity": "sha512-7ZILI7HjcE+p31oQvwbokjk6OA/bnFxrhJ19n82Ex9Ph8fNAq+Hm/7KchpMGlTgWhUxRHMMCut+vEtNpWpowKw==",
+ "dependencies": {
+ "@remix-run/router": "1.15.3",
+ "react-router": "6.22.3"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8",
+ "react-dom": ">=16.8"
+ }
+ },
"node_modules/resolve-from": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
diff --git a/frontend/package.json b/frontend/package.json
index c0de196..f3ae3f2 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -11,7 +11,8 @@
},
"dependencies": {
"react": "^18.2.0",
- "react-dom": "^18.2.0"
+ "react-dom": "^18.2.0",
+ "react-router-dom": "^6.22.3"
},
"devDependencies": {
"@types/react": "^18.2.64",
diff --git a/frontend/src/App.css b/frontend/src/App.css
index e69de29..6e19a9f 100644
--- a/frontend/src/App.css
+++ b/frontend/src/App.css
@@ -0,0 +1,14 @@
+.App {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center; /* If you're centering the content */
+ height: 100vh; /* Full height */
+ margin-top: -100px; /* Move up */
+ }
+
+ body {
+ background-color: #0C2D48;
+ font-family: 'Hiragino Sans', 'Hiragino Kaku Gothic ProN', Meiryo, sans-serif;
+ }
+
\ No newline at end of file
diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx
index 8d4280a..570d257 100644
--- a/frontend/src/App.tsx
+++ b/frontend/src/App.tsx
@@ -1,22 +1,21 @@
import './App.css'
+import { BrowserRouter, Routes, Route } from 'react-router-dom';
import MainSearch from './components/MainSearch';
+import Results from './components/Results';
function App() {
-
return (
- <>
-
-

-
-
- >
- )
+
+
+
+
+ } />
+ } />
+
+
+
+ );
}
export default App
diff --git a/frontend/src/components/MainSearch.tsx b/frontend/src/components/MainSearch.tsx
index 2558f8f..70021cf 100644
--- a/frontend/src/components/MainSearch.tsx
+++ b/frontend/src/components/MainSearch.tsx
@@ -1,38 +1,73 @@
-import React from 'react';
+import React, { useState, FormEvent } from 'react';
+import { useNavigate } from 'react-router-dom';
import '../screens/MainScreenWrapper.css';
+interface Filters {
+ professor: string;
+ course: string;
+ topic: string;
+}
+
const MainSearch: React.FC = () => {
+ const [filters, setFilters] = useState({
+ professor: '',
+ course: '',
+ topic: '',
+ });
+
+ const navigate = useNavigate();
+
+ const handleChange = (event: React.ChangeEvent) => {
+ const { name, value } = event.target;
+ setFilters((prevFilters: Filters) => ({
+ ...prevFilters,
+ [name]: value,
+ }));
+ };
+
+ const handleSubmit = (event: React.FormEvent) => {
+ event.preventDefault();
+ var input = filters.toString()
+ const searchParams = new URLSearchParams(input)
+ navigate(`/results?${searchParams}`);
+ };
+
return (
-
+ <>
+
+

+
+
+
+ >
);
}
diff --git a/frontend/src/components/Results.tsx b/frontend/src/components/Results.tsx
new file mode 100644
index 0000000..22e19e2
--- /dev/null
+++ b/frontend/src/components/Results.tsx
@@ -0,0 +1,69 @@
+import React, { useState, useEffect } from 'react';
+import { useLocation, useNavigate } from 'react-router-dom';
+import styles from '../screens/Results.module.css'; // Make sure this path is correct
+
+interface File {
+ id: string;
+ name: string; // do we even use id and name?
+ professor: string;
+ course: string;
+ type?: string; // Assumed type is optional
+ // what other properties to add?semester?
+}
+
+const Results: React.FC = () => {
+ const [files, setFiles] = useState([]);
+ const [isLoading, setLoading] = useState(false);
+ const location = useLocation();
+ const navigate = useNavigate();
+
+ useEffect(() => {
+ const fetchFiles = async () => {
+ setLoading(true);
+ try {
+ // Need to double check this
+ const queryString = location.search; // Includes the '?' prefix
+ const response = await fetch(`/api/path-to-filefilterview${queryString}`);
+ if (!response.ok) {
+ throw new Error(`HTTP error! status: ${response.status}`);
+ }
+ const data = await response.json();
+ setFiles(data);
+ } catch (e) {
+ console.error("Could not fetch files", e);
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ fetchFiles();
+ }, [location]);
+
+ const handleSearchAgain = () => {
+ navigate('/');
+ };
+
+ if (isLoading) return Loading...
;
+
+ return (
+
+
+

+
+
+
+ {isLoading ? (
+
Loading...
+ ) : files.length ? (
+
+ {/* Table structure here */}
+
+ ) : (
+
No results found.
+ )}
+
+
+ );
+};
+
+export default Results;
diff --git a/frontend/src/screens/MainScreenWrapper.css b/frontend/src/screens/MainScreenWrapper.css
index f1d68e6..4c2d85c 100644
--- a/frontend/src/screens/MainScreenWrapper.css
+++ b/frontend/src/screens/MainScreenWrapper.css
@@ -15,9 +15,16 @@ html, body {
justify-content: center;
padding: 20px;
background: #B1D4E0;
+ gap: 15;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1); /* shadow */
}
+
+ .logo {
+ height: 100px; /* Adjust this value as needed */
+ width: auto; /* Keep the logo's aspect ratio */
+ margin-bottom: 15px; /* Gap between logo and search box */
+ }
.filter-item + .filter-item {
margin-top: 20px; /* space between filter items */
diff --git a/frontend/src/screens/Results.module.css b/frontend/src/screens/Results.module.css
new file mode 100644
index 0000000..30223ec
--- /dev/null
+++ b/frontend/src/screens/Results.module.css
@@ -0,0 +1,57 @@
+.wrapper {
+ display: flex;
+ flex-direction: column;
+ height: 100vh;
+ color: #FFFFFF;
+ }
+
+ .header {
+ display: flex;
+ justify-content: space-between;
+ padding: 10px 20px;
+ position: fixed;
+ width: 100%;
+ top: 0;
+ left: 0;
+ background-color: #145DA0;
+ }
+
+ .logo {
+ height: 80px; /* Adjust according to preference */
+ margin-right: auto;
+ }
+
+
+ .resultsContainer {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ padding-top: 100px; /* Adjust based on header height to ensure content doesn't overlap */
+ margin: auto;
+ width: 90%;
+ max-width: 600px;
+ }
+
+ .resultsTable {
+ /* to be filled out */
+ width: 100%;
+ }
+
+
+ .searchAgainButton {
+ height: 50px;
+ padding: 4px 8px;
+ background-color: #0C2D48;
+ color: white;
+ border: none;
+ border-radius: 4px;
+ font-family: 'Hiragino Sans', 'Hiragino Kaku Gothic ProN', Meiryo, sans-serif;
+ cursor: pointer;
+ margin-right: 35px;
+ margin-top: 15px;
+ }
+
+ .searchAgainButton:hover {
+ background-color: #B1D4E0; /* lighter shade for hover effect */
+ }
\ No newline at end of file