diff --git a/backend/src/controllers/classes.ts b/backend/src/controllers/classes.ts index b8061b5a..5fd4ce9d 100644 --- a/backend/src/controllers/classes.ts +++ b/backend/src/controllers/classes.ts @@ -1,11 +1,14 @@ import { Request, Response } from 'express'; import { + createClass, getAllClasses, getClass, getClassStudents, getClassStudentsIds, getClassTeacherInvitations, } from '../services/class.js'; +import { ClassDTO, mapToClass } from '../interfaces/class.js'; +import { getClassRepository, getStudentRepository, getTeacherRepository } from '../data/repositories.js'; export async function getAllClassesHandler( req: Request, @@ -19,6 +22,29 @@ export async function getAllClassesHandler( }); } +export async function createClassHandler( + req: Request, + res: Response, +): Promise { + const classData = req.body as ClassDTO; + + if (!classData.displayName) { + res.status(400).json({ + error: 'Missing one or more required fields: displayName', + }); + return; + } + + const cls = await createClass(classData); + + if (!cls) { + res.status(500).json({ error: "Something went wrong while creating class" }); + return + } + + res.status(201).json({ class: cls }); +} + export async function getClassHandler( req: Request, res: Response diff --git a/backend/src/entities/classes/class.entity.ts b/backend/src/entities/classes/class.entity.ts index b40b5baf..b9fd4d0e 100644 --- a/backend/src/entities/classes/class.entity.ts +++ b/backend/src/entities/classes/class.entity.ts @@ -17,7 +17,7 @@ import { ClassRepository } from '../../data/classes/class-repository.js'; }) export class Class { @PrimaryKey() - classId = v4(); + classId? = v4(); @Property({ type: 'string' }) displayName!: string; diff --git a/backend/src/interfaces/assignment.ts b/backend/src/interfaces/assignment.ts index de7ce25f..8f6120b6 100644 --- a/backend/src/interfaces/assignment.ts +++ b/backend/src/interfaces/assignment.ts @@ -17,7 +17,7 @@ export interface AssignmentDTO { export function mapToAssignmentDTOId(assignment: Assignment): AssignmentDTO { return { id: assignment.id!, - class: assignment.within.classId, + class: assignment.within.classId!, title: assignment.title, description: assignment.description, learningPath: assignment.learningPathHruid, @@ -29,7 +29,7 @@ export function mapToAssignmentDTOId(assignment: Assignment): AssignmentDTO { export function mapToAssignmentDTO(assignment: Assignment): AssignmentDTO { return { id: assignment.id!, - class: assignment.within.classId, + class: assignment.within.classId!, title: assignment.title, description: assignment.description, learningPath: assignment.learningPathHruid, diff --git a/backend/src/interfaces/class.ts b/backend/src/interfaces/class.ts index c18ee842..379a8635 100644 --- a/backend/src/interfaces/class.ts +++ b/backend/src/interfaces/class.ts @@ -1,4 +1,7 @@ +import { Collection } from '@mikro-orm/core'; import { Class } from '../entities/classes/class.entity.js'; +import { Student } from '../entities/users/student.entity.js'; +import { Teacher } from '../entities/users/teacher.entity.js'; export interface ClassDTO { id: string; @@ -16,7 +19,7 @@ export interface ClassDTO { export function mapToClassDTO(cls: Class): ClassDTO { return { - id: cls.classId, + id: cls.classId!, displayName: cls.displayName, teachers: cls.teachers.map((teacher) => { return teacher.username; @@ -27,3 +30,16 @@ export function mapToClassDTO(cls: Class): ClassDTO { joinRequests: [], // TODO }; } + +export function mapToClass( + classData: ClassDTO, + students: Collection, + teachers: Collection +): Class { + const cls = new Class(); + cls.displayName = classData.displayName; + cls.students = students; + cls.teachers = teachers; + + return cls; +} diff --git a/backend/src/interfaces/group.ts b/backend/src/interfaces/group.ts index 9c4cecdc..ca7f687a 100644 --- a/backend/src/interfaces/group.ts +++ b/backend/src/interfaces/group.ts @@ -18,7 +18,7 @@ export function mapToGroupDTO(group: Group): GroupDTO { export function mapToGroupDTOId(group: Group): GroupDTO { return { - assignment: group.assignment.id, + assignment: group.assignment.id!, groupNumber: group.groupNumber, members: group.members.map((member) => { return member.username; diff --git a/backend/src/routes/classes.ts b/backend/src/routes/classes.ts index c67b573b..e0972988 100644 --- a/backend/src/routes/classes.ts +++ b/backend/src/routes/classes.ts @@ -1,5 +1,6 @@ import express from 'express'; import { + createClassHandler, getAllClassesHandler, getClassHandler, getClassStudentsHandler, @@ -12,6 +13,8 @@ const router = express.Router(); // Root endpoint used to search objects router.get('/', getAllClassesHandler); +router.post('/', createClassHandler); + // Information about an class with id 'id' router.get('/:id', getClassHandler); diff --git a/backend/src/services/class.ts b/backend/src/services/class.ts index 45185383..a7f5f7ea 100644 --- a/backend/src/services/class.ts +++ b/backend/src/services/class.ts @@ -1,7 +1,10 @@ import { getClassRepository, + getStudentRepository, getTeacherInvitationRepository, + getTeacherRepository, } from '../data/repositories.js'; +import { Class } from '../entities/classes/class.entity.js'; import { ClassDTO, mapToClassDTO } from '../interfaces/class.js'; import { mapToStudentDTO, StudentDTO } from '../interfaces/student.js'; import { @@ -27,10 +30,39 @@ export async function getAllClasses( return classes.map(mapToClassDTO); } return classes.map((cls) => { - return cls.classId; + return cls.classId!; }); } +export async function createClass(classData: ClassDTO): Promise { + const teacherRepository = getTeacherRepository(); + const teacherUsernames = classData.teachers || []; + const teachers = (await Promise.all(teacherUsernames.map(id => teacherRepository.findByUsername(id)))) + .filter(teacher => teacher != null); + + const studentRepository = getStudentRepository(); + const studentUsernames = classData.students || []; + const students = (await Promise.all(studentUsernames.map(id => studentRepository.findByUsername(id)))) + .filter(student => student != null); + + //const cls = mapToClass(classData, teachers, students); + + const classRepository = getClassRepository(); + + try { + const newClass = classRepository.create({ + displayName: classData.displayName, + teachers: teachers, + students: students, + }); + await classRepository.save(newClass); + + return newClass; + } catch(e) { + return null; + } +} + export async function getClass(classId: string): Promise { const classRepository = getClassRepository(); const cls = await classRepository.findById(classId); diff --git a/backend/src/services/students.ts b/backend/src/services/students.ts index 9524f281..602ee4e1 100644 --- a/backend/src/services/students.ts +++ b/backend/src/services/students.ts @@ -34,7 +34,7 @@ export async function getStudentClasses(username: string, full: boolean): Promis return classes.map(mapToClassDTO); } - return classes.map((cls) => cls.classId); + return classes.map((cls) => cls.classId!); } export async function getStudentAssignments(username: string, full: boolean): Promise { @@ -51,7 +51,7 @@ export async function getStudentAssignments(username: string, full: boolean): Pr const assignments = ( await Promise.all( classes.map(async (cls) => { - return await getAllAssignments(cls.classId, full); + return await getAllAssignments(cls.classId!, full); }) ) ).flat();