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

feat: lecturer ratings #122

Merged
merged 2 commits into from
Jan 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
89 changes: 75 additions & 14 deletions backend/app/controllers/courses_controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,42 @@ export default class CoursesController {
assert(typeof params.registration_id === "string");

const registrationId = decodeURIComponent(params.registration_id);
if (registrationId) {
return await Course.query()
.where("registrationId", registrationId)
.preload("groups");
if (!registrationId) {
return [];
}
return [];

const courses = await Course.query()
.where("registrationId", registrationId)
.preload("groups", (groupQuery) => groupQuery.preload("lecturers"));

const transformedCourses = courses.map((course) => ({
id: course.id,
name: course.name,
registrationId: course.registrationId,
createdAt: course.createdAt,
updatedAt: course.updatedAt,
groups: course.groups.map((group) => ({
id: group.id,
name: group.name,
lecturer: Array.isArray(group.lecturers)
? group.lecturers
.map((lecturer) => `${lecturer.name} ${lecturer.surname}`)
.join(", ")
: "Brak prowadzącego",
averageRating: Array.isArray(group.lecturers)
? (
group.lecturers.reduce(
(total, lecturer) =>
total + (Number.parseFloat(lecturer.averageRating) || 0),
olekszczepanowski marked this conversation as resolved.
Show resolved Hide resolved
0,
) / group.lecturers.length
).toFixed(2)
: 0,
...group.serialize(),
})),
}));

return transformedCourses;
}

/**
Expand All @@ -38,17 +68,48 @@ export default class CoursesController {
*/
async show({ params }: HttpContext) {
assert(typeof params.registration_id === "string");
assert(typeof params.id === "string");
const registrationId = decodeURIComponent(params.registration_id);
if (registrationId) {
assert(typeof params.id === "string");

return await Course.query()
.where("registrationId", registrationId)
.andWhere("id", params.id)
.preload("groups")
.firstOrFail();

if (!registrationId) {
return [];
}
return {};

const course = await Course.query()
.where("registrationId", registrationId)
.andWhere("id", params.id)
.preload("groups", (groupQuery) => groupQuery.preload("lecturers"))
.firstOrFail();

const transformedCourse = {
id: course.id,
name: course.name,
registrationId: course.registrationId,
createdAt: course.createdAt,
updatedAt: course.updatedAt,
groups: course.groups.map((group) => ({
olekszczepanowski marked this conversation as resolved.
Show resolved Hide resolved
id: group.id,
name: group.name,
lecturer: Array.isArray(group.lecturers)
? group.lecturers
.map((lecturer) => `${lecturer.name} ${lecturer.surname}`)
.join(", ")
: "Brak prowadzącego",
averageRating: Array.isArray(group.lecturers)
? (
group.lecturers.reduce(
(total, lecturer) =>
total + (Number.parseFloat(lecturer.averageRating) || 0),
0,
) / group.lecturers.length
).toFixed(2)
: 0,

...group.serialize(),
})),
};

return transformedCourse;
}

/**
Expand Down
68 changes: 58 additions & 10 deletions backend/app/controllers/groups_controller.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import assert from "node:assert";

import type { HttpContext } from "@adonisjs/core/http";

import Group from "#models/group";
Expand All @@ -10,10 +8,36 @@ export default class GroupsController {
* Display a list of all groups in matching course
*/
async index({ params }: HttpContext) {
const courseId = params.course_id as unknown;
if (typeof courseId === "string") {
return Group.query().where("courseId", courseId);
const courseId = params.course_id as string;

olekszczepanowski marked this conversation as resolved.
Show resolved Hide resolved
if (courseId) {
const groups = await Group.query()
.where("courseId", courseId)
.preload("lecturers");

const transformedGroups = groups.map((group) => ({
id: group.id,
name: group.name,
lecturer: Array.isArray(group.lecturers)
? group.lecturers
.map((lecturer) => `${lecturer.name} ${lecturer.surname}`)
.join(", ")
: "Brak prowadzącego",
averageRating: Array.isArray(group.lecturers)
? (
group.lecturers.reduce(
(total, lecturer) =>
total + (Number.parseFloat(lecturer.averageRating) || 0),
0,
) / group.lecturers.length
).toFixed(2)
: 0,
...group.serialize(),
}));

return transformedGroups;
}

return {};
}

Expand All @@ -30,14 +54,38 @@ export default class GroupsController {
* Show individual group in matching group
*/
async show({ params }: HttpContext) {
const courseId = params.course_id as unknown;
if (typeof courseId === "string") {
assert(typeof params.id === "string");
const courseId = params.course_id as string;

return await Group.query()
if (courseId && typeof params.id === "string") {
const group = await Group.query()
.where("courseId", courseId)
.andWhere("id", params.id);
.andWhere("id", params.id)
.preload("lecturers")
.firstOrFail();

const transformedGroup = {
id: group.id,
name: group.name,
lecturer: Array.isArray(group.lecturers)
? group.lecturers
.map((lecturer) => `${lecturer.name} ${lecturer.surname}`)
.join(", ")
: "Brak prowadzącego",
averageRating: Array.isArray(group.lecturers)
? (
group.lecturers.reduce(
(total, lecturer) =>
total + (Number.parseFloat(lecturer.averageRating) || 0),
0,
) / group.lecturers.length
).toFixed(2)
: 0,
...group.serialize(),
};

return transformedGroup;
}

return {};
}

Expand Down
80 changes: 54 additions & 26 deletions backend/app/controllers/schedules_controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,26 @@ export default class SchedulesController {
return { message: "User not authenticated." };
}

// Pobierz wszystkie harmonogramy użytkownika
const schedules = await Schedule.query()
.where("userId", userId)
.preload("registrations") // Preload registrations dla każdego harmonogramu
.preload("courses"); // Preload courses dla każdego harmonogramu
.preload("registrations")
.preload("courses");

// Przetwórz każdy harmonogram, aby uzyskać pożądaną strukturę
const transformedSchedules = await Promise.all(
schedules.map(async (schedule) => {
// Pobierz grupy powiązane z kursami w harmonogramie
const courseGroups = await schedule
.related("courses")
.query()
.preload("groups", (groupQuery) =>
groupQuery.whereExists((subQuery) =>
subQuery
.from("schedule_groups")
.whereRaw("schedule_groups.group_id = groups.id")
.andWhere("schedule_groups.schedule_id", schedule.id),
),
);
.preload("groups", (groupQuery) => {
void groupQuery
.preload("lecturers")
.whereExists((subQuery) =>
subQuery
.from("schedule_groups")
.whereRaw("schedule_groups.group_id = groups.id")
.andWhere("schedule_groups.schedule_id", schedule.id),
);
});

return {
id: schedule.id,
Expand All @@ -57,6 +56,21 @@ export default class SchedulesController {
groups: course.groups.map((group) => ({
id: group.id,
name: group.name,
lecturer: Array.isArray(group.lecturers)
? group.lecturers
.map((lecturer) => `${lecturer.name} ${lecturer.surname}`)
.join(", ")
: "Brak prowadzącego",
averageRating: Array.isArray(group.lecturers)
? (
group.lecturers.reduce(
(total, lecturer) =>
total +
(Number.parseFloat(lecturer.averageRating) || 0),
0,
) / group.lecturers.length
).toFixed(2)
: 0,
...group.serialize(),
})),
})),
Expand Down Expand Up @@ -121,24 +135,24 @@ export default class SchedulesController {
const schedule = await Schedule.query()
.where("id", scheduleId)
.andWhere("userId", userId)
.preload("registrations") // Preload registrations
.preload("courses") // Preload courses (grupy powiązane z kursami zostaną załadowane osobno)
.preload("registrations")
.preload("courses")
.firstOrFail();

// Pobranie grup powiązanych z kursami z uwzględnieniem schedule_id
const courseGroups = await schedule
.related("courses")
.query()
.preload("groups", (groupQuery) =>
groupQuery.whereExists((subQuery) =>
subQuery
.from("schedule_groups")
.whereRaw("schedule_groups.group_id = groups.id")
.andWhere("schedule_groups.schedule_id", scheduleId),
),
);

// Transformacja danych do żądanej struktury
.preload("groups", (groupQuery) => {
void groupQuery
.preload("lecturers")
.whereExists((subQuery) =>
subQuery
.from("schedule_groups")
.whereRaw("schedule_groups.group_id = groups.id")
.andWhere("schedule_groups.schedule_id", scheduleId),
);
});

const transformedSchedule = {
id: schedule.id,
userId: schedule.userId,
Expand All @@ -155,6 +169,20 @@ export default class SchedulesController {
groups: course.groups.map((group) => ({
id: group.id,
name: group.name,
lecturer: Array.isArray(group.lecturers)
? group.lecturers
.map((lecturer) => `${lecturer.name} ${lecturer.surname}`)
.join(", ")
: "Brak prowadzącego",
averageRating: Array.isArray(group.lecturers)
? (
group.lecturers.reduce(
(total, lecturer) =>
total + (Number.parseFloat(lecturer.averageRating) || 0),
0,
) / group.lecturers.length
).toFixed(2)
: 0,
...group.serialize(),
olekszczepanowski marked this conversation as resolved.
Show resolved Hide resolved
})),
})),
Expand Down
16 changes: 13 additions & 3 deletions backend/app/models/group.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { DateTime } from "luxon";

import { BaseModel, column } from "@adonisjs/lucid/orm";
import { BaseModel, column, manyToMany } from "@adonisjs/lucid/orm";
import type { ManyToMany } from "@adonisjs/lucid/types/relations";

import Lecturer from "./lecturer.js";

export default class Group extends BaseModel {
@column({ isPrimary: true })
Expand All @@ -18,8 +21,15 @@ export default class Group extends BaseModel {
@column()
declare group: string;

@column()
declare lecturer: string;
@manyToMany(() => Lecturer, {
localKey: "id",
pivotForeignKey: "group_id",
relatedKey: "id",
pivotRelatedForeignKey: "lecturer_id",
pivotTable: "group_lecturers",
pivotTimestamps: true,
})
declare lecturers: ManyToMany<typeof Lecturer>;

@column()
declare week: "-" | "TP" | "TN";
Expand Down
22 changes: 19 additions & 3 deletions backend/app/models/group_archive.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { DateTime } from "luxon";

import { BaseModel, column } from "@adonisjs/lucid/orm";
import { BaseModel, column, manyToMany } from "@adonisjs/lucid/orm";
import type { ManyToMany } from "@adonisjs/lucid/types/relations";

import Lecturer from "./lecturer.js";

export default class GroupArchive extends BaseModel {
static table = "groups_archive";
Expand All @@ -19,8 +22,15 @@ export default class GroupArchive extends BaseModel {
@column()
declare group: string;

@column()
declare lecturer: string;
@manyToMany(() => Lecturer, {
localKey: "id",
pivotForeignKey: "group_id",
relatedKey: "id",
pivotRelatedForeignKey: "lecturer_id",
pivotTable: "group_archive_lecturers",
pivotTimestamps: true,
})
declare lecturers: ManyToMany<typeof Lecturer>;

@column()
declare week: "-" | "TP" | "TN";
Expand All @@ -37,6 +47,12 @@ export default class GroupArchive extends BaseModel {
@column()
declare url: string;

@column()
declare spotsOccupied: number;

@column()
declare spotsTotal: number;

@column.dateTime({ autoCreate: true })
declare createdAt: DateTime;

Expand Down
Loading
Loading