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 ( +
+
+ University Logo + 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 ( +
+
+ dots +
+
+ +
+ + + +
+ ); +} + +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 = () => ( +
+

Current GPA

+

3.9

+
+ ); + + 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}

+ + + + + + + + + {year === '100' && level100Courses.map((course, i) => ( + + + + + ))} + {year === '200' && level200Courses.map((course, i) => ( + + + + + ))} + {year === '300' && level300Courses.map((course, i) => ( + + + + + ))} + {year === '400' && level400Courses.map((course, i) => ( + + + + + ))} + +
CourseGrade
{course}A
{course}B
{course}B+
{course}A
+

Total CGPA: {3.6}

+
+ ))} +
+
+
+ + + ); + }; + + const LineChart = () => ( +
+

Grade Progress Chart

+
Chart for grades
+
+ ); + + return ( +
+

Student Dashboard

+ +

Grade Report

+
+ + +
+ {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

+
{ + e.preventDefault(); + submitSupportRequest({ /* Form data */ }); + }} + > + + +
+ + + + ); +}; + +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';