second screen draft

This commit is contained in:
Sahej Panag
2024-04-12 15:23:40 -04:00
parent 78988ed5ce
commit 443bc2e13e
8 changed files with 246 additions and 25 deletions

View File

@@ -9,7 +9,8 @@
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0" "react-dom": "^18.2.0",
"react-router-dom": "^6.22.3"
}, },
"devDependencies": { "devDependencies": {
"@types/react": "^18.2.64", "@types/react": "^18.2.64",
@@ -569,6 +570,14 @@
"node": ">= 8" "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": { "node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.13.0", "version": "4.13.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.13.0.tgz", "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" "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": { "node_modules/resolve-from": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",

View File

@@ -11,7 +11,8 @@
}, },
"dependencies": { "dependencies": {
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0" "react-dom": "^18.2.0",
"react-router-dom": "^6.22.3"
}, },
"devDependencies": { "devDependencies": {
"@types/react": "^18.2.64", "@types/react": "^18.2.64",

View File

@@ -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;
}

View File

@@ -1,22 +1,21 @@
import './App.css' import './App.css'
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import MainSearch from './components/MainSearch'; import MainSearch from './components/MainSearch';
import Results from './components/Results';
function App() { function App() {
return ( return (
<> <BrowserRouter>
<div className="App" style={{ display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'center', height: '100vh' , gap: 15}}> <div className="App">
<img <header style={{ display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'center', height: '100px', gap: 15 }}>
src="/PeerNotes.png" </header>
alt="PeerNotes Logo" <Routes>
style={{ <Route path="/" element={<MainSearch />} />
height: "100px" <Route path="/results" element={<Results />} />
}} </Routes>
/> </div>
<MainSearch /> </BrowserRouter>
</div> );
</>
)
} }
export default App export default App

View File

@@ -1,38 +1,73 @@
import React from 'react'; import React, { useState, FormEvent } from 'react';
import { useNavigate } from 'react-router-dom';
import '../screens/MainScreenWrapper.css'; import '../screens/MainScreenWrapper.css';
interface Filters {
professor: string;
course: string;
topic: string;
}
const MainSearch: React.FC = () => { const MainSearch: React.FC = () => {
const [filters, setFilters] = useState<Filters>({
professor: '',
course: '',
topic: '',
});
const navigate = useNavigate();
const handleChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
const { name, value } = event.target;
setFilters((prevFilters: Filters) => ({
...prevFilters,
[name]: value,
}));
};
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
var input = filters.toString()
const searchParams = new URLSearchParams(input)
navigate(`/results?${searchParams}`);
};
return ( return (
<div className="filter-container"> <>
<div style={{ textAlign: 'center' }}>
<img src="/PeerNotes.png" alt="PeerNotes Logo" className="logo" />
</div>
<form onSubmit={handleSubmit} className="filter-container">
<div className="filter-item"> <div className="filter-item">
<label htmlFor="professors">Professors:</label> <label htmlFor="professors">Professors:</label>
<select id="professors"> <select id="professors" name="professor" value={filters.professor} onChange={handleChange}>
<option value="">Select a Professor</option> <option value="">Select a Professor</option>
{/* temporary */} {/* temporary options */}
<option value="professor1">Professor 1</option> <option value="professor1">Professor 1</option>
<option value="professor2">Professor 2</option> <option value="professor2">Professor 2</option>
</select> </select>
</div> </div>
<div className="filter-item"> <div className="filter-item">
<label htmlFor="courses">Course:</label> <label htmlFor="courses">Course:</label>
<select id="courses"> <select id="courses" name="course" value={filters.course} onChange={handleChange}>
<option value="">Select a Course</option> <option value="">Select a Course</option>
{/* temporary */} {/* temporary options */}
<option value="course1">Course 1</option> <option value="course1">Course 1</option>
<option value="course2">Course 2</option> <option value="course2">Course 2</option>
</select> </select>
</div> </div>
<div className="filter-item"> <div className="filter-item">
<label htmlFor="topics">Topic:</label> <label htmlFor="topics">Topic:</label>
<select id="topics"> <select id="topics" name="topic" value={filters.topic} onChange={handleChange}>
<option value="">Select a Topic</option> <option value="">Select a Topic</option>
{/* temporary */} {/* temporary options */}
<option value="topic1">Topic 1</option> <option value="topic1">Topic 1</option>
<option value="topic2">Topic 2</option> <option value="topic2">Topic 2</option>
</select> </select>
</div> </div>
<button type="submit" className="submit-button">Submit</button> <button type="submit" className="submit-button">Submit</button>
</div> </form>
</>
); );
} }

View File

@@ -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<File[]>([]);
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 <div>Loading...</div>;
return (
<div className={styles.wrapper}>
<div className={styles.header}>
<img src="/PeerNotes.png" alt="PeerNotes Logo" className={styles.logo} />
<button onClick={handleSearchAgain} className={styles.searchAgainButton}>Search Again</button>
</div>
<div className={styles.resultsContainer}>
{isLoading ? (
<p>Loading...</p>
) : files.length ? (
<table className={styles.resultsTable}>
{/* Table structure here */}
</table>
) : (
<p>No results found.</p>
)}
</div>
</div>
);
};
export default Results;

View File

@@ -15,9 +15,16 @@ html, body {
justify-content: center; justify-content: center;
padding: 20px; padding: 20px;
background: #B1D4E0; background: #B1D4E0;
gap: 15;
border-radius: 8px; border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1); /* shadow */ 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 { .filter-item + .filter-item {
margin-top: 20px; /* space between filter items */ margin-top: 20px; /* space between filter items */

View File

@@ -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 */
}