diff --git a/backend/pigeonhole/apps/projects/views.py b/backend/pigeonhole/apps/projects/views.py
index c411cfc9..8f606cab 100644
--- a/backend/pigeonhole/apps/projects/views.py
+++ b/backend/pigeonhole/apps/projects/views.py
@@ -1,3 +1,4 @@
+import zipfile
from os.path import basename, realpath
from django.db import transaction
@@ -15,7 +16,7 @@
from backend.pigeonhole.apps.groups.models import GroupSerializer
from backend.pigeonhole.apps.submissions.models import (
Submissions,
- SubmissionsSerializer, submission_folder_path,
+ SubmissionsSerializer,
)
from backend.pigeonhole.apps.users.models import User
from backend.pigeonhole.filters import (
@@ -25,7 +26,6 @@
)
from .models import Project, ProjectSerializer
from .permissions import CanAccessProject
-from ..submissions.views import ZipUtilities
class CsrfExemptSessionAuthentication(SessionAuthentication):
@@ -253,19 +253,22 @@ def download_submissions(self, request, *args, **kwargs):
if len(submissions) == 0:
return Response(status=status.HTTP_400_BAD_REQUEST)
- path = 'backend/downloads/submissions.zip'
- submission_folders = []
+ path = ""
- for submission in submissions:
- submission_folders.append(
- submission_folder_path(
- submission.group_id.group_id, submission.submission_id
+ if len(submissions) == 1:
+ path = submissions[0].file.path
+
+ else:
+ path = "backend/downloads/submissions.zip"
+ zipf = zipfile.ZipFile(file=path, mode="w", compression=zipfile.ZIP_STORED)
+
+ for submission in submissions:
+ zipf.write(
+ filename=submission.file.path,
+ arcname=basename(submission.file.path),
)
- )
- utilities = ZipUtilities()
- filename = path
- utilities.toZip(submission_folders, filename)
+ zipf.close()
path = realpath(path)
response = FileResponse(
diff --git a/backend/pigeonhole/apps/submissions/views.py b/backend/pigeonhole/apps/submissions/views.py
index 7710bc5c..a4c23f60 100644
--- a/backend/pigeonhole/apps/submissions/views.py
+++ b/backend/pigeonhole/apps/submissions/views.py
@@ -206,26 +206,40 @@ def download_selection(self, request, *args, **kwargs):
if not ids:
return Response(status=status.HTTP_400_BAD_REQUEST)
- path = 'backend/downloads/submissions.zip'
- submission_folders = []
+ path = ""
- for sid in ids:
- submission = Submissions.objects.get(submission_id=sid)
+ if len(ids) == 1:
+ submission = Submissions.objects.get(submission_id=ids[0])
if submission is None:
return Response(
- {"message": f"Submission with id {id} not found",
+ {"message": f"Submission with id {ids[0]} not found",
"errorcode": "ERROR_SUBMISSION_NOT_FOUND"},
- status=status.HTTP_404_NOT_FOUND
+ status=status.HTTP_404_NOT_FOUND,
)
- submission_folders.append(
- submission_folder_path(
- submission.group_id.group_id, submission.submission_id
+
+ path = submission.file.path
+
+ else:
+ path = 'backend/downloads/submissions.zip'
+ submission_folders = []
+
+ for sid in ids:
+ submission = Submissions.objects.get(submission_id=sid)
+ if submission is None:
+ return Response(
+ {"message": f"Submission with id {id} not found",
+ "errorcode": "ERROR_SUBMISSION_NOT_FOUND"},
+ status=status.HTTP_404_NOT_FOUND
+ )
+ submission_folders.append(
+ submission_folder_path(
+ submission.group_id.group_id, submission.submission_id
+ )
)
- )
- utilities = ZipUtilities()
- filename = path
- utilities.toZip(submission_folders, filename)
+ utilities = ZipUtilities()
+ filename = path
+ utilities.toZip(submission_folders, filename)
path = realpath(path)
response = FileResponse(
diff --git a/frontend/__test__/AccountMenu.test.tsx b/frontend/__test__/AccountMenu.test.tsx
index 7e605243..104a73f6 100644
--- a/frontend/__test__/AccountMenu.test.tsx
+++ b/frontend/__test__/AccountMenu.test.tsx
@@ -43,6 +43,8 @@ describe('AccountMenu', () => {
fireEvent.click(screen.getByRole('button'));
const menu = screen.getByRole('menu');
expect(menu).toBeVisible();
+ fireEvent.click(screen.getByRole('menuitem', {name: 'settings'}));
+ expect(menu).not.toBeVisible();
});
diff --git a/frontend/__test__/course_components/CancelButton.test.tsx b/frontend/__test__/course_components/CancelButton.test.tsx
new file mode 100644
index 00000000..e134106e
--- /dev/null
+++ b/frontend/__test__/course_components/CancelButton.test.tsx
@@ -0,0 +1,10 @@
+import {render, screen} from "@testing-library/react";
+import React from "react";
+import CancelButton from "@app/[locale]/components/course_components/CancelButton";
+
+describe("CancelButton", () => {
+ it("renders cancel button and click", async () => {
+ render();
+ screen.getByText(/cancel/i).click();
+ });
+});
diff --git a/frontend/app/[locale]/components/AccountMenu.tsx b/frontend/app/[locale]/components/AccountMenu.tsx
index e58ab51f..a9efdd43 100644
--- a/frontend/app/[locale]/components/AccountMenu.tsx
+++ b/frontend/app/[locale]/components/AccountMenu.tsx
@@ -20,16 +20,13 @@ import {useEffect, useState} from "react";
const backend_url = process.env['NEXT_PUBLIC_BACKEND_URL'];
export default function AccountMenu() {
- /*
- * Account menu component, used to display the user's name and a dropdown menu with options to go to the profile page and logout(right side of the navbar)
- * */
const [user, setUser] = useState(null);
const [error, setError] = useState(null);
- const [anchorEl, setAnchorEl] = React.useState(null);
- const open = Boolean(anchorEl);
const { t } = useTranslation()
useEffect(() => {
+
+
const fetchCourses = async () => {
try{
setUser(await getUserData());
@@ -42,23 +39,26 @@ export default function AccountMenu() {
fetchCourses();
}, []);
- //Utility & navigation functions
+
+
+ const [anchorEl, setAnchorEl] = React.useState(null);
+ const open = Boolean(anchorEl);
const handleClick = (event: React.MouseEvent) => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
+ //TODO: Handle settings and My profile actions!!
setAnchorEl(null);
};
const toProfile = () => {
window.location.href = '/profile'
- };
+ }
const handleLogout = () => {
setAnchorEl(null);
window.location.href = backend_url + "/auth/logout";
};
-
return (
@@ -108,6 +108,12 @@ export default function AccountMenu() {
{t('my_profile')}
+
- {user?.role !== 3 ? ( //Do not display edit button if the user is a student.
+ {user?.role !== 3 ? (
{
- /*
- * Card component displayed in the home page that represent a course
- * @param course: Course object of the course that is to be displayed in the card
- * */
const [projects, setProjects] = useState([]);
const [last_submission, setSubmission] =
useState({
@@ -48,7 +44,7 @@ const CourseCard = ({params: {course}}: { params: { course: Course } }) => {
};
fetchProjects();
- }, [course.course_id, last_submission, projects]);
+ }, [course.course_id]);
diff --git a/frontend/app/[locale]/components/CourseControls.tsx b/frontend/app/[locale]/components/CourseControls.tsx
index 16de8f8c..d70fd1fc 100644
--- a/frontend/app/[locale]/components/CourseControls.tsx
+++ b/frontend/app/[locale]/components/CourseControls.tsx
@@ -10,11 +10,6 @@ import {useTranslation} from "react-i18next";
import {APIError, fetchUserData, UserData} from "@lib/api";
const CourseControls = ({selectedYear, onYearChange}) => {
- /*
- * Component containing the text and buttons displayed at the top of the home page
- * @param selectedYear: currently selected year
- * @param onYearChange: function that shows course cards of the selected year
- * */
const currentYear = new Date().getFullYear();
const academicYear = `${currentYear - 1}-${currentYear.toString().slice(-2)}`;
@@ -38,7 +33,9 @@ const CourseControls = ({selectedYear, onYearChange}) => {
setLoading(false);
}, []);
- // displayed academic year
+
+
+
const years = [
`${currentYear - 2}-${(currentYear - 1).toString().slice(-2)}`,
academicYear,
@@ -108,7 +105,7 @@ const CourseControls = ({selectedYear, onYearChange}) => {
height={'fit-content'}
gap={2}
>
- {user?.role !== 3 ? ( // Students may not see the add course button.
+ {user?.role !== 3 ? (
+ )
+ }
}
export default Footer;
\ No newline at end of file
diff --git a/frontend/app/[locale]/components/GroupSubmissionList.tsx b/frontend/app/[locale]/components/GroupSubmissionList.tsx
index 185d4220..04f67477 100644
--- a/frontend/app/[locale]/components/GroupSubmissionList.tsx
+++ b/frontend/app/[locale]/components/GroupSubmissionList.tsx
@@ -8,16 +8,10 @@ import CalendarMonthIcon from '@mui/icons-material/CalendarMonth';
import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline';
const GroupSubmissionList = ({project_id, page_size = 5, search}: {
- project_id: number,
- page_size: number,
- search: string
- }) => {
- /*
- * Component that displays the list of group submissions(used in the project details page)
- * @param project_id: id of the project
- * @param page_size: number of items per page(for the listview pagination)
- * @param search: search text
- */
+ project_id: number,
+ page_size: number,
+ search: string
+}) => {
const {t} = useTranslation()
const headers = [
{" " + t('group_number')},
diff --git a/frontend/app/[locale]/components/HomeButton.tsx b/frontend/app/[locale]/components/HomeButton.tsx
index cb4ce555..28196158 100644
--- a/frontend/app/[locale]/components/HomeButton.tsx
+++ b/frontend/app/[locale]/components/HomeButton.tsx
@@ -5,9 +5,6 @@ import { Button, Typography } from '@mui/material'
import Link from "next/link";
const HomeButton = () => {
- /*
- * Button that redirects to the home page, displayed in the header
- */
return (
diff --git a/frontend/app/[locale]/components/JoinCourseWithToken.tsx b/frontend/app/[locale]/components/JoinCourseWithToken.tsx
index 099b50dc..cb95515e 100644
--- a/frontend/app/[locale]/components/JoinCourseWithToken.tsx
+++ b/frontend/app/[locale]/components/JoinCourseWithToken.tsx
@@ -3,14 +3,9 @@ import {useEffect, useState} from 'react';
import {getUserData, joinCourseUsingToken} from '@lib/api';
const JoinCourseWithToken = ({token, course_id}: { token: any, course_id: any }) => {
- /*
- * Component that joins the user to the course using the token, and redirects to the course page.
- * The component is invisible to the user and is used in the course page.
- * @param token: token used to join the course
- * @param course_id: id of the course
- */
const [joined, setJoined] = useState(false);
+
useEffect(() => {
const join = async () => {
// check the token, if it exists, try joining the course
diff --git a/frontend/app/[locale]/components/LanguageSelect.tsx b/frontend/app/[locale]/components/LanguageSelect.tsx
index eea1f6f4..dc1d21b6 100644
--- a/frontend/app/[locale]/components/LanguageSelect.tsx
+++ b/frontend/app/[locale]/components/LanguageSelect.tsx
@@ -7,17 +7,11 @@ import { useTranslation } from 'react-i18next';
import i18nConfig from '../../../i18nConfig';
const LanguageSelect = () => {
- /*
- * This component is a language select dropdown that allows the user to change the language of the website.
- * It uses the i18n hook to get the current locale and the router to redirect to the new locale path.
- * It is used in the NavBar component.
- */
const { i18n } = useTranslation();
const currentLocale = i18n.language;
const router = useRouter();
let currentPathname = usePathname();
- // handle change of language
const handleChange = (e: SelectChangeEvent) => {
const newLocale = e.target.value;
diff --git a/frontend/app/[locale]/components/ListView.tsx b/frontend/app/[locale]/components/ListView.tsx
index 583222a8..82e85d61 100644
--- a/frontend/app/[locale]/components/ListView.tsx
+++ b/frontend/app/[locale]/components/ListView.tsx
@@ -4,10 +4,14 @@ import {
Box,
Button,
Checkbox,
+ Container,
CssBaseline,
Typography,
+ IconButton,
TextField,
tableCellClasses,
+ TableSortLabel,
+ TablePagination,
Table,
TableBody,
TableCell,
@@ -21,12 +25,15 @@ import {
} from '@mui/material';
import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp';
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
+import CropSquareIcon from '@mui/icons-material/CropSquare';
import {styled} from '@mui/system';
import {NextPage} from 'next';
+import checkMarkImage from './check-mark.png';
import CheckIcon from '@mui/icons-material/Check';
import CancelIcon from "@mui/icons-material/Cancel";
import {
- getArchivedCourses,
+ deleteData, getArchivedCourses,
+ getCourses,
getGroups_by_project,
getGroupSubmissions,
getProject,
@@ -35,6 +42,7 @@ import {
getStudents_by_course,
getTeachers_by_course,
getUser,
+ getUserData,
getUsers,
postData,
getOpenCourses,
@@ -42,6 +50,7 @@ import {
} from '@lib/api';
import baseTheme from "../../../styles/theme";
import {useTranslation} from "react-i18next";
+import StudentCoTeacherButtons from './StudentCoTeacherButtons';
const backend_url = process.env['NEXT_PUBLIC_BACKEND_URL'];
diff --git a/frontend/app/[locale]/components/LoginCard.tsx b/frontend/app/[locale]/components/LoginCard.tsx
index 46eb23d8..15f9e572 100644
--- a/frontend/app/[locale]/components/LoginCard.tsx
+++ b/frontend/app/[locale]/components/LoginCard.tsx
@@ -5,9 +5,6 @@ import Image from 'next/image';
import logo from '../../../public/logo.png';
const LoginCard: React.FC = () => {
- /*
- * This component is the login card that is displayed on the login page.
- */
return (
diff --git a/frontend/app/[locale]/components/NavBar.tsx b/frontend/app/[locale]/components/NavBar.tsx
index efe0db10..a8d7dfdc 100644
--- a/frontend/app/[locale]/components/NavBar.tsx
+++ b/frontend/app/[locale]/components/NavBar.tsx
@@ -30,14 +30,9 @@ import {APIError, Course, getCoursesForUser, UserData, getUserData} from "@lib/a
const backend_url = process.env['NEXT_PUBLIC_BACKEND_URL'];
const NavBar = () => {
- /*
- * This component is the navigation bar that is displayed at the top of the page.
- * It contains the menu button that opens the drawer with the course list and the bottom menu items.
- */
const [courses, setCourses] = useState([]); // Initialize courses as an empty array
const [user, setUser] = useState(null);
const [error, setError] = useState(null);
- const [open, setOpen] = React.useState(false);
const {t} = useTranslation();
useEffect(() => {
@@ -80,10 +75,14 @@ const NavBar = () => {
window.location.href = backend_url + "/auth/logout";
};
+ const [open, setOpen] = React.useState(false);
+
const toggleDrawer = (newOpen: boolean) => () => {
setOpen(newOpen);
};
+ //const courses = ["Course1", "Course2", "Course3", "Course4"];
+
const DrawerList = (
{
- /*
- * This component is the profile card that is displayed on the profile page.
- * It displays the user's profile picture, name, email, role and a button to edit the account.
- */
const [user, setUser] = useState({
id: 0,
email: "",
diff --git a/frontend/app/[locale]/components/ProfileEditCard.tsx b/frontend/app/[locale]/components/ProfileEditCard.tsx
index 42e928bd..03f5f85c 100644
--- a/frontend/app/[locale]/components/ProfileEditCard.tsx
+++ b/frontend/app/[locale]/components/ProfileEditCard.tsx
@@ -15,9 +15,6 @@ import {APIError, getImage, getUserData, updateUserData, UserData} from "@lib/ap
import {useTranslation} from "react-i18next";
const ProfileEditCard = () => {
- /*
- * This component is the profile edit card that is displayed on the profile edit page.
- */
const [user, setUser] = useState({
id: 0,
email: "",
diff --git a/frontend/app/[locale]/components/ProjectCalendar.tsx b/frontend/app/[locale]/components/ProjectCalendar.tsx
index d9a0cf03..15524bc9 100644
--- a/frontend/app/[locale]/components/ProjectCalendar.tsx
+++ b/frontend/app/[locale]/components/ProjectCalendar.tsx
@@ -2,14 +2,13 @@
import React, { useState, useRef, useEffect } from 'react';
import { DateCalendar, PickersDay, PickersDayProps } from '@mui/x-date-pickers';
-import { Box, Typography, Paper, List, ListItem, Divider, Badge, Skeleton } from '@mui/material';
+import { CircularProgress, Box, Typography, Paper, List, ListItem, Divider, Badge, Skeleton } from '@mui/material';
import ScheduleIcon from '@mui/icons-material/Schedule';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
import { useProjects } from '../calendar/useProjects';
import { useTranslation } from 'react-i18next';
-// Fake fetch function that simulates fetching deadlines from the server
function fakeFetch(
date: Date,
{ signal }: { signal: AbortSignal },
@@ -33,11 +32,6 @@ function fakeFetch(
}
const ProjectCalendar: React.FC = () => {
- /*
- * This component is the project calendar that is displayed in the calendar page.
- * It displays a calendar with highlighted days that have projects due on that day.
- * It also displays the projects due on the selected day.
- */
const requestAbortController = useRef(null);
const [value, setValue] = useState(new Date());
const [highlightedDays, setHighlightedDays] = useState([]);
@@ -45,7 +39,6 @@ const ProjectCalendar: React.FC = () => {
const { projects, loading, error } = useProjects();
const { t } = useTranslation();
- // Fetch highlighted days from the server
const fetchHighlightedDays = (date: Date) => {
const controller = new AbortController();
fakeFetch(
@@ -68,7 +61,6 @@ const ProjectCalendar: React.FC = () => {
requestAbortController.current = controller;
};
- // Fetch highlighted days when the component mounts
useEffect(() => {
try {
fetchHighlightedDays(new Date());
@@ -80,7 +72,6 @@ const ProjectCalendar: React.FC = () => {
return () => requestAbortController.current?.abort();
}, [projects]);
- // Loading state
if (loading || loadingCalendar) {
return(
{
);
};
- // Handle month and year change(refetch highlighted days when month or year changes)
const handleMonthChange = (date: Date) => {
if (requestAbortController.current) {
requestAbortController.current.abort();
@@ -141,7 +131,6 @@ const ProjectCalendar: React.FC = () => {
fetchHighlightedDays(date);
};
- // Render projects on the selected day
const renderProjects = (date: Date) => {
const projectsOnThisDay = projects.filter((project) =>
isSameDay(new Date(project.deadline), date)
@@ -164,7 +153,6 @@ const ProjectCalendar: React.FC = () => {
);
};
- // Custom day component that displays a badge with a schedule icon if the day has a project due
function customDay(props: PickersDayProps & { highlightedDays?: number[] }) {
const { highlightedDays = [], day, outsideCurrentMonth, ...other } = props;
diff --git a/frontend/app/[locale]/components/ProjectDetailsPage.tsx b/frontend/app/[locale]/components/ProjectDetailsPage.tsx
index 2235cc56..0e6b71fd 100644
--- a/frontend/app/[locale]/components/ProjectDetailsPage.tsx
+++ b/frontend/app/[locale]/components/ProjectDetailsPage.tsx
@@ -28,15 +28,9 @@ interface ProjectDetailsPageProps {
}
const ProjectDetailsPage: React.FC = ({
- locale,
- project_id,
- }) => {
- /*
- * This component is the project details page that is displayed when a user clicks on a project.
- * It displays the project details, submissions and groups.
- * @param locale: The locale used for the translations
- * @param project_id: The id of the project
- */
+ locale,
+ project_id,
+}) => {
const { t } = useTranslation();
const [project, setProject] = useState();
@@ -307,7 +301,6 @@ const ProjectDetailsPage: React.FC = ({
);
};
-// Function to build a tree structure from a list of paths
function buildTree(paths) {
const tree = {};
if (!paths) {
@@ -334,7 +327,6 @@ function buildTree(paths) {
return tree;
}
-// Function to build a string representation of a tree structure
function buildTreeString(tree, indent = '') {
let treeString = '';
diff --git a/frontend/app/[locale]/components/ProjectReturnButton.tsx b/frontend/app/[locale]/components/ProjectReturnButton.tsx
index aed0068b..aa561222 100644
--- a/frontend/app/[locale]/components/ProjectReturnButton.tsx
+++ b/frontend/app/[locale]/components/ProjectReturnButton.tsx
@@ -10,11 +10,6 @@ interface ProjectReturnButtonProps {
}
const ProjectReturnButton: React.FC = ({locale, project_id}) => {
- /*
- * This component is the return button that is displayed on the project page.
- * @param locale: The current locale of the page
- * @param project_id: The id of the project
- */
const {t} = useTranslation();
return (
diff --git a/frontend/app/[locale]/components/ProjectSubmissionsList.tsx b/frontend/app/[locale]/components/ProjectSubmissionsList.tsx
index ffe68802..4d488ec4 100644
--- a/frontend/app/[locale]/components/ProjectSubmissionsList.tsx
+++ b/frontend/app/[locale]/components/ProjectSubmissionsList.tsx
@@ -9,16 +9,10 @@ import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline';
const ProjectSubmissionsList = ({project_id, page_size = 5, search}: {
- project_id: number,
- page_size: number,
- search: string
- }) => {
- /*
- * This component is the list of submissions that is displayed on the project page.
- * @param project_id: The id of the project
- * @param page_size: The number of submissions to display per page
- * @param search: The search text to filter submissions
- */
+ project_id: number,
+ page_size: number,
+ search: string
+}) => {
const {t} = useTranslation()
const headers = [
{" " + t('group_number')}
diff --git a/frontend/app/[locale]/components/StatusButton.tsx b/frontend/app/[locale]/components/StatusButton.tsx
index f6217b6d..72d5841f 100644
--- a/frontend/app/[locale]/components/StatusButton.tsx
+++ b/frontend/app/[locale]/components/StatusButton.tsx
@@ -10,15 +10,9 @@ interface StatusButtonProps {
fileIndex: number,
}
-function StatusButton({files, setFiles, fileIndex}: StatusButtonProps,) {
- /*
- * This component is a button that displays the status of a file.
- * The status can be one of three values: +, ~ or -, which correspond to required, optional or forbidden.
- * The button cycles through these values when clicked.
- * @param files: The list of files that the status button is associated with
- * @param setFiles: The function to update the list of files
- * @param fileIndex: The index of the file in the list of files
- */
+function StatusButton(
+ {files, setFiles, fileIndex}: StatusButtonProps,
+) {
const [statusIndex, setStatusIndex] = useState(getStart(files[fileIndex]));
const statuses = [
{ icon: },
diff --git a/frontend/app/[locale]/components/StudentCoTeacherButtons.tsx b/frontend/app/[locale]/components/StudentCoTeacherButtons.tsx
index 2365f7a6..6f40e418 100644
--- a/frontend/app/[locale]/components/StudentCoTeacherButtons.tsx
+++ b/frontend/app/[locale]/components/StudentCoTeacherButtons.tsx
@@ -2,18 +2,13 @@
import {Box, Button} from "@mui/material";
import {useTranslation} from "react-i18next";
import {useEffect, useState} from "react";
-import {APIError, getUserData, UserData} from "@lib/api";
+import {APIError, Course, getCourse, getProjectsFromCourse, getUserData, UserData} from "@lib/api";
interface StudentCoTeacherButtonsProps {
course_id:number
}
const StudentCoTeacherButtons = ({course_id}: StudentCoTeacherButtonsProps) => {
- /*
- * This component displays the student and co-teacher buttons on the course page.
- * It allows the user to view the students and co-teachers of the course.
- * @param course_id: The id of the course
- s*/
const [user, setUser] = useState(null);
const [error, setError] = useState(null);
const {t} = useTranslation()
diff --git a/frontend/app/[locale]/components/SubmissionDetailsPage.tsx b/frontend/app/[locale]/components/SubmissionDetailsPage.tsx
index 616be775..fbef3e31 100644
--- a/frontend/app/[locale]/components/SubmissionDetailsPage.tsx
+++ b/frontend/app/[locale]/components/SubmissionDetailsPage.tsx
@@ -18,12 +18,6 @@ interface SubmissionDetailsPageProps {
}
const SubmissionDetailsPage: React.FC = ({ locale, submission_id }) => {
- /*
- * This component displays the submission details page.
- * It shows the evaluation status of the submission, the uploaded files and the artifacts.
- * @param locale: The locale used for the translation
- * @param submission_id: The id of the submission
- */
const { t } = useTranslation();
const [submission, setSubmission] = useState();
diff --git a/frontend/app/[locale]/components/SubmitDetailsPage.tsx b/frontend/app/[locale]/components/SubmitDetailsPage.tsx
index 8d1af333..8adc50ca 100644
--- a/frontend/app/[locale]/components/SubmitDetailsPage.tsx
+++ b/frontend/app/[locale]/components/SubmitDetailsPage.tsx
@@ -34,15 +34,9 @@ interface SubmitDetailsPageProps {
}
const SubmitDetailsPage: React.FC = ({
- locale,
- project_id,
- }) => {
- /*
- * This component is the submit details page that is displayed when the user wants to submit a project.
- * It allows the user to upload folders and files to submit the project.
- * @param locale: The locale used for the translations
- * @param project_id: The id of the project
- */
+ locale,
+ project_id,
+}) => {
const { t } = useTranslation();
const [projectData, setProjectData] = useState();
diff --git a/frontend/app/[locale]/components/YearStateComponent.tsx b/frontend/app/[locale]/components/YearStateComponent.tsx
index ac6a824f..a4b7f2db 100644
--- a/frontend/app/[locale]/components/YearStateComponent.tsx
+++ b/frontend/app/[locale]/components/YearStateComponent.tsx
@@ -6,10 +6,6 @@ import React, {useState} from "react";
import {useTranslation} from "react-i18next";
const YearStateComponent = () => {
- /*
- * This component displays the course controls and the courses grid.
- * It allows the user to select the academic year and view the courses.
- */
const currentYear = new Date().getFullYear();
const academicYear = `${currentYear - 1}-${currentYear.toString().slice(-2)}`;
const [selectedYear, setSelectedYear] = useState(academicYear);
diff --git a/frontend/app/[locale]/components/admin_components/UserList.tsx b/frontend/app/[locale]/components/admin_components/UserList.tsx
index 5f4ff045..ad54df46 100644
--- a/frontend/app/[locale]/components/admin_components/UserList.tsx
+++ b/frontend/app/[locale]/components/admin_components/UserList.tsx
@@ -7,10 +7,6 @@ import {useTranslation} from "react-i18next";
const UserList = () => {
- /*
- * This component displays the list of users.
- * It allows the admin to remove users.
- */
const {t} = useTranslation();
const headers = [
diff --git a/frontend/app/[locale]/components/course_components/ArchiveButton.tsx b/frontend/app/[locale]/components/course_components/ArchiveButton.tsx
index ef85fce6..8a94e3cd 100644
--- a/frontend/app/[locale]/components/course_components/ArchiveButton.tsx
+++ b/frontend/app/[locale]/components/course_components/ArchiveButton.tsx
@@ -11,10 +11,6 @@ interface ArchiveButtonProps {
}
const ArchiveButton = ({course_id}: ArchiveButtonProps) => {
- /*
- * This component displays the archive button for a course.
- * @param course_id: The id of the course
- */
const [error, setError] = useState(null);
const [archived, setArchived] = useState(false);
const {t} = useTranslation()
diff --git a/frontend/app/[locale]/components/course_components/CancelButton.tsx b/frontend/app/[locale]/components/course_components/CancelButton.tsx
new file mode 100644
index 00000000..2b62cb8d
--- /dev/null
+++ b/frontend/app/[locale]/components/course_components/CancelButton.tsx
@@ -0,0 +1,34 @@
+'use client';
+
+import React from 'react'
+import {useTranslation} from "react-i18next";
+
+const CancelButton = () => {
+ const {t} = useTranslation()
+
+ const handleCancel = () => {
+ window.location.href = "/home";
+ }
+
+ return (
+
+
+
+
+ )
+}
+
+export default CancelButton
\ No newline at end of file
diff --git a/frontend/app/[locale]/components/course_components/DeleteButton.tsx b/frontend/app/[locale]/components/course_components/DeleteButton.tsx
index e3d1ca27..67094e37 100644
--- a/frontend/app/[locale]/components/course_components/DeleteButton.tsx
+++ b/frontend/app/[locale]/components/course_components/DeleteButton.tsx
@@ -1,67 +1,63 @@
-'use client';
-
-import React, { useState } from 'react';
-import { useTranslation } from "react-i18next";
-import { deleteCourse } from "@lib/api";
-import { Button, Dialog, DialogActions, DialogTitle } from '@mui/material';
-
-interface DeleteButtonProps {
- courseId: number
-}
-
-const DeleteButton = ({ courseId }: DeleteButtonProps) => {
- /*
- * This component displays the delete button for a course.
- * @param courseId: The id of the course
- */
- const { t } = useTranslation();
- const [open, setOpen] = useState(false);
-
- const handleOpen = () => {
- setOpen(true);
- };
-
- const handleClose = () => {
- setOpen(false);
- };
-
- const handleDelete = async () => {
- await deleteCourse(courseId);
- window.location.href = "/home";
- };
-
- return (
- <>
-
-
- >
- );
-};
-
-export default DeleteButton;
+'use client';
+
+import React, { useState } from 'react';
+import { useTranslation } from "react-i18next";
+import { deleteCourse } from "@lib/api";
+import { Button, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, Typography } from '@mui/material';
+
+interface DeleteButtonProps {
+ courseId: number
+}
+
+const DeleteButton = ({ courseId }: DeleteButtonProps) => {
+ const { t } = useTranslation();
+ const [open, setOpen] = useState(false);
+
+ const handleOpen = () => {
+ setOpen(true);
+ };
+
+ const handleClose = () => {
+ setOpen(false);
+ };
+
+ const handleDelete = async () => {
+ await deleteCourse(courseId);
+ window.location.href = "/home";
+ };
+
+ return (
+ <>
+
+
+ >
+ );
+};
+
+export default DeleteButton;
diff --git a/frontend/app/[locale]/components/general/ItemsList.tsx b/frontend/app/[locale]/components/general/ItemsList.tsx
index a353e112..e2564ed1 100644
--- a/frontend/app/[locale]/components/general/ItemsList.tsx
+++ b/frontend/app/[locale]/components/general/ItemsList.tsx
@@ -14,14 +14,6 @@ interface ItemsListProps {
}
const ItemsList = ({items, setItems, input_placeholder, empty_list_placeholder, button_text}: ItemsListProps) => {
- /*
- * This component displays a list of items and allows the user to add and delete items.
- * @param items: The list of items
- * @param setItems: The function to set the list of items
- * @param input_placeholder: The placeholder for the input field
- * @param empty_list_placeholder: The placeholder for the list when it is empty
- * @param button_text: The text for the button
- */
const [newItem, setNewItem] = useState('')
const [noInput, setNoInput] = useState(false)
diff --git a/frontend/app/[locale]/components/general/RequiredFilesList.tsx b/frontend/app/[locale]/components/general/RequiredFilesList.tsx
index 983b09b8..5cd34792 100644
--- a/frontend/app/[locale]/components/general/RequiredFilesList.tsx
+++ b/frontend/app/[locale]/components/general/RequiredFilesList.tsx
@@ -26,18 +26,6 @@ const ItemsList = ({
items_status,
setItemsStatus
}: ItemsListProps) => {
- /*
- * This component is a variation of the ItemsList that works specifically for the required files of a project.
- * It displays a list of files and allows the user to add and delete files.
- * It also allows the user to set the status of the files.
- * @param items: The list of files
- * @param setItems: The function to set the list of files
- * @param input_placeholder: The placeholder for the input field
- * @param empty_list_placeholder: The placeholder for the list when it is empty
- * @param button_text: The text for the button
- * @param items_status: The list of statuses for the files
- * @param setItemsStatus: The function to set the list of statuses for the files
- */
const [newItem, setNewItem] = useState('')
const [noInput, setNoInput] = useState(false)
const {t} = useTranslation();
diff --git a/frontend/app/[locale]/components/project_components/testfiles.tsx b/frontend/app/[locale]/components/project_components/testfiles.tsx
index a98ff9b8..c3bf135e 100644
--- a/frontend/app/[locale]/components/project_components/testfiles.tsx
+++ b/frontend/app/[locale]/components/project_components/testfiles.tsx
@@ -14,14 +14,6 @@ interface TestFilesProps {
}
function TestFiles({testfilesName, setTestfilesName, testfilesData, setTestfilesData}: TestFilesProps) {
- /*
- * This component displays the list of test files for a project.
- * It allows the user to delete test files.
- * @param testfilesName: The list of names of the test files
- * @param setTestfilesName: The function to set the list of names of the test files
- * @param testfilesData: The list of data of the test files
- * @param setTestfilesData: The function to set the list of data of the test files
- */
const {t} = useTranslation();
return
diff --git a/frontend/app/[locale]/components/project_components/title.tsx b/frontend/app/[locale]/components/project_components/title.tsx
index 2862f183..2c4f24fe 100644
--- a/frontend/app/[locale]/components/project_components/title.tsx
+++ b/frontend/app/[locale]/components/project_components/title.tsx
@@ -13,15 +13,6 @@ interface TitleProps {
}
function Title({isTitleEmpty, setTitle, title, score, isScoreEmpty, setScore}: TitleProps) {
- /*
- * This component displays the title and the maximum score of a project.
- * @param isTitleEmpty: A boolean that indicates if the title is empty
- * @param setTitle: The function to set the title
- * @param title: The title of the project
- * @param score: The maximum score of the project
- * @param isScoreEmpty: A boolean that indicates if the score is empty
- * @param setScore: The function to set the score
- */
const {t} = useTranslation();
const handleScoreChange = (event: any) => {
diff --git a/frontend/app/[locale]/components/project_components/uploadButton.tsx b/frontend/app/[locale]/components/project_components/uploadButton.tsx
index 71258d7b..b4644d0b 100644
--- a/frontend/app/[locale]/components/project_components/uploadButton.tsx
+++ b/frontend/app/[locale]/components/project_components/uploadButton.tsx
@@ -11,19 +11,14 @@ interface UploadTestFileProps {
setTestfilesData: (value: (((prevState: JSZipObject[]) => JSZipObject[]) | JSZipObject[])) => void,
}
-function UploadTestFile({
+function UploadTestFile(
+ {
testfilesName,
setTestfilesName,
testfilesData,
setTestfilesData,
- }: UploadTestFileProps) {
- /*
- * This component allows the user to upload test files for a project.
- * @param testfilesName: The list of names of the test files
- * @param setTestfilesName: The function to set the list of names of the test files
- * @param testfilesData: The list of data of the test files
- * @param setTestfilesData: The function to set the list of data of the test files
- */
+ }: UploadTestFileProps
+) {
const {t} = useTranslation();
const handleFileChange = async (event: any) => {
let zip = new JSZip();
diff --git a/frontend/app/[locale]/components/user_components/CancelButton.tsx b/frontend/app/[locale]/components/user_components/CancelButton.tsx
index acb17c78..b9817030 100644
--- a/frontend/app/[locale]/components/user_components/CancelButton.tsx
+++ b/frontend/app/[locale]/components/user_components/CancelButton.tsx
@@ -4,9 +4,6 @@ import React from 'react'
import {useTranslation} from "react-i18next";
const CancelButton = () => {
- /*
- * This component displays the cancel button.
- */
const {t} = useTranslation()
const handleCancel = () => {
diff --git a/frontend/app/[locale]/components/user_components/DeleteButton.tsx b/frontend/app/[locale]/components/user_components/DeleteButton.tsx
index 03eceb3b..390c9f59 100644
--- a/frontend/app/[locale]/components/user_components/DeleteButton.tsx
+++ b/frontend/app/[locale]/components/user_components/DeleteButton.tsx
@@ -3,17 +3,13 @@
import React, { useState } from 'react';
import { useTranslation } from "react-i18next";
import { deleteUser } from "@lib/api";
-import { Button, Dialog, DialogActions, DialogTitle, Typography } from '@mui/material';
+import { Button, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, Typography } from '@mui/material';
interface DeleteButtonProps {
userId: number
}
const DeleteButton = ({ userId }: DeleteButtonProps) => {
- /*
- * This component displays the delete button for a user.
- * @param userId: The id of the user
- */
const { t } = useTranslation();
const [open, setOpen] = useState(false);
diff --git a/frontend/app/[locale]/project/[project_id]/edit/projectEditForm.tsx b/frontend/app/[locale]/project/[project_id]/edit/projectEditForm.tsx
index ef3100f9..a7a9ee17 100644
--- a/frontend/app/[locale]/project/[project_id]/edit/projectEditForm.tsx
+++ b/frontend/app/[locale]/project/[project_id]/edit/projectEditForm.tsx
@@ -89,13 +89,13 @@ function ProjectEditForm({project_id, add_course_id}: ProjectEditFormProps) {
if (project.deadline !== null) setDeadline(dayjs(project["deadline"]));
setDescription(project.description)
if (project.file_structure !== null && project.file_structure !== "") {
+ console.log(project.file_structure)
const file_structure = project.file_structure.split(",").map((item: string) => item.trim().replace(/"/g, ''));
const file_structure_status = file_structure.map((item: string) => item[0]);
const file_structure_name = file_structure.map((item: string) => item.substring(1));
setFiles(file_structure_name);
setStatusFiles(file_structure_status);
}
- setDockerImage(project["test_docker_image"])
setGroupSize(project["group_size"])
setTitle(project["name"])
setGroupAmount(project["number_of_groups"])