Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Course views for teacher #161

Merged
merged 45 commits into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
e267e55
teacher detailed course base project list
JibrilExe Mar 27, 2024
673a140
basic
JibrilExe Mar 27, 2024
2b941a9
Merge branch 'development' into frontend/feature/coursesteacher
JibrilExe Mar 31, 2024
3907358
scrollers
JibrilExe Mar 31, 2024
2450ba9
Merge branch 'development' into frontend/feature/coursesteacher
JibrilExe Apr 1, 2024
3e99550
doc
JibrilExe Apr 1, 2024
dc98d2a
backtick strings
JibrilExe Apr 1, 2024
1fa7210
base all courses page
JibrilExe Apr 1, 2024
17c597e
changed height
JibrilExe Apr 2, 2024
d70e61a
merged with dev
JibrilExe Apr 2, 2024
a0f296c
first finished version of teacher course views
JibrilExe Apr 2, 2024
e21c049
merged with dev
JibrilExe Apr 3, 2024
aba444f
teacher all course page reviewed
JibrilExe Apr 4, 2024
0fd3537
display time until deadline
JibrilExe Apr 4, 2024
772ab0c
more searchbars and translations
JibrilExe Apr 13, 2024
7ea55c1
Merge branch 'development' into frontend/feature/coursesteacher
JibrilExe Apr 13, 2024
4e803ad
changed file structure for maintainability
JibrilExe Apr 13, 2024
77aad27
titles and absolute create button
JibrilExe Apr 13, 2024
673f53e
searchbars update url and remain on reload
JibrilExe Apr 13, 2024
866ad2d
user and admin listing
JibrilExe Apr 13, 2024
6ea09e5
Merge branch 'development' into frontend/feature/coursesteacher
JibrilExe Apr 13, 2024
b3088ec
reworked form and gave unique ids to all list items
JibrilExe Apr 13, 2024
8758e97
whoops linter ssst
JibrilExe Apr 13, 2024
c0d5a0e
added .env to gitignore
JibrilExe Apr 14, 2024
014931e
placeholder for loading courses
JibrilExe Apr 14, 2024
4b1662f
debounce seachbars
JibrilExe Apr 14, 2024
0c20f48
better debouncing more hooks
JibrilExe Apr 14, 2024
22dc78a
setup for loader but doesnt work yet bc bad router
JibrilExe Apr 14, 2024
44149c0
Merge branch 'development' into frontend/feature/coursesteacher
JibrilExe Apr 15, 2024
dba8ac5
loaders
JibrilExe Apr 15, 2024
a279a6d
course detail teacher course join codes menu
JibrilExe Apr 15, 2024
0b3f202
join code link points to app host now
JibrilExe Apr 15, 2024
c1bbf75
accident
JibrilExe Apr 15, 2024
bff0a8a
Merge branch 'development' into frontend/feature/coursesteacher
JibrilExe Apr 16, 2024
16d495a
fixed empty filters, placeholders and teacher in admin list
JibrilExe Apr 16, 2024
fbc9cc3
reworked
JibrilExe Apr 18, 2024
139d942
delete
JibrilExe Apr 18, 2024
3bfad45
Merge branch 'development' into frontend/feature/coursesteacher
JibrilExe Apr 18, 2024
a381494
removed wannabe popup errorer
JibrilExe Apr 18, 2024
32dbf90
unuserud
JibrilExe Apr 18, 2024
82462c8
merged dev and fix translation
JibrilExe Apr 19, 2024
0af039b
package
JibrilExe Apr 19, 2024
6e637cb
fix
JibrilExe Apr 19, 2024
965dda9
uhh
JibrilExe Apr 19, 2024
e2e8bed
u
JibrilExe Apr 19, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions backend/project/endpoints/authentication/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,6 @@ def microsoft_authentication():
res = requests.post(f"https://login.microsoftonline.com/{TENANT_ID}/oauth2/v2.0/token",
data=data,
timeout=5)
if res.status_code != 200:
abort(make_response((
{"message":
"An error occured while trying to authenticate your authorization code"},
500)))
token = res.json()["access_token"]
profile_res = requests.get("https://graph.microsoft.com/v1.0/me",
headers={"Authorization":f"Bearer {token}"},
Expand Down
2 changes: 1 addition & 1 deletion backend/project/endpoints/authentication/me.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def get(self):
"""
Will return all user data associated with the access token in the request
"""
uid = get_jwt_identity
uid = get_jwt_identity()

return query_by_id_from_model(User,
"uid",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def get(self, course_id):
return query_selected_from_model(
CourseShareCode,
urljoin(f"{RESPONSE_URL}/", f"{str(course_id)}/", "join_codes"),
select_values=["join_code", "expiry_time"],
select_values=["join_code", "expiry_time", "for_admins"],
filters={"course_id": course_id}
)

Expand Down
4 changes: 2 additions & 2 deletions backend/project/models/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,6 @@ def to_dict(self):
"""
return {
'uid': self.uid,
'role': self.role.name, # Convert the enum to a string
'display_name': self.display_name
'display_name': self.display_name,
'role': self.role.name # Convert the enum to a string
}
2 changes: 1 addition & 1 deletion backend/project/utils/models/user_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def get_user(user_id):
db.session.rollback()
abort(make_response(({"message": "An error occurred while fetching the user"}
, 500)))
if not user:
if user is None:
abort(make_response(({"message":f"User with id: {user_id} not found"}, 404)))
return user

Expand Down
2 changes: 1 addition & 1 deletion backend/project/utils/query_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ def query_by_id_from_model(model: DeclarativeMeta,
if not result:
return {"message": "Resource not found", "url": base_url}, 404
return {
"data": result,
"data": result.to_dict() if hasattr(result, "to_dict") else result,
"message": "Resource fetched correctly",
"url": urljoin(f"{base_url}/", str(column_id))}, 200
except SQLAlchemyError:
Expand Down
2 changes: 2 additions & 0 deletions frontend/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ dist
dist-ssr
*.local

.env

# Editor directories and files
.vscode/*
!.vscode/extensions.json
Expand Down
22 changes: 17 additions & 5 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 5 additions & 4 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,17 @@
"test": "npm run cypress:test"
},
"dependencies": {
"@emotion/react": "^11.11.3",
"@emotion/styled": "^11.11.0",
"@mui/icons-material": "^5.15.10",
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.5",
"@mui/icons-material": "^5.15.15",
"@mui/material": "^5.15.15",
"@mui/lab": "^5.0.0-alpha.170",
"@mui/material": "^5.15.10",
"@mui/styled-engine-sc": "^6.0.0-alpha.16",
"@mui/x-data-grid": "^7.1.1",
"@mui/x-date-pickers": "^7.1.1",
"axios": "^1.6.8",
"dayjs": "^1.11.10",
"debounce": "^2.0.0",
"downloadjs": "^1.4.7",
"i18next-browser-languagedetector": "^7.2.0",
"i18next-http-backend": "^2.5.0",
Expand Down
44 changes: 43 additions & 1 deletion frontend/public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,43 @@
"welcomeDescription": "Welcome to Peristerónas, the online submission platform of UGent",
"login": "Login"
},
"courseDetailTeacher": {
"title": "Course Details",
"deleteCourse": "Delete Course",
"unauthorizedDelete": "You are unauthorized to delete this course",
"noCoursesFound": "No courses found",
"noProjects": "No projects",
"noStudents": "No students in this course",
"joinCodes": "Join Codes",
"forAdmins": "For Admins",
"forStudents": "For Students",
"noExpiryDate": "No expiry date",
"expiryDate": "Expiry Date",
"newJoinCode": "New Join Code",
"deleteSelected": "Delete Selected Students",
"projects": "Projects",
"newProject": "New Project",
"assistantList": "List of co-teachers/assistants",
"newTeacher": "New teacher",
"studentList": "List of students",
"newStudent": "New student(s)",
"deadline": "Deadline",
"teacher": "Teacher",
"view": "View",
"admins": "Admins",
"students": "Students"
},
"allCoursesTeacher": {
"title": "All Courses",
"courseForm": "Course Form",
"courseName": "Course Name",
"submit": "Submit",
"emptyCourseNameError": "Course name should not be empty",
"cancel": "Cancel",
"create": "Create",
"activeCourses": "Active Courses",
"archivedCourses":"Archived Courses"
},
"courseForm": {
"courseName": "Course Name",
"submit": "Submit",
Expand All @@ -42,7 +79,12 @@
"daysAgo": "days ago",
"hoursAgo": "hours ago",
"minutesAgo": "minutes ago",
"justNow": "just now"
"justNow": "just now",
"yearsLater": "years later",
"monthsLater": "months later",
"daysLater": "days later",
"hoursLater": "hours later",
"minutesLater": "minutes later"
},
"error": {
"pageNotFound": "Page Not Found",
Expand Down
44 changes: 43 additions & 1 deletion frontend/public/locales/nl/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,43 @@
"welcomeDescription": "Welkom bij Peristerónas, het online indieningsplatform van UGent",
"login": "Aanmelden"
},
"courseDetailTeacher": {
"title": "Vak Details",
"noCoursesFound": "Geen vakken gevonden",
"unauthorizedDelete": "U heeft niet de juiste rechten om dit vak te verwijderen",
"noProjects": "Geen projecten",
"noStudents": "Geen studenten voor dit vak",
"deleteCourse": "Verwijder vak",
"joinCodes": "Join Codes",
"forAdmins": "Voor Admins",
"forStudents": "Voor Studenten",
"noExpiryDate": "Geen vervaldatum",
"expiryDate": "Vervaldatum",
"newJoinCode": "Nieuwe Join Code",
"deleteSelected": "Verwijder geselecteerde studenten",
"projects": "Projecten",
"newProject": "Nieuw Project",
"assistantList": "Lijst co-leerkrachten/assistenten",
"newTeacher": "Nieuwe leerkracht",
"studentList": "Lijst studenten",
"newStudent": "Nieuwe student(en)",
"deadline": "Deadline",
"teacher": "Leerkracht",
"view": "Bekijk",
"admins": "Admins",
"students": "Studenten"
},
"allCoursesTeacher": {
"title": "Alle Vakken",
"courseForm": "Vak Form",
"courseName": "Vak Naam",
"submit": "Opslaan",
"emptyCourseNameError": "Vak naam mag niet leeg zijn",
"cancel": "Annuleer",
"create": "Nieuw Vak",
"activeCourses": "Actieve Vakken",
"archivedCourses":"Gearchiveerde Vakken"
},
"courseForm": {
"courseName": "Vak Naam",
"submit": "Opslaan",
Expand Down Expand Up @@ -74,7 +111,12 @@
"daysAgo": "dagen geleden",
"hoursAgo": "uur geleden",
"minutesAgo": "minuten geleden",
"justNow": "Zonet"
"justNow": "Zonet",
"yearsLater": "jaren later",
"monthsLater": "maanden later",
"daysLater": "dagen later",
"hoursLater": "uur later",
"minutesLater": "minuten later"
},
"projectsOverview": {
"past_deadline": "Verlopen Projecten",
Expand Down
7 changes: 7 additions & 0 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { Route, RouterProvider, createBrowserRouter, createRoutesFromElements } from "react-router-dom";
import Layout from "./components/Header/Layout";
import { AllCoursesTeacher } from "./components/Courses/AllCoursesTeacher";
import { CourseDetailTeacher } from "./components/Courses/CourseDetailTeacher";
import { dataLoaderCourseDetail, dataLoaderCourses } from "./components/Courses/CourseUtils";
import LanguagePath from "./components/LanguagePath";
import ProjectView from "./pages/project/projectView/ProjectView";
import { ErrorBoundary } from "./pages/error/ErrorBoundary.tsx";
Expand All @@ -20,6 +23,10 @@ const router = createBrowserRouter(
<Route path=":projectId" element={<ProjectView />}>
</Route>
</Route>
<Route path="courses">
<Route index element={<AllCoursesTeacher />} loader={dataLoaderCourses}/>
<Route path=":courseId" element={<CourseDetailTeacher />} loader={dataLoaderCourseDetail} />
</Route>
<Route path="projects">
<Route index element={<ProjectOverView/>} loader={fetchProjectPage}/>
<Route path="create" element={<ProjectCreateHome />} />
Expand Down
79 changes: 79 additions & 0 deletions frontend/src/components/Courses/AllCoursesTeacher.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { Button, Dialog, DialogActions, DialogTitle, FormControl, FormHelperText, Grid, Input, InputLabel } from "@mui/material";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";
import { SideScrollableCourses } from "./CourseUtilComponents";
import { Course, callToApiToCreateCourse } from "./CourseUtils";
import { Title } from "../Header/Title";
import { useLoaderData } from "react-router-dom";

/**
* @returns A jsx component representing all courses for a teacher
*/
export function AllCoursesTeacher(): JSX.Element {
const [open, setOpen] = useState(false);
const courses = (useLoaderData() as Course[]);

const [courseName, setCourseName] = useState('');
const [error, setError] = useState('');

const navigate = useNavigate();

const { t } = useTranslation('translation', { keyPrefix: 'allCoursesTeacher' });

const handleClickOpen = () => {
setOpen(true);
};

const handleClose = () => {
setOpen(false);
};

const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setCourseName(event.target.value);
setError(''); // Clearing error message when user starts typing
};

const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault(); // Prevents the default form submission behaviour

if (!courseName.trim()) {
setError(t('emptyCourseNameError'));
return;
}

const data = { name: courseName };
callToApiToCreateCourse(JSON.stringify(data), navigate);
};
return (
<>
<Title title={t('title')}></Title>
<Grid container direction={'column'} style={{marginTop: '1rem', width:'100vw', height: '80vh'}}>
<SideScrollableCourses courses={courses}></SideScrollableCourses>
<Dialog open={open} onClose={handleClose}>
<DialogTitle>{t('courseForm')}</DialogTitle>
<form style={{ margin: "2rem" }} onSubmit={handleSubmit}>
<FormControl>
<InputLabel htmlFor="course-name">{t('courseName')}</InputLabel>
<Input
id="course-name"
value={courseName}
onChange={handleInputChange}
error={!!error}
aria-describedby="my-helper-text"
/>
{error && <FormHelperText id="my-helper-text">{error}</FormHelperText>}
</FormControl>
<DialogActions>
<Button onClick={handleClose}>{t('cancel')}</Button>
<Button type="submit">{t('submit')}</Button>
</DialogActions>
</form>
</Dialog>
<Grid item style={{position: "absolute", left: "2rem", bottom: "5rem"}}>
<Button onClick={handleClickOpen} >{t('create')}</Button>
</Grid>
</Grid>
</>
);
}
Loading
Loading