From c6991a4f637a2db2e9603c161abf92cde25af9aa Mon Sep 17 00:00:00 2001 From: NosheenSahrish Date: Tue, 10 Jun 2025 10:33:35 +0200 Subject: [PATCH 01/20] changed to direct axios call instead of apiservice import --- .../courses/course/AssignmentSubmission.jsx | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/pages/courses/course/AssignmentSubmission.jsx b/src/pages/courses/course/AssignmentSubmission.jsx index f0ef106..197a7ff 100644 --- a/src/pages/courses/course/AssignmentSubmission.jsx +++ b/src/pages/courses/course/AssignmentSubmission.jsx @@ -5,7 +5,7 @@ import axios from "axios"; import { useSelector } from "react-redux"; import { themeConfig } from "../../../themeConfig"; import { iconColors } from "../../../utils/styles"; -import {getAssignmentsByCourse, createAssignment, submitAssignment, getSubmissionsByStudent, getSubmissionsByAssignment, updateAssignment, deleteAssignment} from '../../../services/api'; + const AssignmentSubmission = () => { const {courseId, assignmentId} = useParams(); @@ -96,7 +96,7 @@ const AssignmentSubmission = () => { const fetchAssignments = async () => { setLoading(true); try { - const response = await getAssignmentsByCourse(courseId); + const response = await axios.get(`http://localhost:8080/api/courses/${courseId}/assignments`); setAssignments(response.data); if (userRole === 'STUDENT' && studentId) { @@ -113,7 +113,7 @@ const AssignmentSubmission = () => { const fetchSubmissions = async () => { try { - const response = await getSubmissionsByStudent(courseId, studentId); + const response = await axios.get(`http://localhost:8080/api/courses/${courseId}/submissions/student/${studentId}`); setSubmissions(response.data); if (assignmentId) { @@ -147,7 +147,7 @@ const AssignmentSubmission = () => { const fetchCourseSubmissions = async () => { try { if (assignmentId) { - const response = await getSubmissionsByAssignment(courseId, assignmentId); + const response = await axios.get(`http://localhost:8080/api/courses/${courseId}/submissions/${assignmentId}/submissions`); setCourseSubmissions(response.data); } else { setCourseSubmissions([]); @@ -192,7 +192,18 @@ const AssignmentSubmission = () => { return; } - await submitAssignment(courseId, assignmentId, studentId, file); + // CHANGED: Direct axios call instead of API service + const formData = new FormData(); + formData.append('file', file); + + await axios.post( + `http://localhost:8080/api/courses/${courseId}/submissions/${assignmentId}/student/${studentId}`, + formData, + { + headers: { 'Content-Type': 'multipart/form-data' } + } + ); + alert('Assignment submitted successfully!'); setSubmissionData(prev => ({ @@ -245,7 +256,7 @@ const AssignmentSubmission = () => { e.preventDefault(); try { - await createAssignment(courseId, newAssignment); + await axios.post(`http://localhost:8080/api/courses/${courseId}/assignments`, newAssignment); alert('Assignment created successfully!'); setNewAssignment({courseId: courseId, title: '', description: '', dueDate: ''}); fetchAssignments(); @@ -274,7 +285,7 @@ const AssignmentSubmission = () => { e.preventDefault(); try { - await updateAssignment(editAssignment.courseId, editAssignment.id, newAssignment); + await axios.put(`http://localhost:8080/api/courses/${editAssignment.courseId}/assignments/${editAssignment.id}`, newAssignment); alert('Assignment updated successfully!'); setNewAssignment({courseId: courseId, title: '', description: '', dueDate: ''}); setEditAssignment(null); @@ -287,7 +298,7 @@ const AssignmentSubmission = () => { const handleDeleteAssignment = async (assignmentId) => { try { - await deleteAssignment(courseId, assignmentId); + await axios.delete(`http://localhost:8080/api/courses/${courseId}/assignments/${assignmentId}`); alert('Assignment deleted successfully!'); setShowDeleteConfirm(null); fetchAssignments(); From 7ff33ca7df4e7a620f46bd9b43ed949647af638c Mon Sep 17 00:00:00 2001 From: NosheenSahrish Date: Tue, 10 Jun 2025 10:43:14 +0200 Subject: [PATCH 02/20] code is working now after changes in assignmentsubmission --- src/pages/courses/course/AssignmentSubmission.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/courses/course/AssignmentSubmission.jsx b/src/pages/courses/course/AssignmentSubmission.jsx index 197a7ff..2cc97dc 100644 --- a/src/pages/courses/course/AssignmentSubmission.jsx +++ b/src/pages/courses/course/AssignmentSubmission.jsx @@ -192,7 +192,6 @@ const AssignmentSubmission = () => { return; } - // CHANGED: Direct axios call instead of API service const formData = new FormData(); formData.append('file', file); From d8fdfe898f6f39b5a02d8b69c7f0293601e30b7c Mon Sep 17 00:00:00 2001 From: Lidizz Date: Tue, 10 Jun 2025 11:49:07 +0200 Subject: [PATCH 03/20] added newer assignment sub version --- .../courses/course/AssignmentSubmission.jsx | 26 +++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/pages/courses/course/AssignmentSubmission.jsx b/src/pages/courses/course/AssignmentSubmission.jsx index f0ef106..2cc97dc 100644 --- a/src/pages/courses/course/AssignmentSubmission.jsx +++ b/src/pages/courses/course/AssignmentSubmission.jsx @@ -5,7 +5,7 @@ import axios from "axios"; import { useSelector } from "react-redux"; import { themeConfig } from "../../../themeConfig"; import { iconColors } from "../../../utils/styles"; -import {getAssignmentsByCourse, createAssignment, submitAssignment, getSubmissionsByStudent, getSubmissionsByAssignment, updateAssignment, deleteAssignment} from '../../../services/api'; + const AssignmentSubmission = () => { const {courseId, assignmentId} = useParams(); @@ -96,7 +96,7 @@ const AssignmentSubmission = () => { const fetchAssignments = async () => { setLoading(true); try { - const response = await getAssignmentsByCourse(courseId); + const response = await axios.get(`http://localhost:8080/api/courses/${courseId}/assignments`); setAssignments(response.data); if (userRole === 'STUDENT' && studentId) { @@ -113,7 +113,7 @@ const AssignmentSubmission = () => { const fetchSubmissions = async () => { try { - const response = await getSubmissionsByStudent(courseId, studentId); + const response = await axios.get(`http://localhost:8080/api/courses/${courseId}/submissions/student/${studentId}`); setSubmissions(response.data); if (assignmentId) { @@ -147,7 +147,7 @@ const AssignmentSubmission = () => { const fetchCourseSubmissions = async () => { try { if (assignmentId) { - const response = await getSubmissionsByAssignment(courseId, assignmentId); + const response = await axios.get(`http://localhost:8080/api/courses/${courseId}/submissions/${assignmentId}/submissions`); setCourseSubmissions(response.data); } else { setCourseSubmissions([]); @@ -192,7 +192,17 @@ const AssignmentSubmission = () => { return; } - await submitAssignment(courseId, assignmentId, studentId, file); + const formData = new FormData(); + formData.append('file', file); + + await axios.post( + `http://localhost:8080/api/courses/${courseId}/submissions/${assignmentId}/student/${studentId}`, + formData, + { + headers: { 'Content-Type': 'multipart/form-data' } + } + ); + alert('Assignment submitted successfully!'); setSubmissionData(prev => ({ @@ -245,7 +255,7 @@ const AssignmentSubmission = () => { e.preventDefault(); try { - await createAssignment(courseId, newAssignment); + await axios.post(`http://localhost:8080/api/courses/${courseId}/assignments`, newAssignment); alert('Assignment created successfully!'); setNewAssignment({courseId: courseId, title: '', description: '', dueDate: ''}); fetchAssignments(); @@ -274,7 +284,7 @@ const AssignmentSubmission = () => { e.preventDefault(); try { - await updateAssignment(editAssignment.courseId, editAssignment.id, newAssignment); + await axios.put(`http://localhost:8080/api/courses/${editAssignment.courseId}/assignments/${editAssignment.id}`, newAssignment); alert('Assignment updated successfully!'); setNewAssignment({courseId: courseId, title: '', description: '', dueDate: ''}); setEditAssignment(null); @@ -287,7 +297,7 @@ const AssignmentSubmission = () => { const handleDeleteAssignment = async (assignmentId) => { try { - await deleteAssignment(courseId, assignmentId); + await axios.delete(`http://localhost:8080/api/courses/${courseId}/assignments/${assignmentId}`); alert('Assignment deleted successfully!'); setShowDeleteConfirm(null); fetchAssignments(); From 4ec8691bf236afccba2f56b39e527db5e1429950 Mon Sep 17 00:00:00 2001 From: Lidizz Date: Tue, 10 Jun 2025 11:54:56 +0200 Subject: [PATCH 04/20] removed base url from login and signup and edited assignment sub --- src/pages/Login.jsx | 3 +-- src/pages/Signup.jsx | 3 +-- src/pages/courses/course/AssignmentSubmission.jsx | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/pages/Login.jsx b/src/pages/Login.jsx index 910bbcb..382d5c9 100644 --- a/src/pages/Login.jsx +++ b/src/pages/Login.jsx @@ -3,7 +3,6 @@ import axios from 'axios'; import { useNavigate, Link } from 'react-router-dom'; import { useSelector } from 'react-redux'; import { Eye, EyeOff } from 'lucide-react'; -import { API_BASE_URL } from '../config'; import {themeConfig} from "../themeConfig.js"; import {iconColors} from "../utils/styles.js"; @@ -25,7 +24,7 @@ const Login = () => { e.preventDefault(); setError(''); try { - const response = await axios.post(`${API_BASE_URL}/login`, formData); + const response = await axios.post(`http://localhost:8080/api/users/login`, formData); localStorage.setItem('user', JSON.stringify(response.data)); navigate('/dashboard'); } catch (err) { diff --git a/src/pages/Signup.jsx b/src/pages/Signup.jsx index 1c95667..0268029 100644 --- a/src/pages/Signup.jsx +++ b/src/pages/Signup.jsx @@ -4,7 +4,6 @@ import { useNavigate, Link } from 'react-router-dom'; import { useSelector } from 'react-redux'; import { Eye, EyeOff } from 'lucide-react'; import { iconColors } from '../utils/styles'; -import { API_BASE_URL } from '../config'; import {themeConfig} from "../themeConfig.js"; const Signup = () => { @@ -30,7 +29,7 @@ const Signup = () => { return; } try { - await axios.post(`${API_BASE_URL}/register`, { + await axios.post(`http://localhost:8080/api/users/register`, { email: formData.email, firstName: formData.firstName, lastName: formData.lastName, diff --git a/src/pages/courses/course/AssignmentSubmission.jsx b/src/pages/courses/course/AssignmentSubmission.jsx index 2cc97dc..7dfd77f 100644 --- a/src/pages/courses/course/AssignmentSubmission.jsx +++ b/src/pages/courses/course/AssignmentSubmission.jsx @@ -888,7 +888,7 @@ const AssignmentSubmission = () => { className={`w-full px-3 py-2 border ${border} rounded-md ${ theme === "light" ? "bg-white" : "bg-gray-800" } ${text} focus:outline-none focus:ring-2 focus:ring-purple-500`} - placeholder="Enter grade (e.g., A, B+, 85, etc.)" + placeholder="Enter grade (A, B, C, D, E, F)" /> From 7c88c0d2dc87ed51dc4c1b77b80fd3a4e0a8668d Mon Sep 17 00:00:00 2001 From: Lidizz Date: Tue, 10 Jun 2025 12:47:56 +0200 Subject: [PATCH 05/20] fix buttons for module editing --- src/components/DashboardCard.jsx | 10 +++-- src/config.js | 2 +- .../courses/course/AssignmentSubmission.jsx | 2 +- src/pages/courses/course/ModulesCreate.jsx | 2 +- src/pages/courses/course/ModulesEdit.jsx | 37 ++++++++++--------- src/services/api.js | 3 +- 6 files changed, 31 insertions(+), 25 deletions(-) diff --git a/src/components/DashboardCard.jsx b/src/components/DashboardCard.jsx index fbc683b..a9a9413 100644 --- a/src/components/DashboardCard.jsx +++ b/src/components/DashboardCard.jsx @@ -5,15 +5,17 @@ import {themeConfig} from "../themeConfig.js"; const DashboardCard = () => { const { theme } = useSelector((state) => state.theme); const { bg, text, border } = themeConfig[theme]; + const subjects = [ - { title: "APP200", endDate: "2025-06-12" }, + { title: "APP2000", endDate: "2025-06-12" }, { title: "DAT2000", endDate: "2025-05-31" }, { title: "OBJ2100", endDate: "2025-06-23" }, ]; + return (
- {subjects.map((subject) => ( -
+ {subjects.map((subject, index) => ( +

{subject.title}

End Date: {subject.endDate}

@@ -22,4 +24,4 @@ const DashboardCard = () => { ); }; -export default DashboardCard; \ No newline at end of file +export default DashboardCard; diff --git a/src/config.js b/src/config.js index b0593b7..0bd83c8 100644 --- a/src/config.js +++ b/src/config.js @@ -1 +1 @@ -export const API_BASE_URL = 'http://localhost:8080/api/users'; \ No newline at end of file +// export const API_BASE_URL = 'http://localhost:8080/api/users'; \ No newline at end of file diff --git a/src/pages/courses/course/AssignmentSubmission.jsx b/src/pages/courses/course/AssignmentSubmission.jsx index 7dfd77f..0292755 100644 --- a/src/pages/courses/course/AssignmentSubmission.jsx +++ b/src/pages/courses/course/AssignmentSubmission.jsx @@ -929,4 +929,4 @@ const AssignmentSubmission = () => { ); }; -export default AssignmentSubmission; \ No newline at end of file +export default AssignmentSubmission; diff --git a/src/pages/courses/course/ModulesCreate.jsx b/src/pages/courses/course/ModulesCreate.jsx index 96a1feb..8cdca65 100644 --- a/src/pages/courses/course/ModulesCreate.jsx +++ b/src/pages/courses/course/ModulesCreate.jsx @@ -79,4 +79,4 @@ const ModulesCreate = () => { ); }; -export default ModulesCreate; \ No newline at end of file +export default ModulesCreate; diff --git a/src/pages/courses/course/ModulesEdit.jsx b/src/pages/courses/course/ModulesEdit.jsx index c3b09e2..a089171 100644 --- a/src/pages/courses/course/ModulesEdit.jsx +++ b/src/pages/courses/course/ModulesEdit.jsx @@ -1,26 +1,26 @@ import React, {useEffect} from 'react'; -import { useNavigate, useParams } from 'react-router-dom'; +import {useNavigate, useParams} from 'react-router-dom'; import axios from 'axios'; -import { ArrowLeft } from 'lucide-react'; -import { useSelector } from 'react-redux'; -import { themeConfig } from '../../../themeConfig'; -import { iconColors } from '../../../utils/styles'; +import {ArrowLeft} from 'lucide-react'; +import {useSelector} from 'react-redux'; +import {themeConfig} from '../../../themeConfig'; +import {iconColors} from '../../../utils/styles'; const ModulesEdit = () => { - const { courseId } = useParams(); + const {courseId} = useParams(); const navigate = useNavigate(); - const { theme } = useSelector((state) => state.theme); - const { bg, text, accentBg, border } = themeConfig[theme]; + const {theme} = useSelector((state) => state.theme); + const {bg, text, accentBg, border} = themeConfig[theme]; const [title, setTitle] = React.useState(''); const [description, setDescription] = React.useState(''); const [moduleNumber, setModuleNumber] = React.useState(''); const [resourceId, setResourceId] = React.useState(''); const [message, setMessage] = React.useState(''); const [error, setError] = React.useState(''); - const { moduleId } = useParams(); + const {moduleId} = useParams(); const [type, setType] = React.useState('update'); - console.log(moduleId); + // console.log(moduleId); useEffect(() => { if (!moduleId) return; @@ -99,9 +99,9 @@ const ModulesEdit = () => { > - + Back to Modules @@ -126,14 +126,14 @@ const ModulesEdit = () => { @@ -154,7 +154,8 @@ const ModulesEdit = () => { />
- + { />
- + { {type && (
- +
)} diff --git a/src/services/api.js b/src/services/api.js index ca8b730..0d24642 100644 --- a/src/services/api.js +++ b/src/services/api.js @@ -1,5 +1,6 @@ import axios from 'axios'; -import { API_BASE_URL } from '../config'; + +const API_BASE_URL = 'http://localhost:8080/api'; const api = axios.create({ baseURL: API_BASE_URL, From 9760eb7e392053691f8a2b6194919897d2cd4236 Mon Sep 17 00:00:00 2001 From: Lidizz Date: Tue, 10 Jun 2025 13:42:56 +0200 Subject: [PATCH 06/20] refactored CourseCreate, Grid and Dashboard --- src/pages/Dashboard.jsx | 2 +- src/pages/courses/CourseGrid.jsx | 5 +- src/pages/courses/course/CourseCreate.jsx | 74 ++++++++++++++++++----- 3 files changed, 61 insertions(+), 20 deletions(-) diff --git a/src/pages/Dashboard.jsx b/src/pages/Dashboard.jsx index f25a752..83e2d9f 100644 --- a/src/pages/Dashboard.jsx +++ b/src/pages/Dashboard.jsx @@ -15,4 +15,4 @@ const Dashboard = () => { ); }; -export default Dashboard; \ No newline at end of file +export default Dashboard; diff --git a/src/pages/courses/CourseGrid.jsx b/src/pages/courses/CourseGrid.jsx index efc93e6..21e1ae4 100644 --- a/src/pages/courses/CourseGrid.jsx +++ b/src/pages/courses/CourseGrid.jsx @@ -14,7 +14,7 @@ const CourseGrid = () => { const userId = user?.id; const userRole = user?.role; const {theme} = useSelector((state) => state.theme); - const {bg, text} = themeConfig[theme]; + const {bg, text, accentBg } = themeConfig[theme]; const navigate = useNavigate(); React.useEffect(() => { @@ -59,8 +59,7 @@ const CourseGrid = () => { diff --git a/src/pages/courses/course/CourseCreate.jsx b/src/pages/courses/course/CourseCreate.jsx index 175d217..bd8be81 100644 --- a/src/pages/courses/course/CourseCreate.jsx +++ b/src/pages/courses/course/CourseCreate.jsx @@ -20,10 +20,27 @@ const CourseCreate = () => { const [endDate, setEndDate] = React.useState(''); const [message, setMessage] = React.useState(''); const [error, setError] = React.useState(''); + const [dateError, setDateError] = React.useState(''); + // Date validation function + const validateDates = () => { + if (startDate && endDate && new Date(startDate) >= new Date(endDate)) { + setDateError('End date must be later than start date'); + return false; + } + setDateError(''); + return true; + }; const handleSubmit = async (event) => { event.preventDefault(); + + // Validate dates before submission + if (!validateDates()) { + alert('End date must be later than start date. Please adjust your dates.'); + return; // Prevent form submission + } + try { await axios.post(`http://localhost:8080/api/courses`, { code, @@ -34,18 +51,21 @@ const CourseCreate = () => { startDate, endDate, }); - setCode(''); - setTitle(''); - setDepartment(''); - setDescription(''); - setCredits(''); - setStartDate(''); - setEndDate(''); - setMessage('Course created'); - setError(''); + setCode(''); + setTitle(''); + setDepartment(''); + setDescription(''); + setCredits(''); + setStartDate(''); + setEndDate(''); + setMessage('Course created'); + setError(''); + setDateError(''); } catch (err) { - setError('Could not create course'); setMessage(''); console.error(err); + setError('Could not create course'); + setMessage(''); + console.error(err); } }; @@ -74,7 +94,6 @@ const CourseCreate = () => { />
-
{
setStartDate(e.target.value)} + type="date" + id="startdate" + name="startdate" + className={`w-full px-4 py-2 rounded-md border ${theme === 'light' ? 'bg-light-bg border-light-accent' : 'bg-dark-bg border-dark-accent'} ${text} focus:outline-none focus:ring-2 focus:ring-[#9333ea]`} + required + value={startDate} + onChange={(e) => { + setStartDate(e.target.value); + // Clear date error when user changes dates + if (dateError) setDateError(''); + }} />
setEndDate(e.target.value)} + type="date" + id="enddate" + name="enddate" + className={`w-full px-4 py-2 rounded-md border ${theme === 'light' ? 'bg-light-bg border-light-accent' : 'bg-dark-bg border-dark-accent'} ${text} focus:outline-none focus:ring-2 focus:ring-[#9333ea]`} + required + value={endDate} + onChange={(e) => { + setEndDate(e.target.value); + if (dateError) setDateError(''); + }} />
-
+ {dateError && ( +
+ {dateError} +
+ )} + +
From c7e25f1f1cbdcbe6ab369e1b66d980668d9dd50d Mon Sep 17 00:00:00 2001 From: Lidizz Date: Tue, 10 Jun 2025 13:54:04 +0200 Subject: [PATCH 07/20] refactored course create --- src/pages/courses/course/CourseCreate.jsx | 73 +++++++++++++++++------ 1 file changed, 56 insertions(+), 17 deletions(-) diff --git a/src/pages/courses/course/CourseCreate.jsx b/src/pages/courses/course/CourseCreate.jsx index bd8be81..a7b6587 100644 --- a/src/pages/courses/course/CourseCreate.jsx +++ b/src/pages/courses/course/CourseCreate.jsx @@ -87,39 +87,70 @@ const CourseCreate = () => {
- + setCode(e.target.value)} + type="text" + id="code" + name="code" + placeholder="Enter 6-character (e.g., CS101A)" + className={`w-full px-4 py-2 rounded-md border ${theme === 'light' ? 'bg-light-bg border-light-accent' : 'bg-dark-bg border-dark-accent'} ${text} focus:outline-none focus:ring-2 focus:ring-[#9333ea]`} + required + value={code} + onChange={(e) => setCode(e.target.value)} />
- + setTitle(e.target.value)} + type="text" + id="title" + name="title" + placeholder="Enter course title (minimum 4 characters)" + className={`w-full px-4 py-2 rounded-md border ${theme === 'light' ? 'bg-light-bg border-light-accent' : 'bg-dark-bg border-dark-accent'} ${text} focus:outline-none focus:ring-2 focus:ring-[#9333ea]`} + required + value={title} + onChange={(e) => setTitle(e.target.value)} />
setDepartment(e.target.value)} + type="text" + id="department" + name="department" + placeholder="Enter department name (minimum 2 characters)" + className={`w-full px-4 py-2 rounded-md border ${theme === 'light' ? 'bg-light-bg border-light-accent' : 'bg-dark-bg border-dark-accent'} ${text} focus:outline-none focus:ring-2 focus:ring-[#9333ea]`} + required + value={department} + onChange={(e) => setDepartment(e.target.value)} />
setDescription(e.target.value)} + type="text" + id="description" + name="description" + placeholder="Enter course description" + className={`w-full px-4 py-2 rounded-md border ${theme === 'light' ? 'bg-light-bg border-light-accent' : 'bg-dark-bg border-dark-accent'} ${text} focus:outline-none focus:ring-2 focus:ring-[#9333ea]`} + required + value={description} + onChange={(e) => setDescription(e.target.value)} />
setCredits(e.target.value)} + type="number" + id="credits" + name="credits" + placeholder="Enter number of credits (minimum 1)" + className={`w-full px-4 py-2 rounded-md border ${theme === 'light' ? 'bg-light-bg border-light-accent' : 'bg-dark-bg border-dark-accent'} ${text} focus:outline-none focus:ring-2 focus:ring-[#9333ea]`} + min="0" + required + value={credits} + onChange={(e) => setCredits(e.target.value)} />
@@ -128,6 +159,7 @@ const CourseCreate = () => { type="date" id="startdate" name="startdate" + placeholder="Select course start date" className={`w-full px-4 py-2 rounded-md border ${theme === 'light' ? 'bg-light-bg border-light-accent' : 'bg-dark-bg border-dark-accent'} ${text} focus:outline-none focus:ring-2 focus:ring-[#9333ea]`} required value={startDate} @@ -144,32 +176,39 @@ const CourseCreate = () => { type="date" id="enddate" name="enddate" + placeholder="Select course end date" className={`w-full px-4 py-2 rounded-md border ${theme === 'light' ? 'bg-light-bg border-light-accent' : 'bg-dark-bg border-dark-accent'} ${text} focus:outline-none focus:ring-2 focus:ring-[#9333ea]`} required value={endDate} onChange={(e) => { setEndDate(e.target.value); + // Clear date error when user changes dates if (dateError) setDateError(''); }} />
+ {/* Date validation error message */} {dateError && (
{dateError}
)} -
- -
+ {error &&

{error}

} {message &&

{message}

} + +
+ +
From cce57850f9192e264006eb0dbdbecc5d139d46e2 Mon Sep 17 00:00:00 2001 From: Lidizz Date: Tue, 10 Jun 2025 14:21:01 +0200 Subject: [PATCH 08/20] refactoring --- src/pages/courses/course/CourseCreate.jsx | 6 +-- src/pages/courses/course/CourseModules.jsx | 23 +++++++- src/pages/courses/course/ModulesCreate.jsx | 61 +++++++++++++++++----- src/pages/courses/course/ModulesEdit.jsx | 5 +- 4 files changed, 72 insertions(+), 23 deletions(-) diff --git a/src/pages/courses/course/CourseCreate.jsx b/src/pages/courses/course/CourseCreate.jsx index a7b6587..0bfb457 100644 --- a/src/pages/courses/course/CourseCreate.jsx +++ b/src/pages/courses/course/CourseCreate.jsx @@ -106,7 +106,7 @@ const CourseCreate = () => { type="text" id="title" name="title" - placeholder="Enter course title (minimum 4 characters)" + placeholder="Enter course title (min. 4 characters)" className={`w-full px-4 py-2 rounded-md border ${theme === 'light' ? 'bg-light-bg border-light-accent' : 'bg-dark-bg border-dark-accent'} ${text} focus:outline-none focus:ring-2 focus:ring-[#9333ea]`} required value={title} @@ -119,7 +119,7 @@ const CourseCreate = () => { type="text" id="department" name="department" - placeholder="Enter department name (minimum 2 characters)" + placeholder="Enter department name (min. 2 characters)" className={`w-full px-4 py-2 rounded-md border ${theme === 'light' ? 'bg-light-bg border-light-accent' : 'bg-dark-bg border-dark-accent'} ${text} focus:outline-none focus:ring-2 focus:ring-[#9333ea]`} required value={department} @@ -145,7 +145,7 @@ const CourseCreate = () => { type="number" id="credits" name="credits" - placeholder="Enter number of credits (minimum 1)" + placeholder="Enter number of credits (between 1-30)" className={`w-full px-4 py-2 rounded-md border ${theme === 'light' ? 'bg-light-bg border-light-accent' : 'bg-dark-bg border-dark-accent'} ${text} focus:outline-none focus:ring-2 focus:ring-[#9333ea]`} min="0" required diff --git a/src/pages/courses/course/CourseModules.jsx b/src/pages/courses/course/CourseModules.jsx index 03cb745..8e28853 100644 --- a/src/pages/courses/course/CourseModules.jsx +++ b/src/pages/courses/course/CourseModules.jsx @@ -15,6 +15,23 @@ export const CourseModules = () => { const { theme } = useSelector((state) => state.theme); const { bg, text, border, accentBg, hoverBg } = themeConfig[theme]; + const [course, setCourse] = useState(null); + + useEffect(() => { + setLoading(true); + axios + .get(`http://localhost:8080/api/courses/${courseId}`) + .then((response) => { + setCourse(response.data); + setLoading(false); + }) + .catch((err) => { + setError(err.message || "Course not found"); + setLoading(false); + }); + }, [courseId]); + + useEffect(() => { setLoading(true); axios.get(`http://localhost:8080/api/courses/${courseId}/modules`) @@ -48,7 +65,9 @@ export const CourseModules = () => { Create Module
-

Modules for {courseId}

+ {course && ( // Conditionally render this section +

Modules for {course.title}

+ )}
{modules.length === 0 &&

No modules available.

} {modules.map((module) => ( @@ -63,4 +82,4 @@ export const CourseModules = () => { ); }; -export default CourseModules; \ No newline at end of file +export default CourseModules; diff --git a/src/pages/courses/course/ModulesCreate.jsx b/src/pages/courses/course/ModulesCreate.jsx index 8cdca65..653ed38 100644 --- a/src/pages/courses/course/ModulesCreate.jsx +++ b/src/pages/courses/course/ModulesCreate.jsx @@ -21,9 +21,15 @@ const ModulesCreate = () => { event.preventDefault(); try { axios.post(`http://localhost:8080/api/courses/${courseId}/modules`, { courseId, title, description, moduleNumber }); - setTitle(''); setDescription(''); setModuleNumber(''); setMessage('Module submitted'); setError(''); + setTitle(''); + setDescription(''); + setModuleNumber(''); + setMessage('Module submitted'); + setError(''); } catch (err) { - setError('Could not create module'); setMessage(''); console.error(err); + setError('Could not create module'); + setMessage(''); + console.error(err); } }; @@ -42,41 +48,68 @@ const ModulesCreate = () => {

Create Module

+
setTitle(e.target.value)} + type="text" + id="title" + name="title" + placeholder="Enter module title" + className={`w-full px-4 py-2 rounded-md border ${theme === 'light' ? 'bg-light-bg border-light-accent' : 'bg-dark-bg border-dark-accent'} ${text} focus:outline-none focus:ring-2 focus:ring-[#9333ea]`} + required + value={title} + onChange={(e) => setTitle(e.target.value)} />
+
setDescription(e.target.value)} + type="text" + id="description" + name="description" + placeholder="Enter module description" + className={`w-full px-4 py-2 rounded-md border ${theme === 'light' ? 'bg-light-bg border-light-accent' : 'bg-dark-bg border-dark-accent'} ${text} focus:outline-none focus:ring-2 focus:ring-[#9333ea]`} + required + value={description} + onChange={(e) => setDescription(e.target.value)} />
+
setModuleNumber(e.target.value)} + type="number" + id="modulenr" + name="modulenr" + placeholder="Enter module number" + className={`w-full px-4 py-2 rounded-md border ${theme === 'light' ? 'bg-light-bg border-light-accent' : 'bg-dark-bg border-dark-accent'} ${text} focus:outline-none focus:ring-2 focus:ring-[#9333ea]`} + min="0" + required + value={moduleNumber} + onChange={(e) => setModuleNumber(e.target.value)} />
-
- -
+ {error &&

{error}

} {message &&

{message}

} + +
+ +
); }; -export default ModulesCreate; +export default ModulesCreate; \ No newline at end of file diff --git a/src/pages/courses/course/ModulesEdit.jsx b/src/pages/courses/course/ModulesEdit.jsx index a089171..e52a69d 100644 --- a/src/pages/courses/course/ModulesEdit.jsx +++ b/src/pages/courses/course/ModulesEdit.jsx @@ -20,16 +20,13 @@ const ModulesEdit = () => { const {moduleId} = useParams(); const [type, setType] = React.useState('update'); - // console.log(moduleId); - useEffect(() => { if (!moduleId) return; axios.get(`http://localhost:8080/api/modules/${moduleId}/resources`) .then((res) => { - // If the response is an array of resources, pick the first one or map as needed if (Array.isArray(res.data) && res.data.length > 0) { - setResourceId(res.data[0].id); // or use appropriate property + setResourceId(res.data[0].id); } else { setResourceId(''); setError("No resource found for module"); From 6ab4c16b4606df96ae08aa32d43d59d1803bd1a2 Mon Sep 17 00:00:00 2001 From: Lidizz Date: Tue, 10 Jun 2025 15:42:39 +0200 Subject: [PATCH 09/20] refactore edit module --- src/pages/courses/course/ModulesEdit.jsx | 148 ++++++++++------------- 1 file changed, 65 insertions(+), 83 deletions(-) diff --git a/src/pages/courses/course/ModulesEdit.jsx b/src/pages/courses/course/ModulesEdit.jsx index e52a69d..78dbc98 100644 --- a/src/pages/courses/course/ModulesEdit.jsx +++ b/src/pages/courses/course/ModulesEdit.jsx @@ -1,23 +1,22 @@ -import React, {useEffect} from 'react'; -import {useNavigate, useParams} from 'react-router-dom'; +import React, { useEffect } from 'react'; +import { useNavigate, useParams } from 'react-router-dom'; import axios from 'axios'; -import {ArrowLeft} from 'lucide-react'; -import {useSelector} from 'react-redux'; -import {themeConfig} from '../../../themeConfig'; -import {iconColors} from '../../../utils/styles'; +import { ArrowLeft } from 'lucide-react'; +import { useSelector } from 'react-redux'; +import { themeConfig } from '../../../themeConfig'; +import { iconColors } from '../../../utils/styles'; const ModulesEdit = () => { - const {courseId} = useParams(); + const { courseId, moduleId } = useParams(); const navigate = useNavigate(); - const {theme} = useSelector((state) => state.theme); - const {bg, text, accentBg, border} = themeConfig[theme]; + const { theme } = useSelector((state) => state.theme); + const { bg, text, accentBg, border } = themeConfig[theme]; const [title, setTitle] = React.useState(''); const [description, setDescription] = React.useState(''); const [moduleNumber, setModuleNumber] = React.useState(''); const [resourceId, setResourceId] = React.useState(''); const [message, setMessage] = React.useState(''); const [error, setError] = React.useState(''); - const {moduleId} = useParams(); const [type, setType] = React.useState('update'); useEffect(() => { @@ -86,54 +85,46 @@ const ModulesEdit = () => { return (
-
-
-
+ +

- {type === 'delete' ? 'Delete Module' : 'Update Module'} + {type === 'delete' ? 'Delete Module' : 'Edit Module'}

-
- - +
+ +
+ + +
{type === 'update' && ( @@ -144,32 +135,35 @@ const ModulesEdit = () => { type="text" id="title" name="title" + placeholder="Enter module title" className={`w-full px-4 py-2 rounded-md border ${theme === 'light' ? 'bg-light-bg border-light-accent' : 'bg-dark-bg border-dark-accent'} ${text} focus:outline-none focus:ring-2 focus:ring-[#9333ea]`} required value={title} onChange={(e) => setTitle(e.target.value)} />
+
- + setDescription(e.target.value)} />
+
- + { )} - {type && (
- +
)} -
- -
+ + {error &&

{error}

} + {message &&

{message}

} + +
+
- - {error && ( -

- {error} -

- )} - {message && ( -

- {message} -

- )}
); }; -export default ModulesEdit; +export default ModulesEdit; \ No newline at end of file From d07dbad62b02afef0a4a9196ee743b2fc1152dfb Mon Sep 17 00:00:00 2001 From: arabadnan3 <248852@usn.no> Date: Tue, 10 Jun 2025 16:17:16 +0200 Subject: [PATCH 10/20] Fourth commit of development-adnan --- src/App.jsx | 4 + src/pages/courses/course/ModuleDetails.jsx | 23 ++- src/pages/courses/course/ResourceUpdate.jsx | 156 ++++++++++++++++++++ 3 files changed, 180 insertions(+), 3 deletions(-) create mode 100644 src/pages/courses/course/ResourceUpdate.jsx diff --git a/src/App.jsx b/src/App.jsx index f606a38..3e4f216 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -19,6 +19,7 @@ import CourseCreate from './pages/courses/course/CourseCreate.jsx'; import CourseEdit from './pages/courses/course/CourseEdit.jsx'; import ResourceCreate from "./pages/courses/course/ResourceCreate.jsx"; import ModulesEdit from './pages/courses/course/ModulesEdit.jsx'; +import ResourceUpdate from './pages/courses/course/ResourceUpdate.jsx'; const LoggedInLayout = ({ children }) => { const { theme } = useSelector((state) => state.theme); @@ -97,6 +98,9 @@ function App() { } /> + } + /> } diff --git a/src/pages/courses/course/ModuleDetails.jsx b/src/pages/courses/course/ModuleDetails.jsx index 2ca21c7..5f92fba 100644 --- a/src/pages/courses/course/ModuleDetails.jsx +++ b/src/pages/courses/course/ModuleDetails.jsx @@ -52,6 +52,16 @@ export default function ModuleDetails() { } }; + const deleteResource = async (resId) => { + try { + await axios.delete(`http://localhost:8080/api/modules/${moduleId}/resources/${resId}`); + alert('Resource deleted successfully.'); + window.location.reload(); + } catch (err) { + alert("Error:" + err.message); + } + }; + if (loadingModule || loadingResources) return
Loading module...
; @@ -126,10 +136,17 @@ export default function ModuleDetails() { Download resource ) : ( -

- No resources found. -

+ <> + + )} + ))} diff --git a/src/pages/courses/course/ResourceUpdate.jsx b/src/pages/courses/course/ResourceUpdate.jsx new file mode 100644 index 0000000..11ab957 --- /dev/null +++ b/src/pages/courses/course/ResourceUpdate.jsx @@ -0,0 +1,156 @@ +import { useNavigate, useParams } from 'react-router-dom'; +import axios from 'axios'; +import { ArrowLeft } from 'lucide-react'; +import { useSelector } from 'react-redux'; +import { themeConfig } from '../../../themeConfig'; +import { iconColors } from '../../../utils/styles'; +import React, {useEffect, useState} from "react"; + +const ResourceUpdate = () => { + const { courseId } = useParams(); + const navigate = useNavigate(); + const { theme } = useSelector((state) => state.theme); + const { bg, text, accentBg, border } = themeConfig[theme]; + const [resources, setResources] = useState([]); + const [title, setTitle] = React.useState(''); + const [content, setContent] = React.useState(''); + const [message, setMessage] = React.useState(''); + const [error, setError] = React.useState(''); + const {resourceId } = useParams(); + const {moduleId} = useParams(); + + useEffect(() => { + axios.get(`http://localhost:8080/api/modules/${moduleId}/resources`) + .then((response) => { + console.log('Full response:', response.data); // See the structure + setResources(response.data); + }) + .catch((error) => setError(error)) + .finally(() => setError(null)); + }, [moduleId]); + + const handleSubmit = async (event) => { + event.preventDefault(); + + try { + await axios.put( + `http://localhost:8080/api/modules/${moduleId}/resources/${resourceId}`, + { + title, + content, + } + ); + setMessage('Resource updated successfully'); + setError(''); + + setTitle(''); + setContent(''); + } catch (error) { + console.log(error); + setError('An error occurred while updating the resource'); + setMessage(''); + } + }; + + const handleGoBack = () => navigate(`/course/${courseId}/modules`); + + return ( +
+ +
+
+
+

+ Update Resource +

+
+ +
+ + setTitle(e.target.value)} + /> +
+
+ + setContent(e.target.value)} + /> +
+ +
+ + +
+ +
+ + +
+ + {error && ( +

+ {error} +

+ )} + {message && ( +

+ {message} +

+ )} +
+
+
+ ); +}; + +export default ResourceUpdate; \ No newline at end of file From 6db7266d2e62bb2be94685f33c72383065098c60 Mon Sep 17 00:00:00 2001 From: Lidizz Date: Tue, 10 Jun 2025 17:59:36 +0200 Subject: [PATCH 11/20] refactor code base using prettier, updated forms and added validation --- ...ic-web-apps-thankful-glacier-09f37ef03.yml | 92 +- eslint.config.js | 2 +- index.html | 2 +- postcss.config.js | 2 +- src/App.css | 2 +- src/App.jsx | 279 ++- src/assets/profile-placeholder.jpg | Bin 0 -> 142249 bytes src/components/DashboardCard.jsx | 43 +- src/components/Footer.jsx | 18 +- src/components/Header.jsx | 80 +- src/components/Sidebar.jsx | 87 +- src/components/ThemeSwitcher.jsx | 58 +- src/config.js | 2 +- src/index.css | 11 +- src/main.jsx | 22 +- src/pages/Dashboard.jsx | 26 +- src/pages/Login.jsx | 246 +- src/pages/Profile.jsx | 107 +- src/pages/Signup.jsx | 391 ++-- src/pages/courses/CourseCard.jsx | 83 +- src/pages/courses/CourseGrid.jsx | 167 +- .../courses/course/AssignmentSubmission.jsx | 1996 +++++++++-------- src/pages/courses/course/CourseAssignment.jsx | 132 +- src/pages/courses/course/CourseCreate.jsx | 469 ++-- src/pages/courses/course/CourseEdit.jsx | 498 ++-- src/pages/courses/course/CourseHome.jsx | 167 +- src/pages/courses/course/CourseModules.jsx | 151 +- src/pages/courses/course/ModuleDetails.jsx | 250 ++- src/pages/courses/course/ModulesCreate.jsx | 256 ++- src/pages/courses/course/ModulesEdit.jsx | 455 ++-- src/pages/courses/course/ResourceCreate.jsx | 346 +-- src/services/api.js | 165 +- src/store/store.js | 12 +- src/store/themeSlice.js | 20 +- src/themeConfig.js | 38 +- src/utils/styles.js | 27 +- tailwind.config.js | 25 +- vite.config.js | 9 +- 38 files changed, 3809 insertions(+), 2927 deletions(-) create mode 100644 src/assets/profile-placeholder.jpg diff --git a/.github/workflows/azure-static-web-apps-thankful-glacier-09f37ef03.yml b/.github/workflows/azure-static-web-apps-thankful-glacier-09f37ef03.yml index 0e90d04..37d3347 100644 --- a/.github/workflows/azure-static-web-apps-thankful-glacier-09f37ef03.yml +++ b/.github/workflows/azure-static-web-apps-thankful-glacier-09f37ef03.yml @@ -1,46 +1,46 @@ -name: Azure Static Web Apps CI/CD - -on: - push: - branches: - - main - pull_request: - types: [opened, synchronize, reopened, closed] - branches: - - main - -jobs: - build_and_deploy_job: - if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed') - runs-on: ubuntu-latest - name: Build and Deploy Job - steps: - - uses: actions/checkout@v3 - with: - submodules: true - lfs: false - - name: Build And Deploy - id: builddeploy - uses: Azure/static-web-apps-deploy@v1 - with: - azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_THANKFUL_GLACIER_09F37EF03 }} - repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for Github integrations (i.e. PR comments) - action: "upload" - ###### Repository/Build Configurations - These values can be configured to match your app requirements. ###### - # For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig - app_location: "/" # App source code path - api_location: "" # Api source code path - optional - output_location: "dist" # Built app content directory - optional - ###### End of Repository/Build Configurations ###### - - close_pull_request_job: - if: github.event_name == 'pull_request' && github.event.action == 'closed' - runs-on: ubuntu-latest - name: Close Pull Request Job - steps: - - name: Close Pull Request - id: closepullrequest - uses: Azure/static-web-apps-deploy@v1 - with: - azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_THANKFUL_GLACIER_09F37EF03 }} - action: "close" +name: Azure Static Web Apps CI/CD + +on: + push: + branches: + - main + pull_request: + types: [opened, synchronize, reopened, closed] + branches: + - main + +jobs: + build_and_deploy_job: + if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed') + runs-on: ubuntu-latest + name: Build and Deploy Job + steps: + - uses: actions/checkout@v3 + with: + submodules: true + lfs: false + - name: Build And Deploy + id: builddeploy + uses: Azure/static-web-apps-deploy@v1 + with: + azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_THANKFUL_GLACIER_09F37EF03 }} + repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for Github integrations (i.e. PR comments) + action: "upload" + ###### Repository/Build Configurations - These values can be configured to match your app requirements. ###### + # For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig + app_location: "/" # App source code path + api_location: "" # Api source code path - optional + output_location: "dist" # Built app content directory - optional + ###### End of Repository/Build Configurations ###### + + close_pull_request_job: + if: github.event_name == 'pull_request' && github.event.action == 'closed' + runs-on: ubuntu-latest + name: Close Pull Request Job + steps: + - name: Close Pull Request + id: closepullrequest + uses: Azure/static-web-apps-deploy@v1 + with: + azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_THANKFUL_GLACIER_09F37EF03 }} + action: "close" diff --git a/eslint.config.js b/eslint.config.js index ec2b712..1c0581a 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -30,4 +30,4 @@ export default [ ], }, }, -] +] \ No newline at end of file diff --git a/index.html b/index.html index e22d842..53cb5e2 100644 --- a/index.html +++ b/index.html @@ -2,7 +2,7 @@ - + StudyHub diff --git a/postcss.config.js b/postcss.config.js index 2e7af2b..2aa7205 100644 --- a/postcss.config.js +++ b/postcss.config.js @@ -3,4 +3,4 @@ export default { tailwindcss: {}, autoprefixer: {}, }, -} +}; diff --git a/src/App.css b/src/App.css index a68ab69..8872199 100644 --- a/src/App.css +++ b/src/App.css @@ -2,4 +2,4 @@ /* font-family: Arial, sans-serif;*/ /* margin: 0;*/ /* padding: 0;*/ -/*}*/ \ No newline at end of file +/*}*/ diff --git a/src/App.jsx b/src/App.jsx index f606a38..c6b9b37 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,119 +1,180 @@ -import React from 'react'; -import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; -import { useSelector } from 'react-redux'; -import Header from './components/Header'; -import Sidebar from './components/Sidebar'; -import Login from './pages/Login'; -import Signup from './pages/Signup'; -import Dashboard from './pages/Dashboard'; -import Profile from './pages/Profile'; -import CourseGrid from './pages/courses/CourseGrid.jsx'; -import { themeConfig } from './themeConfig'; -import CourseHome from './pages/courses/course/CourseHome.jsx'; -import CourseModules from './pages/courses/course/CourseModules.jsx'; -import CourseAssignment from './pages/courses/course/CourseAssignment.jsx'; -import AssignmentSubmission from './pages/courses/course/AssignmentSubmission.jsx'; -import ModuleDetails from './pages/courses/course/ModuleDetails'; -import ModulesCreate from './pages/courses/course/ModulesCreate.jsx'; -import CourseCreate from './pages/courses/course/CourseCreate.jsx'; -import CourseEdit from './pages/courses/course/CourseEdit.jsx'; +import React from "react"; +import { BrowserRouter as Router, Routes, Route } from "react-router-dom"; +import { useSelector } from "react-redux"; +import Header from "./components/Header"; +import Sidebar from "./components/Sidebar"; +import Login from "./pages/Login"; +import Signup from "./pages/Signup"; +import Dashboard from "./pages/Dashboard"; +import Profile from "./pages/Profile"; +import CourseGrid from "./pages/courses/CourseGrid.jsx"; +import { themeConfig } from "./themeConfig"; +import CourseHome from "./pages/courses/course/CourseHome.jsx"; +import CourseModules from "./pages/courses/course/CourseModules.jsx"; +import CourseAssignment from "./pages/courses/course/CourseAssignment.jsx"; +import AssignmentSubmission from "./pages/courses/course/AssignmentSubmission.jsx"; +import ModuleDetails from "./pages/courses/course/ModuleDetails"; +import ModulesCreate from "./pages/courses/course/ModulesCreate.jsx"; +import CourseCreate from "./pages/courses/course/CourseCreate.jsx"; +import CourseEdit from "./pages/courses/course/CourseEdit.jsx"; import ResourceCreate from "./pages/courses/course/ResourceCreate.jsx"; -import ModulesEdit from './pages/courses/course/ModulesEdit.jsx'; +import ModulesEdit from "./pages/courses/course/ModulesEdit.jsx"; const LoggedInLayout = ({ children }) => { - const { theme } = useSelector((state) => state.theme); - const { bg, text } = themeConfig[theme]; - return ( -
-
-
- -
- {children} -
-
-
- ); + const { theme } = useSelector((state) => state.theme); + const { bg, text } = themeConfig[theme]; + return ( +
+
+
+ +
+ {children} +
+
+
+ ); }; function App() { - const { theme } = useSelector((state) => state.theme); - const { bg, text } = themeConfig[theme]; + const { theme } = useSelector((state) => state.theme); + const { bg, text } = themeConfig[theme]; - return ( -
- - } /> - } /> - } /> - } - /> - } - /> - } - /> - } - /> - } - - /> -
Schedule Page (TBD)
} - /> -
Groups Page (TBD)
} - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> -
-
- ); + return ( +
+ + } /> + } /> + } /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + +
Schedule Page (TBD)
+ + } + /> + +
Groups Page (TBD)
+ + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> +
+
+ ); } export default function AppWrapper() { - return ( - - - - ); -} \ No newline at end of file + return ( + + + + ); +} diff --git a/src/assets/profile-placeholder.jpg b/src/assets/profile-placeholder.jpg new file mode 100644 index 0000000000000000000000000000000000000000..04d29eab7090c45ab3be8614294cc54a65ce1061 GIT binary patch literal 142249 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 IcKRp%5B|ytzyJUM literal 0 HcmV?d00001 diff --git a/src/components/DashboardCard.jsx b/src/components/DashboardCard.jsx index a9a9413..8de2618 100644 --- a/src/components/DashboardCard.jsx +++ b/src/components/DashboardCard.jsx @@ -1,27 +1,32 @@ -import React from 'react'; -import { useSelector } from 'react-redux'; -import {themeConfig} from "../themeConfig.js"; +import React from "react"; +import { useSelector } from "react-redux"; +import { themeConfig } from "../themeConfig.js"; const DashboardCard = () => { - const { theme } = useSelector((state) => state.theme); - const { bg, text, border } = themeConfig[theme]; + const { theme } = useSelector((state) => state.theme); + const { bg, text, border } = themeConfig[theme]; - const subjects = [ - { title: "APP2000", endDate: "2025-06-12" }, - { title: "DAT2000", endDate: "2025-05-31" }, - { title: "OBJ2100", endDate: "2025-06-23" }, - ]; + const subjects = [ + { title: "APP2000", endDate: "2025-06-12" }, + { title: "DAT2000", endDate: "2025-05-31" }, + { title: "OBJ2100", endDate: "2025-06-23" }, + ]; - return ( -

- {subjects.map((subject, index) => ( -
-

{subject.title}

-

End Date: {subject.endDate}

-
- ))} + return ( +
+ {subjects.map((subject, index) => ( +
+

{subject.title}

+

+ End Date: {subject.endDate} +

- ); + ))} +
+ ); }; export default DashboardCard; diff --git a/src/components/Footer.jsx b/src/components/Footer.jsx index ff3edfa..622f60e 100644 --- a/src/components/Footer.jsx +++ b/src/components/Footer.jsx @@ -1,11 +1,13 @@ -import { useSelector } from 'react-redux'; +import { useSelector } from "react-redux"; export function Footer() { - return ( -
-
-

© {new Date().getFullYear()} StudyHub. All rights reserved.

-
-
- ); + return ( +
+
+

+ © {new Date().getFullYear()} StudyHub. All rights reserved. +

+
+
+ ); } diff --git a/src/components/Header.jsx b/src/components/Header.jsx index 759a0c9..8407b0f 100644 --- a/src/components/Header.jsx +++ b/src/components/Header.jsx @@ -1,47 +1,45 @@ -import React from 'react'; -import { useNavigate } from 'react-router-dom'; -import { useSelector, useDispatch } from 'react-redux'; -import { setTheme } from '../store/themeSlice'; -import { themeConfig } from '../themeConfig'; +import React from "react"; +import { useNavigate } from "react-router-dom"; +import { useSelector, useDispatch } from "react-redux"; +import { setTheme } from "../store/themeSlice"; +import { themeConfig } from "../themeConfig"; const Header = () => { - const navigate = useNavigate(); - const { theme } = useSelector((state) => state.theme); - const dispatch = useDispatch(); - const { bg, text, border } = themeConfig[theme]; + const navigate = useNavigate(); + const { theme } = useSelector((state) => state.theme); + const dispatch = useDispatch(); + const { bg, text, border } = themeConfig[theme]; - const handleThemeToggle = () => { - dispatch(setTheme(theme === 'light' ? 'dark' : 'light')); - }; + const handleThemeToggle = () => { + dispatch(setTheme(theme === "light" ? "dark" : "light")); + }; - return ( -
-
navigate('/dashboard')} - > -

StudyHub

-
-
- -
navigate('/profile')} - > - Profile -
-
-
- ); + return ( +
+
navigate("/dashboard")}> +

+ StudyHub +

+
+
+ +
navigate("/profile")}> + Profile +
+
+
+ ); }; -export default Header; \ No newline at end of file +export default Header; diff --git a/src/components/Sidebar.jsx b/src/components/Sidebar.jsx index 45a7698..22e434d 100644 --- a/src/components/Sidebar.jsx +++ b/src/components/Sidebar.jsx @@ -1,50 +1,55 @@ -import React, { useState } from 'react'; -import { useNavigate } from 'react-router-dom'; -import { useSelector } from 'react-redux'; -import { Home, BookOpen, Calendar, Users } from 'lucide-react'; -import { themeConfig } from '../themeConfig'; -import { iconColors } from '../utils/styles'; +import React, { useState } from "react"; +import { useNavigate } from "react-router-dom"; +import { useSelector } from "react-redux"; +import { Home, BookOpen, Calendar, Users } from "lucide-react"; +import { themeConfig } from "../themeConfig"; +import { iconColors } from "../utils/styles"; const Sidebar = () => { - const navigate = useNavigate(); - const { theme } = useSelector((state) => state.theme); - const [isCollapsed, setIsCollapsed] = useState(false); - const { bg, text, border, accentBg } = themeConfig[theme]; + const navigate = useNavigate(); + const { theme } = useSelector((state) => state.theme); + const [isCollapsed, setIsCollapsed] = useState(false); + const { bg, text, border, accentBg } = themeConfig[theme]; - const navItems = [ - { icon: , label: 'Dashboard', path: '/dashboard' }, - { icon: , label: 'Courses', path: '/courses' }, - { icon: , label: 'Schedule', path: '/schedule' }, - { icon: , label: 'Groups', path: '/groups' }, - ]; + const navItems = [ + { icon: , label: "Dashboard", path: "/dashboard" }, + { icon: , label: "Courses", path: "/courses" }, + { icon: , label: "Schedule", path: "/schedule" }, + { icon: , label: "Groups", path: "/groups" }, + ]; - return ( - + ); }; -export default Sidebar; \ No newline at end of file +export default Sidebar; diff --git a/src/components/ThemeSwitcher.jsx b/src/components/ThemeSwitcher.jsx index 6efe0b2..453bc21 100644 --- a/src/components/ThemeSwitcher.jsx +++ b/src/components/ThemeSwitcher.jsx @@ -1,36 +1,38 @@ -import React from 'react'; -import { useSelector, useDispatch } from 'react-redux'; -import { setTheme } from '../store/themeSlice'; -import { themeConfig } from '../themeConfig'; +import React from "react"; +import { useSelector, useDispatch } from "react-redux"; +import { setTheme } from "../store/themeSlice"; +import { themeConfig } from "../themeConfig"; const themes = [ - { name: 'light', label: 'Light ☀️' }, - { name: 'dark', label: 'Dark 🌙' }, - { name: 'ocean', label: 'Ocean 🌊' }, - { name: 'forest', label: 'Forest 🌲' }, - { name: 'sunset', label: 'Sunset 🌅' }, + { name: "light", label: "Light ☀️" }, + { name: "dark", label: "Dark 🌙" }, + { name: "ocean", label: "Ocean 🌊" }, + { name: "forest", label: "Forest 🌲" }, + { name: "sunset", label: "Sunset 🌅" }, ]; const ThemeSwitcher = ({ className }) => { - const { theme } = useSelector((state) => state.theme); - const dispatch = useDispatch(); - const { bg, text, border } = themeConfig[theme]; + const { theme } = useSelector((state) => state.theme); + const dispatch = useDispatch(); + const { bg, text, border } = themeConfig[theme]; - return ( -
- -
- ); + return ( +
+ +
+ ); }; -export default ThemeSwitcher; \ No newline at end of file +export default ThemeSwitcher; diff --git a/src/config.js b/src/config.js index 0bd83c8..b512432 100644 --- a/src/config.js +++ b/src/config.js @@ -1 +1 @@ -// export const API_BASE_URL = 'http://localhost:8080/api/users'; \ No newline at end of file +// export const API_BASE_URL = 'http://localhost:8080/api/users'; diff --git a/src/index.css b/src/index.css index f65fcba..6ff7657 100644 --- a/src/index.css +++ b/src/index.css @@ -1,4 +1,4 @@ -@import url('https://fonts.googleapis.com/css2?family=Quicksand:wght@400;500;600;700&family=Roboto+Condensed:wght@400;700&display=swap'); +@import url("https://fonts.googleapis.com/css2?family=Quicksand:wght@400;500;600;700&family=Roboto+Condensed:wght@400;700&display=swap"); @import "tailwindcss/base"; @import "tailwindcss/components"; @import "tailwindcss/utilities"; @@ -7,7 +7,12 @@ html { @apply font-quicksand text-[16px] leading-6 min-h-screen; } - h1, h2, h3, h4, h5, h6 { + h1, + h2, + h3, + h4, + h5, + h6 { @apply font-roboto; } } @@ -37,4 +42,4 @@ top: 2rem; right: 2rem; } -} \ No newline at end of file +} diff --git a/src/main.jsx b/src/main.jsx index febba96..214b892 100644 --- a/src/main.jsx +++ b/src/main.jsx @@ -1,12 +1,12 @@ -import React from 'react'; -import { createRoot } from 'react-dom/client'; -import { Provider } from 'react-redux'; -import './index.css'; -import App from './App.jsx'; -import { store } from './store/store.js'; +import React from "react"; +import { createRoot } from "react-dom/client"; +import { Provider } from "react-redux"; +import "./index.css"; +import App from "./App.jsx"; +import { store } from "./store/store.js"; -createRoot(document.getElementById('root')).render( - - - -); \ No newline at end of file +createRoot(document.getElementById("root")).render( + + + , +); diff --git a/src/pages/Dashboard.jsx b/src/pages/Dashboard.jsx index 83e2d9f..8204025 100644 --- a/src/pages/Dashboard.jsx +++ b/src/pages/Dashboard.jsx @@ -1,18 +1,20 @@ -import React from 'react'; +import React from "react"; import DashboardCard from "../components/DashboardCard.jsx"; -import { useSelector } from 'react-redux'; -import {themeConfig} from "../themeConfig.js"; +import { useSelector } from "react-redux"; +import { themeConfig } from "../themeConfig.js"; const Dashboard = () => { - const { theme } = useSelector((state) => state.theme); - const { bg, text } = themeConfig[theme]; - return ( -
-

Dashboard

-

Your enrolled classes for the semester

- -
- ); + const { theme } = useSelector((state) => state.theme); + const { bg, text } = themeConfig[theme]; + return ( +
+

+ Dashboard +

+

Your enrolled classes for the semester

+ +
+ ); }; export default Dashboard; diff --git a/src/pages/Login.jsx b/src/pages/Login.jsx index 382d5c9..d1813d3 100644 --- a/src/pages/Login.jsx +++ b/src/pages/Login.jsx @@ -1,112 +1,154 @@ -import React, { useState } from 'react'; -import axios from 'axios'; -import { useNavigate, Link } from 'react-router-dom'; -import { useSelector } from 'react-redux'; -import { Eye, EyeOff } from 'lucide-react'; -import {themeConfig} from "../themeConfig.js"; -import {iconColors} from "../utils/styles.js"; +import React, { useState } from "react"; +import axios from "axios"; +import { useNavigate, Link } from "react-router-dom"; +import { useSelector } from "react-redux"; +import { Eye, EyeOff } from "lucide-react"; +import { themeConfig } from "../themeConfig.js"; +import { iconColors } from "../utils/styles.js"; const Login = () => { - const [formData, setFormData] = useState({ email: '', password: '' }); - const [showPassword, setShowPassword] = useState(false); - const [error, setError] = useState(''); - const navigate = useNavigate(); - const { theme } = useSelector((state) => state.theme); - const { bg, text, accentBg, border } = themeConfig[theme]; + const [formData, setFormData] = useState({ email: "", password: "" }); + const [showPassword, setShowPassword] = useState(false); + const [error, setError] = useState(""); + const navigate = useNavigate(); + const { theme } = useSelector((state) => state.theme); + const { bg, text, accentBg, border } = themeConfig[theme]; - const handleChange = (e) => { - const { name, value } = e.target; - setFormData((prev) => ({ ...prev, [name]: value })); - setError(''); - }; + const handleChange = (e) => { + const { name, value } = e.target; + setFormData((prev) => ({ ...prev, [name]: value })); + setError(""); + }; - const handleSubmit = async (e) => { - e.preventDefault(); - setError(''); - try { - const response = await axios.post(`http://localhost:8080/api/users/login`, formData); - localStorage.setItem('user', JSON.stringify(response.data)); - navigate('/dashboard'); - } catch (err) { - setError(err.response?.data || 'Login failed'); - } - }; + const handleSubmit = async (e) => { + e.preventDefault(); + setError(""); + try { + const response = await axios.post( + `http://localhost:8080/api/users/login`, + formData, + ); + localStorage.setItem("user", JSON.stringify(response.data)); + navigate("/dashboard"); + } catch (err) { + setError(err.response?.data || "Login failed"); + } + }; - const handleForgotPasswordClick = (e) => { - e.preventDefault(); - alert('Password reset not implemented. Contact support.'); - }; + const handleForgotPasswordClick = (e) => { + e.preventDefault(); + alert("Password reset not implemented. Contact support."); + }; - return ( -
-
-
- + return ( +
+
+
+
+

+ Login to StudyHub +

+ {error && ( +

+ {error} +

+ )} +
+
+ +
+
+ +
+ + +
+
+
+
+ + +
+ + Forgot password? + +
+ +
+

+ Don't have an account?{" "} + + Register + +

- ); +
+
+ ); }; -export default Login; \ No newline at end of file +export default Login; diff --git a/src/pages/Profile.jsx b/src/pages/Profile.jsx index 2c4f870..f930dd3 100644 --- a/src/pages/Profile.jsx +++ b/src/pages/Profile.jsx @@ -1,57 +1,66 @@ -import React from 'react'; -import { useNavigate } from 'react-router-dom'; -import { useSelector } from 'react-redux'; -import {themeConfig} from "../themeConfig.js"; +import React from "react"; +import { useNavigate } from "react-router-dom"; +import { useSelector } from "react-redux"; +import { themeConfig } from "../themeConfig.js"; const Profile = () => { - const user = JSON.parse(localStorage.getItem('user')); - const navigate = useNavigate(); - const { theme } = useSelector((state) => state.theme); - const { bg, text, border, accentBg } = themeConfig[theme]; - const [profilePic, setProfilePic] = React.useState('/profile-placeholder.jpg'); + const user = JSON.parse(localStorage.getItem("user")); + const navigate = useNavigate(); + const { theme } = useSelector((state) => state.theme); + const { bg, text, border, accentBg } = themeConfig[theme]; + const [profilePic, setProfilePic] = React.useState( + "/profile-placeholder.jpg", + ); - if (!user) { - navigate('/login'); - return null; - } + if (!user) { + navigate("/login"); + return null; + } - const handleLogout = () => { localStorage.removeItem('user'); navigate('/login'); }; - const handleImageChange = (e) => { - const file = e.target.files[0]; - if (file) { - const reader = new FileReader(); - reader.onloadend = () => setProfilePic(reader.result); - reader.readAsDataURL(file); - } - }; + const handleLogout = () => { + localStorage.removeItem("user"); + navigate("/login"); + }; - return ( -
-
-

User Profile

-
- Profile - -
-
-

Username: {user.username}

-

Email: {user.email}

-

First Name: {user.firstName}

-

Last Name: {user.lastName}

-

Role: {user.role}

-
- -
+ return ( +
+
+

+ User Profile +

+ +
+

+ Username: {user.username} +

+

+ Email: {user.email} +

+

+ First Name: {user.firstName} +

+

+ Last Name: {user.lastName} +

+

+ Role: {user.role} +

- ); + +
+
+ ); }; -export default Profile; \ No newline at end of file +export default Profile; diff --git a/src/pages/Signup.jsx b/src/pages/Signup.jsx index 0268029..63c8d0b 100644 --- a/src/pages/Signup.jsx +++ b/src/pages/Signup.jsx @@ -1,180 +1,231 @@ -import React from 'react'; -import axios from 'axios'; -import { useNavigate, Link } from 'react-router-dom'; -import { useSelector } from 'react-redux'; -import { Eye, EyeOff } from 'lucide-react'; -import { iconColors } from '../utils/styles'; -import {themeConfig} from "../themeConfig.js"; +import React from "react"; +import axios from "axios"; +import { useNavigate, Link } from "react-router-dom"; +import { useSelector } from "react-redux"; +import { Eye, EyeOff } from "lucide-react"; +import { iconColors } from "../utils/styles"; +import { themeConfig } from "../themeConfig.js"; const Signup = () => { - const [formData, setFormData] = React.useState({ - email: '', firstName: '', lastName: '', role: 'STUDENT', password: '', passwordConfirm: '', - }); - const [showPassword, setShowPassword] = React.useState(false); - const [error, setError] = React.useState(''); - const navigate = useNavigate(); - const { theme } = useSelector((state) => state.theme); - const { bg, text, accentBg, border } = themeConfig[theme]; + const [formData, setFormData] = React.useState({ + email: "", + firstName: "", + lastName: "", + role: "STUDENT", + password: "", + passwordConfirm: "", + }); + const [showPassword, setShowPassword] = React.useState(false); + const [error, setError] = React.useState(""); + const navigate = useNavigate(); + const { theme } = useSelector((state) => state.theme); + const { bg, text, accentBg, border } = themeConfig[theme]; - const handleChange = (e) => { - const { name, value } = e.target; - setFormData((prev) => ({ ...prev, [name]: value })); - setError(''); - }; + const handleChange = (e) => { + const { name, value } = e.target; + setFormData((prev) => ({ ...prev, [name]: value })); + setError(""); + }; - const handleSubmit = async (e) => { - e.preventDefault(); - if (formData.password !== formData.passwordConfirm) { - setError('Passwords do not match'); - return; - } - try { - await axios.post(`http://localhost:8080/api/users/register`, { - email: formData.email, - firstName: formData.firstName, - lastName: formData.lastName, - role: formData.role, - password: formData.password, - }); - navigate('/dashboard'); - } catch (err) { - setError(err.response?.data || 'Registration failed'); - } - }; + const handleSubmit = async (e) => { + e.preventDefault(); + if (formData.password !== formData.passwordConfirm) { + setError("Passwords do not match"); + return; + } + try { + await axios.post(`http://localhost:8080/api/users/register`, { + email: formData.email, + firstName: formData.firstName, + lastName: formData.lastName, + role: formData.role, + password: formData.password, + }); + navigate("/dashboard"); + } catch (err) { + setError(err.response?.data || "Registration failed"); + } + }; - const handleReset = () => { - setFormData({ email: '', firstName: '', lastName: '', role: 'STUDENT', password: '', passwordConfirm: '' }); - setError(''); - }; + const handleReset = () => { + setFormData({ + email: "", + firstName: "", + lastName: "", + role: "STUDENT", + password: "", + passwordConfirm: "", + }); + setError(""); + }; - return ( -
-
-
-
-

Join StudyHub

- {error &&

{error}

} -
-
-
- - -
-
- - -
-
-
- - -
-
- - -
-
- -
- - -
-
-
- -
- - -
-
-
- - -
-
-

- Already have an account? Login -

-
+ return ( +
+
+
+
+

+ Join StudyHub +

+ {error && ( +

+ {error} +

+ )} +
+
+
+ + +
+
+ + +
+
+
+ + +
+
+ + +
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+
+

+ Already have an account?{" "} + + Login + +

- ); +
+
+ ); }; -export default Signup; \ No newline at end of file +export default Signup; diff --git a/src/pages/courses/CourseCard.jsx b/src/pages/courses/CourseCard.jsx index bc4451e..3a9a1e0 100644 --- a/src/pages/courses/CourseCard.jsx +++ b/src/pages/courses/CourseCard.jsx @@ -1,49 +1,50 @@ import { BookOpen } from "lucide-react"; import { useNavigate } from "react-router-dom"; -import { useSelector } from 'react-redux'; -import { themeConfig } from '../../themeConfig'; -import {iconColors} from "../../utils/styles.js"; +import { useSelector } from "react-redux"; +import { themeConfig } from "../../themeConfig"; +import { iconColors } from "../../utils/styles.js"; import React from "react"; const CourseCard = ({ id, title, department, credits }) => { - const navigate = useNavigate(); - const { theme } = useSelector((state) => state.theme); - const { bg, text, border, hoverBg } = themeConfig[theme]; - - const handleCourseClick = () => navigate(`/course/${id}`); - - const handleCourseClick2 = () => navigate(`/courses/${id}/CourseEdit`); - - return ( -
- - - - + const navigate = useNavigate(); + const { theme } = useSelector((state) => state.theme); + const { bg, text, border, hoverBg } = themeConfig[theme]; + + const handleCourseClick = () => navigate(`/course/${id}`); + + const handleCourseClick2 = () => navigate(`/courses/${id}/CourseEdit`); + + return ( +
+ + +
+ ); }; -export default CourseCard; \ No newline at end of file +export default CourseCard; diff --git a/src/pages/courses/CourseGrid.jsx b/src/pages/courses/CourseGrid.jsx index 21e1ae4..988b00d 100644 --- a/src/pages/courses/CourseGrid.jsx +++ b/src/pages/courses/CourseGrid.jsx @@ -1,96 +1,87 @@ import CourseCard from "./CourseCard.jsx"; import React from "react"; import axios from "axios"; -import {useSelector} from 'react-redux'; -import {themeConfig} from '../../themeConfig'; -import {useNavigate} from "react-router-dom"; +import { useSelector } from "react-redux"; +import { themeConfig } from "../../themeConfig"; +import { useNavigate } from "react-router-dom"; const CourseGrid = () => { - const [courses, setCourses] = React.useState([]); - const [loading, setLoading] = React.useState(true); - const [error, setError] = React.useState(null); - const user = JSON.parse(localStorage.getItem('user')); - //const studentId = user?.id; - const userId = user?.id; - const userRole = user?.role; - const {theme} = useSelector((state) => state.theme); - const {bg, text, accentBg } = themeConfig[theme]; - const navigate = useNavigate(); - - React.useEffect(() => { - if (!userId) { - setError("No user ID found"); - setLoading(false); - return; - } - let endpoint; - - if (userRole === 'STUDENT') { - endpoint = `http://localhost:8080/api/courses/student/${userId}/summary`; - } else if (userRole === 'INSTRUCTOR') { - endpoint = `http://localhost:8080/api/courses/instructor/${userId}/summary`; - } else { - setError("Invalid user role"); - setLoading(false); - return; - } - - - axios.get(endpoint) - .then((response) => { - setCourses(response.data); - setLoading(false); - }) - .catch(err => { - console.error('Error fetching courses:', err); - setError('Error fetching courses'); - setLoading(false); - }); - }, [userId, userRole]); - - - if (loading) return

Loading...

; - if (error) return

{error}

; - - return ( - -
- - - - -
- - -

Your Courses

- -
- -
- - -
- {courses.length === 0 &&

No enrolled courses.

} - {courses.map((course, index) => ( - - ))} - -
-
+ const [courses, setCourses] = React.useState([]); + const [loading, setLoading] = React.useState(true); + const [error, setError] = React.useState(null); + const user = JSON.parse(localStorage.getItem("user")); + //const studentId = user?.id; + const userId = user?.id; + const userRole = user?.role; + const { theme } = useSelector((state) => state.theme); + const { bg, text, accentBg } = themeConfig[theme]; + const navigate = useNavigate(); + + React.useEffect(() => { + if (!userId) { + setError("No user ID found"); + setLoading(false); + return; + } + let endpoint; + + if (userRole === "STUDENT") { + endpoint = `http://localhost:8080/api/courses/student/${userId}/summary`; + } else if (userRole === "INSTRUCTOR") { + endpoint = `http://localhost:8080/api/courses/instructor/${userId}/summary`; + } else { + setError("Invalid user role"); + setLoading(false); + return; + } + + axios + .get(endpoint) + .then((response) => { + setCourses(response.data); + setLoading(false); + }) + .catch((err) => { + console.error("Error fetching courses:", err); + setError("Error fetching courses"); + setLoading(false); + }); + }, [userId, userRole]); + + if (loading) return

Loading...

; + if (error) return

{error}

; + + return ( +
+ + +
+

+ Your Courses +

+ +
+ +
+ {courses.length === 0 &&

No enrolled courses.

} + {courses.map((course, index) => ( + + ))}
- - - ); +
+
+ ); }; -export default CourseGrid; \ No newline at end of file +export default CourseGrid; diff --git a/src/pages/courses/course/AssignmentSubmission.jsx b/src/pages/courses/course/AssignmentSubmission.jsx index 0292755..c49fb7d 100644 --- a/src/pages/courses/course/AssignmentSubmission.jsx +++ b/src/pages/courses/course/AssignmentSubmission.jsx @@ -1,932 +1,1134 @@ import React, { useEffect, useState } from "react"; import { useParams, useNavigate } from "react-router-dom"; -import {ArrowLeft, Upload, X, Calendar, CheckCircle, Plus} from "lucide-react"; +import { + ArrowLeft, + Upload, + X, + Calendar, + CheckCircle, + Plus, +} from "lucide-react"; import axios from "axios"; import { useSelector } from "react-redux"; import { themeConfig } from "../../../themeConfig"; import { iconColors } from "../../../utils/styles"; - const AssignmentSubmission = () => { - const {courseId, assignmentId} = useParams(); - const navigate = useNavigate(); - const {theme} = useSelector((state) => state.theme); - const {bg, text, accentBg, border} = themeConfig[theme]; - - // Get user - const user = JSON.parse(localStorage.getItem("user")); - const studentId = user?.id; - const userRole = user?.role || 'STUDENT'; - - // Form state for submission - const [submissionForm, setSubmissionForm] = useState({ - text: "", - fileName: "No file chosen" - }); - - // Assignment and loading states - const [assignment, setAssignment] = useState(null); - const [assignments, setAssignments] = useState([]); - const [loading, setLoading] = useState(true); - const [error, setError] = useState(null); - - // Submission data state for display (grades/feedback) - const [submissionData, setSubmissionData] = useState({ - grade: null, - feedback: null, - isSubmitted: false, - submittedFileName: null + const { courseId, assignmentId } = useParams(); + const navigate = useNavigate(); + const { theme } = useSelector((state) => state.theme); + const { bg, text, accentBg, border } = themeConfig[theme]; + + // Get user + const user = JSON.parse(localStorage.getItem("user")); + const studentId = user?.id; + const userRole = user?.role || "STUDENT"; + + // Form state for submission + const [submissionForm, setSubmissionForm] = useState({ + text: "", + fileName: "No file chosen", + }); + + // Assignment and loading states + const [assignment, setAssignment] = useState(null); + const [assignments, setAssignments] = useState([]); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + // Submission data state for display (grades/feedback) + const [submissionData, setSubmissionData] = useState({ + grade: null, + feedback: null, + isSubmitted: false, + submittedFileName: null, + }); + + // Instructor states + const [courseSubmissions, setCourseSubmissions] = useState([]); + const [editAssignment, setEditAssignment] = useState(null); + const [showDeleteConfirm, setShowDeleteConfirm] = useState(null); + const [submissions, setSubmissions] = useState([]); + const [selectedSubmission, setSelectedSubmission] = useState(null); + const [showGrade, setShowGrade] = useState(false); + const [gradeForm, setGradeForm] = useState({ + grade: "", + feedback: "", + }); + + const [newAssignment, setNewAssignment] = useState({ + courseId: courseId, + title: "", + description: "", + dueDate: "", + }); + + useEffect(() => { + if (courseId) { + fetchAssignments(); + } + }, [courseId]); + + useEffect(() => { + if (userRole === "STUDENT" && assignmentId && studentId && courseId) { + fetchSubmissions(); + } + }, [assignmentId, userRole, studentId, courseId]); + + useEffect(() => { + if (assignmentId && assignments.length > 0) { + const foundAssignment = assignments.find( + (a) => a.id.toString() === assignmentId, + ); + setAssignment(foundAssignment); + } + }, [assignmentId, assignments]); + + // Fallback useEffect for assignment fetching + useEffect(() => { + if (!assignment && assignmentId) { + setLoading(true); + axios + .get( + `http://localhost:8080/api/courses/${courseId}/assignments/${assignmentId}`, + ) + .then((response) => { + setAssignment(response.data); + setLoading(false); + }) + .catch((err) => { + setError(err.message || "Assignment not found"); + setLoading(false); + }); + } + }, [courseId, assignmentId, assignment]); + + const fetchAssignments = async () => { + setLoading(true); + try { + const response = await axios.get( + `http://localhost:8080/api/courses/${courseId}/assignments`, + ); + setAssignments(response.data); + + if (userRole === "STUDENT" && studentId) { + fetchSubmissions(); + } else if (userRole === "INSTRUCTOR") { + fetchCourseSubmissions(); + } + setLoading(false); + } catch (err) { + setError(err.message || "Assignment not found"); + setLoading(false); + } + }; + + const fetchSubmissions = async () => { + try { + const response = await axios.get( + `http://localhost:8080/api/courses/${courseId}/submissions/student/${studentId}`, + ); + setSubmissions(response.data); + + if (assignmentId) { + const currentSubmission = response.data.find( + (s) => s.assignmentId && s.assignmentId.toString() === assignmentId, + ); + + if (currentSubmission) { + setSubmissionData({ + grade: currentSubmission.grade, + feedback: currentSubmission.feedback, + isSubmitted: !!currentSubmission.submittedFileName, + submittedFileName: currentSubmission.submittedFileName, + }); + } else { + setSubmissionData({ + grade: null, + feedback: null, + isSubmitted: false, + submittedFileName: null, + }); + } + } + } catch (err) { + if (err.response?.status !== 404) { + console.error("Error fetching submissions:", err); + } + } + }; + + const fetchCourseSubmissions = async () => { + try { + if (assignmentId) { + const response = await axios.get( + `http://localhost:8080/api/courses/${courseId}/submissions/${assignmentId}/submissions`, + ); + setCourseSubmissions(response.data); + } else { + setCourseSubmissions([]); + } + } catch (err) { + if (err.response?.status === 404) { + setCourseSubmissions([]); + } else { + console.error("Error fetching assignment submissions:", err); + setCourseSubmissions([]); + } + } + }; + + const handleFileChange = (e) => { + const file = e.target.files[0]; + if (file) { + setSubmissionForm((prev) => ({ + ...prev, + fileName: file.name, + })); + } + }; + + const clearFile = () => { + setSubmissionForm((prev) => ({ ...prev, fileName: "No file chosen" })); + const fileInput = document.getElementById("assignmentFile"); + if (fileInput) { + fileInput.value = ""; + } + }; + + const handleSubmit = async (e) => { + e.preventDefault(); + + try { + const fileInput = document.getElementById("assignmentFile"); + const file = fileInput.files[0]; + + if (!file) { + alert("Please select a file to submit"); + return; + } + + const formData = new FormData(); + formData.append("file", file); + + await axios.post( + `http://localhost:8080/api/courses/${courseId}/submissions/${assignmentId}/student/${studentId}`, + formData, + { + headers: { "Content-Type": "multipart/form-data" }, + }, + ); + + alert("Assignment submitted successfully!"); + + setSubmissionData((prev) => ({ + ...prev, + isSubmitted: true, + submittedFileName: file.name, + })); + + await fetchSubmissions(); + setSubmissionForm({ text: "", fileName: "No file chosen" }); + fileInput.value = ""; + } catch (err) { + console.error("Submission error:", err); + alert("Failed to submit assignment"); + } + }; + + const handleDownload = async () => { + try { + const currentSubmission = submissions.find( + (s) => + s && s.assignmentId && s.assignmentId.toString() === assignmentId, + ); + + if (!currentSubmission) { + alert("Submission not found"); + return; + } + + const response = await axios.get( + `http://localhost:8080/api/courses/${courseId}/submissions/${assignmentId}/student/${studentId}/download`, + { responseType: "blob" }, + ); + + const url = window.URL.createObjectURL(new Blob([response.data])); + const a = document.createElement("a"); + a.href = url; + a.setAttribute( + "download", + submissionData.submittedFileName || + currentSubmission.fileName || + "download", + ); + document.body.appendChild(a); + a.click(); + a.remove(); + window.URL.revokeObjectURL(url); + } catch (err) { + console.error("Download error:", err); + alert("Failed to download file"); + } + }; + + const handleCreateAssignment = async (e) => { + e.preventDefault(); + + try { + await axios.post( + `http://localhost:8080/api/courses/${courseId}/assignments`, + newAssignment, + ); + alert("Assignment created successfully!"); + setNewAssignment({ + courseId: courseId, + title: "", + description: "", + dueDate: "", + }); + fetchAssignments(); + } catch (err) { + console.error("Error creating assignment:", err); + alert( + "Error creating assignment: " + + (err.response?.data?.message || err.message), + ); + } + }; + + const handleEditAssignment = (assignmentToEdit) => { + setEditAssignment(assignmentToEdit); + setNewAssignment({ + courseId: courseId, + title: assignmentToEdit.title, + description: assignmentToEdit.description, + dueDate: assignmentToEdit.dueDate.slice(0, 16), }); - - // Instructor states - const [courseSubmissions, setCourseSubmissions] = useState([]); - const [editAssignment, setEditAssignment] = useState(null); - const [showDeleteConfirm, setShowDeleteConfirm] = useState(null); - const [submissions, setSubmissions] = useState([]); - const [selectedSubmission, setSelectedSubmission] = useState(null); - const [showGrade, setShowGrade] = useState(false); - const [gradeForm, setGradeForm] = useState({ - grade: '', - feedback: '' + }; + + const cancelEdit = () => { + setEditAssignment(null); + setNewAssignment({ + courseId: courseId, + title: "", + description: "", + dueDate: "", }); - - const [newAssignment, setNewAssignment] = useState({ + }; + + const handleUpdateAssignment = async (e) => { + e.preventDefault(); + + try { + await axios.put( + `http://localhost:8080/api/courses/${editAssignment.courseId}/assignments/${editAssignment.id}`, + newAssignment, + ); + alert("Assignment updated successfully!"); + setNewAssignment({ courseId: courseId, - title: '', - description: '', - dueDate: '' + title: "", + description: "", + dueDate: "", + }); + setEditAssignment(null); + fetchAssignments(); + } catch (err) { + console.error("Error updating assignment:", err); + alert( + "Error updating assignment: " + + (err.response?.data?.message || err.message), + ); + } + }; + + const handleDeleteAssignment = async (assignmentId) => { + try { + await axios.delete( + `http://localhost:8080/api/courses/${courseId}/assignments/${assignmentId}`, + ); + alert("Assignment deleted successfully!"); + setShowDeleteConfirm(null); + fetchAssignments(); + } catch (err) { + console.error("Error deleting assignment:", err); + alert( + "Error deleting assignment: " + + (err.response?.data?.message || err.message), + ); + } + }; + + const handleGradeSubmission = (submission) => { + setSelectedSubmission(submission); + setGradeForm({ + grade: submission.grade || "", + feedback: submission.feedback || "", }); - - useEffect(() => { - if (courseId) { - fetchAssignments(); - } - }, [courseId]); - - useEffect(() => { - if (userRole === 'STUDENT' && assignmentId && studentId && courseId) { - fetchSubmissions(); - } - }, [assignmentId, userRole, studentId, courseId]); - - useEffect(() => { - if (assignmentId && assignments.length > 0) { - const foundAssignment = assignments.find(a => a.id.toString() === assignmentId); - setAssignment(foundAssignment); - } - }, [assignmentId, assignments]); - - // Fallback useEffect for assignment fetching - useEffect(() => { - if (!assignment && assignmentId) { - setLoading(true); - axios - .get(`http://localhost:8080/api/courses/${courseId}/assignments/${assignmentId}`) - .then((response) => { - setAssignment(response.data); - setLoading(false); - }) - .catch((err) => { - setError(err.message || "Assignment not found"); - setLoading(false); - }); - } - }, [courseId, assignmentId, assignment]); - - const fetchAssignments = async () => { - setLoading(true); - try { - const response = await axios.get(`http://localhost:8080/api/courses/${courseId}/assignments`); - setAssignments(response.data); - - if (userRole === 'STUDENT' && studentId) { - fetchSubmissions(); - } else if (userRole === 'INSTRUCTOR') { - fetchCourseSubmissions(); - } - setLoading(false); - } catch (err) { - setError(err.message || "Assignment not found"); - setLoading(false); - } - }; - - const fetchSubmissions = async () => { - try { - const response = await axios.get(`http://localhost:8080/api/courses/${courseId}/submissions/student/${studentId}`); - setSubmissions(response.data); - - if (assignmentId) { - const currentSubmission = response.data.find(s => - s.assignmentId && s.assignmentId.toString() === assignmentId - ); - - if (currentSubmission) { - setSubmissionData({ - grade: currentSubmission.grade, - feedback: currentSubmission.feedback, - isSubmitted: !!currentSubmission.submittedFileName, - submittedFileName: currentSubmission.submittedFileName - }); - } else { - setSubmissionData({ - grade: null, - feedback: null, - isSubmitted: false, - submittedFileName: null - }); - } - } - } catch (err) { - if (err.response?.status !== 404) { - console.error('Error fetching submissions:', err); - } - } - }; - - const fetchCourseSubmissions = async () => { - try { - if (assignmentId) { - const response = await axios.get(`http://localhost:8080/api/courses/${courseId}/submissions/${assignmentId}/submissions`); - setCourseSubmissions(response.data); - } else { - setCourseSubmissions([]); - } - } catch (err) { - if (err.response?.status === 404) { - setCourseSubmissions([]); - } else { - console.error('Error fetching assignment submissions:', err); - setCourseSubmissions([]); - } - } - }; - - const handleFileChange = (e) => { - const file = e.target.files[0]; - if (file) { - setSubmissionForm((prev) => ({ - ...prev, - fileName: file.name - })); - } - }; - - const clearFile = () => { - setSubmissionForm((prev) => ({ ...prev, fileName: "No file chosen" })); - const fileInput = document.getElementById('assignmentFile'); - if (fileInput) { - fileInput.value = ''; - } - }; - - const handleSubmit = async (e) => { - e.preventDefault(); - - try { - const fileInput = document.getElementById('assignmentFile'); - const file = fileInput.files[0]; - - if (!file) { - alert('Please select a file to submit'); - return; - } - - const formData = new FormData(); - formData.append('file', file); - - await axios.post( - `http://localhost:8080/api/courses/${courseId}/submissions/${assignmentId}/student/${studentId}`, - formData, - { - headers: { 'Content-Type': 'multipart/form-data' } - } - ); - - alert('Assignment submitted successfully!'); - - setSubmissionData(prev => ({ - ...prev, - isSubmitted: true, - submittedFileName: file.name - })); - - await fetchSubmissions(); - setSubmissionForm({text: '', fileName: 'No file chosen'}); - fileInput.value = ''; - - } catch (err) { - console.error("Submission error:", err); - alert("Failed to submit assignment"); - } - }; - - const handleDownload = async () => { - try { - const currentSubmission = submissions.find(s => - s && s.assignmentId && s.assignmentId.toString() === assignmentId - ); - - if (!currentSubmission) { - alert('Submission not found'); - return; - } - - const response = await axios.get( - `http://localhost:8080/api/courses/${courseId}/submissions/${assignmentId}/student/${studentId}/download`, - { responseType: 'blob' } - ); - - const url = window.URL.createObjectURL(new Blob([response.data])); - const a = document.createElement('a'); - a.href = url; - a.setAttribute('download', submissionData.submittedFileName || currentSubmission.fileName || 'download'); - document.body.appendChild(a); - a.click(); - a.remove(); - window.URL.revokeObjectURL(url); - } catch (err) { - console.error('Download error:', err); - alert('Failed to download file'); - } - }; - - const handleCreateAssignment = async (e) => { - e.preventDefault(); - - try { - await axios.post(`http://localhost:8080/api/courses/${courseId}/assignments`, newAssignment); - alert('Assignment created successfully!'); - setNewAssignment({courseId: courseId, title: '', description: '', dueDate: ''}); - fetchAssignments(); - } catch (err) { - console.error('Error creating assignment:', err); - alert('Error creating assignment: ' + (err.response?.data?.message || err.message)); - } - }; - - const handleEditAssignment = (assignmentToEdit) => { - setEditAssignment(assignmentToEdit); - setNewAssignment({ - courseId: courseId, - title: assignmentToEdit.title, - description: assignmentToEdit.description, - dueDate: assignmentToEdit.dueDate.slice(0, 16) - }); - }; - - const cancelEdit = () => { - setEditAssignment(null); - setNewAssignment({courseId: courseId, title: '', description: '', dueDate: ''}); - }; - - const handleUpdateAssignment = async (e) => { - e.preventDefault(); - - try { - await axios.put(`http://localhost:8080/api/courses/${editAssignment.courseId}/assignments/${editAssignment.id}`, newAssignment); - alert('Assignment updated successfully!'); - setNewAssignment({courseId: courseId, title: '', description: '', dueDate: ''}); - setEditAssignment(null); - fetchAssignments(); - } catch (err) { - console.error('Error updating assignment:', err); - alert('Error updating assignment: ' + (err.response?.data?.message || err.message)); - } - }; - - const handleDeleteAssignment = async (assignmentId) => { - try { - await axios.delete(`http://localhost:8080/api/courses/${courseId}/assignments/${assignmentId}`); - alert('Assignment deleted successfully!'); - setShowDeleteConfirm(null); - fetchAssignments(); - } catch (err) { - console.error('Error deleting assignment:', err); - alert('Error deleting assignment: ' + (err.response?.data?.message || err.message)); - } - }; - - const handleGradeSubmission = (submission) => { - setSelectedSubmission(submission); - setGradeForm({ - grade: submission.grade || '', - feedback: submission.feedback || '' - }); - setShowGrade(true); - }; - - const handleGrade = async () => { - try { - await axios.put( - `http://localhost:8080/api/courses/${courseId}/submissions/${assignmentId}/student/${selectedSubmission.studentId}`, - { - grade: gradeForm.grade, - feedback: gradeForm.feedback - } - ); - - alert('Grade and feedback saved successfully!'); - setShowGrade(false); - fetchCourseSubmissions(); - - } catch (err) { - console.error('Error saving grade:', err); - alert('Failed to save grade: ' + (err.response?.data?.message || err.message)); - } - }; - - const handleDownloadSubmission = async (submission) => { - try { - const response = await axios.get( - `http://localhost:8080/api/courses/${courseId}/submissions/${assignmentId}/student/${submission.studentId}/download`, - { responseType: 'blob' } - ); - - const url = window.URL.createObjectURL(new Blob([response.data])); - const a = document.createElement('a'); - a.href = url; - a.setAttribute('download', submission.submittedFileName || 'submission'); - document.body.appendChild(a); - a.click(); - a.remove(); - window.URL.revokeObjectURL(url); - } catch (err) { - console.error('Download error:', err); - alert('Failed to download file'); - } - }; - - const handleGoBack = () => navigate(`/course/${courseId}/assignments`); - - if (loading) return
Loading assignment...
; - if (error && userRole === 'STUDENT') return
Error: {error}
; - if (!assignment && assignmentId && userRole === 'STUDENT') return
Assignment not found!
; - - return ( -
-
- + + {/* Student Section */} + {userRole === "STUDENT" && assignmentId && assignment && ( +
+
+

+ {assignment.title} +

+

+ {assignment.description || "No description available"} +

+
+
+ + + + + Due:{" "} + {assignment.dueDate + ? new Date(assignment.dueDate).toLocaleDateString() + : "N/A"} + +
+
+
+
+
+
+ +