diff --git a/App.css b/App.css
new file mode 100644
index 0000000000..c921fb120d
--- /dev/null
+++ b/App.css
@@ -0,0 +1,403 @@
+header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 15px;
+ background-color: #fff;
+ color: #070707;
+ width: 100% !important;
+ position: absolute;
+ z-index: 997;
+}
+h1{
+ text-align: center;
+ font-size: 35px;
+ margin: auto;
+ line-height: 48px;
+ letter-spacing: -.6px;
+ font-weight: bold;
+}
+
+.logo-container {
+ display: flex;
+ margin-left: 10%;
+}
+
+.logo {
+ width: 90px;
+ height: 50px;
+ margin-right: 10px;
+}
+
+.department-name {
+ font-size: 15px;
+ font-weight: bold;
+ color: #090909;
+}
+
+nav ul li a {
+ text-decoration: none;
+ color: #060606;
+ font-weight: bold;
+ font-size: 18px;
+}
+nav ul {
+ list-style: none;
+ display: flex;
+}
+
+nav ul li {
+ margin-right: 20px;
+}
+
+nav ul li a:hover {
+ color:blue;
+}
+
+.landing-container {
+ display: flex;
+}
+
+.landing-content img {
+ max-width: 100%;
+}
+
+.landing-content h2 {
+ color: #333;
+}
+
+.landing-content p {
+ color: #555;
+}
+
+.login-container {
+ max-width: 400px;
+ margin: auto;
+ padding: 20px;
+ border: 1px solid #ccc;
+ border-radius: 5px;
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
+}
+
+.login-form {
+ display: flex;
+ flex-direction: column;
+}
+
+.form-group {
+ margin-bottom: 15px;
+}
+
+label {
+ font-weight: bold;
+ display: block;
+ margin-bottom: 5px;
+}
+
+input {
+ width: 100%;
+ padding: 8px;
+ box-sizing: border-box;
+ border: 1px solid #ccc;
+ border-radius: 3px;
+}
+
+.login-btn {
+ background-color: #4caf50;
+ color: white;
+ padding: 10px;
+ border: none;
+ border-radius: 3px;
+ cursor: pointer;
+}
+
+.login-btn:hover {
+ background-color: #45a049;
+}
+
+.signup-link {
+ margin-top: 15px;
+ text-align: center;
+}
+.pagetitle {
+ text-align: center;
+ margin: 20px 0;
+}
+
+.pagetitle div {
+ display: inline-block;
+ margin: 10px;
+}
+
+.pagetitle h1 {
+ font-size: 36px;
+}
+
+.pagetitle h5, .abouttitle p {
+ font-size: 16px;
+ margin: 5px 0;
+}
+
+.page {
+ margin: 20px 0;
+}
+
+.page h1 {
+ font-size: 28px;
+ margin-bottom: 10px;
+}
+
+.page p {
+ font-size: 16px;
+ line-height: 1.5;
+}
+
+.sidetext1, .sidetext2, .sidetext3, .sidetext4 {
+ font-size: 24px;
+ margin-bottom: 10px;
+}
+
+.image1, .image2, .image3 {
+ max-width: 30%;
+ height: auto;
+ margin-right: 20px;
+ transition: transform 0.3s ease-in-out;
+ align-content: flex-start;
+}
+
+.image1:hover, .image2:hover, .image3:hover {
+ transform: scale(1.1);
+}
+
+.video {
+ max-width: 30%;
+ height: auto;
+ margin-top: 20px;
+}
+.fade-in {
+ opacity: 0;
+ animation: fadeIn ease-in 1;
+ animation-fill-mode: forwards;
+ animation-duration: 1s;
+}
+
+@keyframes fadeIn {
+ 0% {
+ opacity: 0;
+ }
+ 100% {
+ opacity: 1;
+ }
+}
+#cover {
+ width: 90%;
+ height: 300px;
+}
+.body {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ min-height: 100vh;
+ background-image: url(../src/images/im3.jpg);
+ background-repeat: no-repeat;
+ background-position: center;
+ background-size: cover;
+}
+.section1 {
+ position: relative;
+ max-width: 400px;
+ background-color: transparent;
+ border: 2px solid rgba(225, 225, 225, 0.5);
+ border-radius: 20px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ padding: 2rem 3rem;
+}
+.inputbox{
+ position: relative;
+ margin: 30px 0;
+ max-width: 310px;
+ border-bottom: 2px solid #fff;
+}
+.inputbox ion-icon {
+ position: absolute;
+ right: 8px;
+ color: #fff;
+ font-size: 1.2rem;
+ top: 20px;
+}
+.inputbox label {
+ position: absolute;
+ top: 50px;
+ left: 5px;
+ transform: translateY(-50%);
+ color: #fff;
+ font-size: 1rem;
+ pointer-events: none;
+ transition: all 0.5s ease-in-out;
+}
+input:focus ~ label,
+input:valid ~ label {
+ top: -5px;
+}
+.inputbox input {
+ width: 100%;
+ height: 60px;
+ background: transparent;
+ border: none;
+ outline: none;
+ font-size: 1rem;
+ padding: 0 35px 0 5px;
+ color: #fff;
+}
+.forget {
+ margin: 35px 0;
+ font-size: 0.85rem;
+ color: #fff;
+ display: flex;
+ justify-content: space-between;
+}
+.forget label {
+ display: flex;
+ align-items: center;
+}
+.forget label input {
+ margin-right: 3px;
+}
+.forget a {
+ color: #fff;
+ text-decoration: none;
+ font-weight: 600;
+}
+.forget a:hover {
+ text-decoration: underline;
+}
+.head{
+ font-size: 2rem;
+ color: #fff;
+ text-align: center;
+}
+button {
+ width: 100%;
+ height: 40px;
+ border-radius: 40px;
+ background-color: rgb(225, 225, 225, 1);
+ border: none;
+ outline: none;
+ cursor: pointer;
+ font-size: 1rem;
+ font-weight: 600;
+ transition: all 0.4s ease;
+}
+button:hover {
+ background-color: rgb(225, 225, 225, 1);
+}
+.register {
+ font-size: 0.9rem;
+ color: #fff;
+ text-align: center;
+ margin: 25px 0 10px;
+}
+.register p a {
+ text-decoration: none;
+ color: #fff;
+ font-weight: 600;
+}
+.register p a:hover {
+ text-decoration: underline;
+}
+
+body {
+ font-family: 'Arial', sans-serif;
+ background-color: #f5f5f5;
+ color: #333;
+ margin-top: 0;
+ padding: 0;
+}
+
+h1, h2 {
+ color: #007bff;
+}
+
+section {
+ margin-bottom: 20px;
+}
+
+ul {
+ list-style-type: none;
+ padding: 0;
+}
+
+li {
+ margin-bottom: 10px;
+}
+
+strong {
+ color: #333;
+}
+
+form {
+ max-width: 400px;
+ margin: auto;
+}
+
+label {
+ display: block;
+ margin-bottom: 5px;
+}
+
+input[type="text"],
+input[type="email"],
+textarea {
+ width: 100%;
+ padding: 8px;
+ margin-bottom: 10px;
+ box-sizing: border-box;
+}
+
+button {
+ background-color: #007bff;
+ color: #fff;
+ padding: 10px 15px;
+ border: none;
+ cursor: pointer;
+}
+
+button:hover {
+ background-color: #0056b3;
+}
+
+
+body {
+ font-family: 'Arial', sans-serif;
+ background-color: #f5f5f5;
+ color: #333;
+ margin: 0;
+ padding: 0;
+}
+
+h1 {
+ color: #007bff;
+}
+
+ul {
+ list-style-type: none;
+ padding: 0;
+}
+
+li {
+ margin-bottom: 15px;
+}
+
+button {
+ background-color: #007bff;
+ color: #fff;
+ padding: 8px 12px;
+ border: none;
+ cursor: pointer;
+}
+
+button:hover {
+ background-color: #0056b3;
+}
diff --git a/App.js b/App.js
new file mode 100644
index 0000000000..b30d608421
--- /dev/null
+++ b/App.js
@@ -0,0 +1,35 @@
+import React from 'react';
+import './App.css';
+import { BrowserRouter, Route, Routes,} from 'react-router-dom';
+import LandingPage from './pages/LandingPage';
+import LoginPage from './pages/LoginPage';
+import Header from './components/Header';
+import Dashboard from './pages/Dashboard';
+import Homepage from './pages/Homepage';
+import ReportGradePage from './pages/ReportGradePage';
+import InstructorContactPage from './pages/InstructorContact';
+import HelpAndSupport from './pages/HelpAndSupport';
+function App() {
+ return (
+
+
+
+
+
+ } />
+ } />
+ } />
+ }/>
+ } />
+ } />
+ } />
+
+
+
+
+
+
+ );
+}
+
+export default App;
diff --git a/App.test.js b/App.test.js
new file mode 100644
index 0000000000..1f03afeece
--- /dev/null
+++ b/App.test.js
@@ -0,0 +1,8 @@
+import { render, screen } from '@testing-library/react';
+import App from './App';
+
+test('renders learn react link', () => {
+ render( );
+ const linkElement = screen.getByText(/learn react/i);
+ expect(linkElement).toBeInTheDocument();
+});
diff --git a/components/Footer.jsx b/components/Footer.jsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/components/Header.jsx b/components/Header.jsx
new file mode 100644
index 0000000000..50dc91784d
--- /dev/null
+++ b/components/Header.jsx
@@ -0,0 +1,25 @@
+import React from 'react';
+import logo from '../images/cslogo.png';
+
+function Header() {
+ return (
+
+
+
+
DEPARTMENT OF COMPUTER SCIENCE
+
+
+
+
+
+ );
+}
+
+export default Header;
diff --git a/components/Sidebar.jsx b/components/Sidebar.jsx
new file mode 100644
index 0000000000..d783664dd4
--- /dev/null
+++ b/components/Sidebar.jsx
@@ -0,0 +1,75 @@
+import React, { useEffect } from 'react';
+import { Helmet } from 'react-helmet-async';
+
+function Sidebar() {
+ useEffect(() => {
+ const scriptModule = document.createElement('script');
+ scriptModule.type = 'module';
+ scriptModule.src = 'https://unpkg.com/ionicons@7.1.0/dist/ionicons/ionicons.esm.js';
+
+ const scriptNoModule = document.createElement('script');
+ scriptNoModule.setAttribute('nomodule', '');
+ scriptNoModule.src = 'https://unpkg.com/ionicons@7.1.0/dist/ionicons/ionicons.esm.js';
+
+ document.head.appendChild(scriptModule);
+ document.head.appendChild(scriptNoModule);
+
+ return () => {
+ document.head.removeChild(scriptModule);
+ document.head.removeChild(scriptNoModule);
+ };
+ }, []);
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default Sidebar;
diff --git a/images/cslogo.png b/images/cslogo.png
new file mode 100644
index 0000000000..e503259ff9
Binary files /dev/null and b/images/cslogo.png differ
diff --git a/images/im3.jpg b/images/im3.jpg
new file mode 100644
index 0000000000..cd6df715d3
Binary files /dev/null and b/images/im3.jpg differ
diff --git a/images/logo5.png b/images/logo5.png
new file mode 100644
index 0000000000..74c7f077ae
Binary files /dev/null and b/images/logo5.png differ
diff --git a/index.css b/index.css
new file mode 100644
index 0000000000..17df0e7ec7
--- /dev/null
+++ b/index.css
@@ -0,0 +1,17 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+body {
+ margin: 0;
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
+ 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
+ sans-serif;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+code {
+ font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
+ monospace;
+}
diff --git a/index.js b/index.js
new file mode 100644
index 0000000000..d563c0fb10
--- /dev/null
+++ b/index.js
@@ -0,0 +1,17 @@
+import React from 'react';
+import ReactDOM from 'react-dom/client';
+import './index.css';
+import App from './App';
+import reportWebVitals from './reportWebVitals';
+
+const root = ReactDOM.createRoot(document.getElementById('root'));
+root.render(
+
+
+
+);
+
+// If you want to start measuring performance in your app, pass a function
+// to log results (for example: reportWebVitals(console.log))
+// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
+reportWebVitals();
diff --git a/logo.svg b/logo.svg
new file mode 100644
index 0000000000..9dfc1c058c
--- /dev/null
+++ b/logo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/pages/Dashboard.jsx b/pages/Dashboard.jsx
new file mode 100644
index 0000000000..0585060643
--- /dev/null
+++ b/pages/Dashboard.jsx
@@ -0,0 +1,145 @@
+import React, { useState } from 'react';
+
+const Dashboard = () => {
+ const [selectedYear, setSelectedYear] = useState(null);
+
+ const handleYearChange = (year) => {
+ setSelectedYear(year);
+ };
+
+ const GPABox = () => (
+
+ );
+
+ const SubjectsAndGrades = ({ year }) => {
+ const semesters = ['Semester 1', 'Semester 2'];
+
+ const level100Courses = [
+ 'UGRC 150 Critical Thinking and Practical Reasoning',
+ 'MATH 121 Algebra and Trigonometry',
+ 'MATH 123 Vectors and Geometry',
+ 'DCIT 101 Introduction to Computer Science',
+ 'DCIT 103 Office Productivity Tools',
+ 'STAT 111 Introduction to Statistics and Probability I',
+ ];
+
+ const level200Courses = [
+ 'UGRC 110 Academic Writing I',
+ 'UGRC 131-136 Understanding Human Society',
+ 'MATH 122 Calculus I',
+ 'MATH 126 Algebra and Geometry',
+ 'STAT 112 Introduction to Statistics and Probability II',
+ 'DCIT 104 Programming',
+ 'DCIT 102 Computer Hardware Fund. and Circuits',
+ ];
+
+ const level300Courses = [
+ 'UGRC 210 Academic Writing II',
+ 'DCIT 201 Programming I',
+ 'DCIT 203 Digital and Logic Systems Design',
+ 'DCIT 205 Multi Media and Web Design',
+ 'DCIT 207 Computer Architecture & Organisation',
+ 'DCIT 209 E-Business Architectures',
+ ];
+
+ const level400Courses = [
+ 'UGRC 220 Introduction to African Studies',
+ 'DCIT 202 Mobile Application Development',
+ 'DCIT 204 Data Structures & Algorithm I',
+ 'DCIT 206 Systems Administration',
+ 'DCIT 208 Software Engineering',
+ 'DCIT 212 Numerical and Computational Methods',
+ ];
+
+ return (
+
+
+
+
{`Year ${year} Subjects and Grades`}
+ {semesters.map((semester, index) => (
+
+
{semester}
+
+
+
+ Course
+ Grade
+
+
+
+ {year === '100' && level100Courses.map((course, i) => (
+
+ {course}
+ A
+
+ ))}
+ {year === '200' && level200Courses.map((course, i) => (
+
+ {course}
+ B
+
+ ))}
+ {year === '300' && level300Courses.map((course, i) => (
+
+ {course}
+ B+
+
+ ))}
+ {year === '400' && level400Courses.map((course, i) => (
+
+ {course}
+ A
+
+ ))}
+
+
+
Total CGPA: {3.6}
+
+ ))}
+
+
+
+
+
+ );
+ };
+
+ const LineChart = () => (
+
+
Grade Progress Chart
+
Chart for grades
+
+ );
+
+ return (
+
+
Student Dashboard
+
+
Grade Report
+
+
+ Select Year:
+
+ handleYearChange(e.target.value)}
+ className="p-2 border border-gray-300 rounded"
+ >
+
+ Select Year
+ Year 100
+ Year 200
+ Year 300
+ Year 400
+
+
+ {selectedYear &&
}
+
+
+ );
+};
+
+export default Dashboard;
diff --git a/pages/HelpAndSupport.jsx b/pages/HelpAndSupport.jsx
new file mode 100644
index 0000000000..fcad73d2a4
--- /dev/null
+++ b/pages/HelpAndSupport.jsx
@@ -0,0 +1,54 @@
+import React from 'react';
+
+const HelpAndSupport= () => {
+ const faqItems = [
+ { id: 1, question: 'How to report a missing grade?', answer: 'Lorem ipsum dolor sit amet, ...' },
+ { id: 2, question: 'How can I contact technical support?', answer: 'Lorem ipsum dolor sit amet, ...' },
+ ];
+
+ const submitSupportRequest = (formData) => {
+ console.log('Submitting support request:', formData);
+ };
+
+ return (
+
+
Help and Support Page
+
+ Frequently Asked Questions
+
+ {faqItems.map((faq) => (
+
+ {faq.question}
+ {faq.answer}
+
+ ))}
+
+
+
+ Contact Technical Support
+
+
+
+ );
+};
+
+export default HelpAndSupport;
diff --git a/pages/Homepage.jsx b/pages/Homepage.jsx
new file mode 100644
index 0000000000..d5d7eb7b2d
--- /dev/null
+++ b/pages/Homepage.jsx
@@ -0,0 +1,21 @@
+import React from 'react';
+import UniversityLogo from '../images/logo5.png';
+
+const HomePage = () => {
+ return (
+
+
+
Welcome to the University of Ghana
+
Empowering Minds, Transforming Lives
+
+
Explore our innovative programs and services.
+
+
+ );
+};
+
+export default HomePage;
diff --git a/pages/InstructorContact.jsx b/pages/InstructorContact.jsx
new file mode 100644
index 0000000000..708880807d
--- /dev/null
+++ b/pages/InstructorContact.jsx
@@ -0,0 +1,38 @@
+import React from 'react';
+
+const InstructorContactPage = () => {
+ const instructors = [
+ { id: 1, name: 'John Doe', email: 'john.doe@example.com' },
+ { id: 2, name: 'Jane Smith', email: 'jane.smith@example.com' },
+ ];
+
+ const sendEmail = (instructor) => {
+ console.log(`Sending email to ${instructor.name} at ${instructor.email}`);
+ };
+
+ return (
+
+
Instructor Contact Page
+
+ {instructors.map((instructor) => (
+
+
+
+
{instructor.name}
+
{instructor.email}
+
+
sendEmail(instructor)}
+ className="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600"
+ >
+ Send Email
+
+
+
+ ))}
+
+
+ );
+};
+
+export default InstructorContactPage;
diff --git a/pages/LandingPage.jsx b/pages/LandingPage.jsx
new file mode 100644
index 0000000000..74142c8bf7
--- /dev/null
+++ b/pages/LandingPage.jsx
@@ -0,0 +1,27 @@
+import React from 'react';
+import backgroundImage from '../images/im3.jpg';
+
+function LandingPage() {
+ return (
+
+
+
+
+
+
+ Welcome to the University of Ghana Grade report website.
+
+
+ This platform allows students and staff of the University of Ghana to access their grade reports easily, without having to go through a long process of booking appointments with the academic office.
+
+
+ Click here to Login
+
+
+
+
+
+ );
+}
+
+export default LandingPage;
diff --git a/pages/LoginPage.jsx b/pages/LoginPage.jsx
new file mode 100644
index 0000000000..5592de74ec
--- /dev/null
+++ b/pages/LoginPage.jsx
@@ -0,0 +1,75 @@
+import React, { useState } from 'react';
+import { useNavigate } from 'react-router-dom';
+
+const LoginPage = () => {
+ const [formData, setFormData] = useState({
+ studentId: '',
+ pin: '',
+ });
+
+ const navigate = useNavigate();
+
+ const handleChange = (e) => {
+ const { name, value } = e.target;
+ setFormData({ ...formData, [name]: value });
+ };
+
+ const handleSubmit = (e) => {
+ e.preventDefault();
+
+ if (formData.studentId && formData.pin) {
+ console.log('Logging in with:', formData);
+ navigate('/dashboard');
+ } else {
+ console.log('Please enter both Student ID and Password');
+ }
+ };
+
+ return (
+
+ );
+};
+
+export default LoginPage;
diff --git a/pages/MissingGradeForm.jsx b/pages/MissingGradeForm.jsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/pages/ReportGradePage.jsx b/pages/ReportGradePage.jsx
new file mode 100644
index 0000000000..6dc2d1659f
--- /dev/null
+++ b/pages/ReportGradePage.jsx
@@ -0,0 +1,107 @@
+import React, { useState } from 'react';
+
+const ReportGradePage = () => {
+ const [formData, setFormData] = useState({
+ course: '',
+ grade: '',
+ lecturer: '',
+ comment: '',
+ });
+
+ const handleChange = (e) => {
+ const { name, value } = e.target;
+ setFormData({ ...formData, [name]: value });
+ };
+
+ const handleSubmit = (e) => {
+ e.preventDefault();
+ console.log('Reporting Grade:', formData);
+ setFormData({
+ course: '',
+ grade: '',
+ lecturer: '',
+ comment: '',
+ });
+ };
+
+ const pageStyle = {
+ backgroundImage: 'url("../images/im3.jpg")',
+ backgroundSize: 'cover',
+ backgroundPosition: 'center',
+ minHeight: '100vh',
+ display: 'flex',
+ flexDirection: 'column',
+ alignItems: 'center',
+ justifyContent: 'center',
+ };
+
+ return (
+
+ );
+};
+
+export default ReportGradePage;
diff --git a/reportWebVitals.js b/reportWebVitals.js
new file mode 100644
index 0000000000..5253d3ad9e
--- /dev/null
+++ b/reportWebVitals.js
@@ -0,0 +1,13 @@
+const reportWebVitals = onPerfEntry => {
+ if (onPerfEntry && onPerfEntry instanceof Function) {
+ import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
+ getCLS(onPerfEntry);
+ getFID(onPerfEntry);
+ getFCP(onPerfEntry);
+ getLCP(onPerfEntry);
+ getTTFB(onPerfEntry);
+ });
+ }
+};
+
+export default reportWebVitals;
diff --git a/setupTests.js b/setupTests.js
new file mode 100644
index 0000000000..8f2609b7b3
--- /dev/null
+++ b/setupTests.js
@@ -0,0 +1,5 @@
+// jest-dom adds custom jest matchers for asserting on DOM nodes.
+// allows you to do things like:
+// expect(element).toHaveTextContent(/react/i)
+// learn more: https://github.com/testing-library/jest-dom
+import '@testing-library/jest-dom';