Skip to content

Commit

Permalink
feat: update lesson progress module
Browse files Browse the repository at this point in the history
  • Loading branch information
wielopolski committed Dec 23, 2024
1 parent 386f762 commit 356a28b
Show file tree
Hide file tree
Showing 16 changed files with 2,242 additions and 172 deletions.
71 changes: 19 additions & 52 deletions apps/api/src/lesson/lesson.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,23 @@ import { CurrentUser } from "src/common/decorators/user.decorator";
import { RolesGuard } from "src/common/guards/roles.guard";
import { USER_ROLES } from "src/user/schemas/userRoles";

import { AdminLessonService } from "./services/adminLesson.service";
import {
CreateLessonBody,
createLessonSchema,
CreateQuizLessonBody,
createQuizLessonSchema,
LessonShow,
lessonShowSchema,
UpdateLessonBody,
updateLessonSchema,
UpdateQuizLessonBody,
updateQuizLessonSchema,
} from "./lesson.schema";
import { AdminLessonService } from "./services/adminLesson.service";
import { LessonService } from "./services/lesson.service";

import type {
LessonShow} from "./lesson.schema";

@Controller("lesson")
@UseGuards(RolesGuard)
export class LessonController {
Expand Down Expand Up @@ -157,56 +159,21 @@ export class LessonController {
});
}

// @Patch("course-lesson")
// @Roles(USER_ROLES.TEACHER, USER_ROLES.ADMIN)
// @Validate({
// request: [
// {
// type: "body",
// schema: Type.Object({
// courseId: UUIDSchema,
// lessonId: UUIDSchema,
// isFree: Type.Boolean(),
// }),
// },
// ],
// response: baseResponse(Type.Object({ isFree: Type.Boolean(), message: Type.String() })),
// })
// async toggleLessonAsFree(
// @Body() body: { courseId: string; lessonId: string; isFree: boolean },
// ): Promise<BaseResponse<{ isFree: boolean; message: string }>> {
// const [toggledLesson] = await this.adminLessonsService.toggleLessonAsFree(
// body.courseId,
// body.lessonId,
// body.isFree,
// );
// return new BaseResponse({
// isFree: toggledLesson.isFree,
// message: body.isFree
// ? "Lesson toggled as free successfully"
// : "Lesson toggled as not free successfully",
// });
// }

// @Post("evaluation-quiz")
// @Roles(USER_ROLES.STUDENT)
// @Validate({
// request: [
// { type: "query", name: "courseId", schema: UUIDSchema },
// { type: "query", name: "lessonId", schema: UUIDSchema },
// ],
// response: baseResponse(Type.Object({ message: Type.String() })),
// })
// async evaluationQuiz(
// @Query("courseId") courseId: string,
// @Query("lessonId") lessonId: string,
// @CurrentUser("userId") currentUserId: UUIDType,
// ): Promise<BaseResponse<{ message: string }>> {
// await this.lessonsService.evaluationQuiz(courseId, lessonId, currentUserId);
// return new BaseResponse({
// message: "Evaluation quiz successfully",
// });
// }
// @Post("evaluation-quiz")
// @Roles(USER_ROLES.STUDENT)
// @Validate({
// request: [{ type: "query", name: "lessonId", schema: UUIDSchema, required: true }],
// response: baseResponse(Type.Object({ message: Type.String() })),
// })
// async evaluationQuiz(
// @Query("lessonId") lessonId: string,
// @CurrentUser("userId") currentUserId: UUIDType,
// ): Promise<BaseResponse<{ message: string }>> {
// await this.lessonService.evaluationQuiz(lessonId, currentUserId);
// return new BaseResponse({
// message: "Evaluation quiz successfully",
// });
// }

// @Delete("clear-quiz-progress")
// @Roles(USER_ROLES.STUDENT)
Expand Down
4 changes: 2 additions & 2 deletions apps/api/src/lesson/lesson.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import { Module } from "@nestjs/common";

import { FileModule } from "src/file/files.module";

import { AdminLessonRepository } from "./repositories/adminLesson.repository";
import { AdminLessonService } from "./services/adminLesson.service";
import { LessonController } from "./lesson.controller";
import { AdminLessonRepository } from "./repositories/adminLesson.repository";
import { LessonRepository } from "./repositories/lesson.repository";
import { AdminLessonService } from "./services/adminLesson.service";
import { LessonService } from "./services/lesson.service";

@Module({
Expand Down
2 changes: 1 addition & 1 deletion apps/api/src/lesson/lesson.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Type } from "@sinclair/typebox";

import { UUIDSchema } from "src/common";

import { LESSON_TYPES, PhotoQuestionType, QuestionType } from "./lesson.type";
import { PhotoQuestionType, QuestionType } from "./lesson.type";

import type { Static } from "@sinclair/typebox";

Expand Down
2 changes: 1 addition & 1 deletion apps/api/src/lesson/lesson.type.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export const LESSON_TYPES = {
TEXT_BLOCK: "text_block",
TEXT: "text",
FILE: "file",
PRESENTATION: "presentation",
VIDEO: "video",
Expand Down
2 changes: 1 addition & 1 deletion apps/api/src/lesson/services/adminLesson.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import { eq, gte, inArray, lte, sql } from "drizzle-orm";
import { DatabasePg } from "src/common";
import { lessons, questionAnswerOptions, questions } from "src/storage/schema";

import { LESSON_TYPES } from "../lesson.type";
import { AdminLessonRepository } from "../repositories/adminLesson.repository";
import { LessonRepository } from "../repositories/lesson.repository";
import { LESSON_TYPES } from "../lesson.type";

import type {
CreateLessonBody,
Expand Down
49 changes: 33 additions & 16 deletions apps/api/src/lesson/services/lesson.service.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,30 @@
import { Inject, Injectable, NotFoundException } from "@nestjs/common";
import { EventBus } from "@nestjs/cqrs";
import { eq, sql } from "drizzle-orm";
import { and, eq, sql } from "drizzle-orm";

import { DatabasePg } from "src/common";
import { FileService } from "src/file/file.service";
import {
chapters,
lessons,
questionAnswerOptions,
questions,
studentCourses,
} from "src/storage/schema";

import { LESSON_TYPES } from "../lesson.type";


import type { LessonShow, OptionBody, QuestionBody } from "../lesson.schema";
import type { PhotoQuestionType, QuestionType } from "../lesson.type";
import type { UUIDType } from "src/common";
import { lessons, questionAnswerOptions, questions } from "src/storage/schema";
import { LESSON_TYPES, PhotoQuestionType, QuestionType } from "../lesson.type";
import { FileService } from "src/file/file.service";
import { LessonShow, OptionBody, QuestionBody } from "../lesson.schema";
import { QuestionTypes } from "src/questions/schema/questions.types";

@Injectable()
export class LessonService {
constructor(
@Inject("DB") private readonly db: DatabasePg,
private readonly fileService: FileService, // TODO: add event bus
) // private readonly eventBus: EventBus,
{}
// private readonly eventBus: EventBus,
) {}

async getLessonById(id: UUIDType): Promise<LessonShow> {
const [lesson] = await this.db
Expand All @@ -34,7 +41,7 @@ export class LessonService {

if (!lesson) throw new NotFoundException("Lesson not found");

if (lesson.type === LESSON_TYPES.TEXT_BLOCK && !lesson.fileUrl) return lesson;
if (lesson.type === LESSON_TYPES.TEXT && !lesson.fileUrl) return lesson;

if (lesson.type !== LESSON_TYPES.QUIZ) {
if (!lesson.fileUrl) throw new NotFoundException("Lesson file not found");
Expand Down Expand Up @@ -97,12 +104,8 @@ export class LessonService {
return { ...lesson, quizDetails };
}

// async evaluationQuiz(courseId: UUIDType, lessonId: UUIDType, userId: UUIDType) {
// const [accessCourseLessons] = await this.chapterRepository.checkLessonAssignment(
// courseId,
// lessonId,
// userId,
// );
// async evaluationQuiz(lessonId: UUIDType, userId: UUIDType) {
// const [accessCourseLessons] = await this.checkLessonAssignment(lessonId, userId);

// if (!accessCourseLessons.isAssigned && !accessCourseLessons.isFree)
// throw new UnauthorizedException("You don't have assignment to this lesson");
Expand Down Expand Up @@ -140,6 +143,20 @@ export class LessonService {
// return true;
// }

async checkLessonAssignment(id: UUIDType, userId: UUIDType) {
return this.db
.select({
isAssigned: sql<boolean>`CASE WHEN ${studentCourses.id} IS NOT NULL THEN TRUE ELSE FALSE END`,
})
.from(lessons)
.leftJoin(chapters, eq(lessons.chapterId, chapters.id))
.leftJoin(
studentCourses,
and(eq(studentCourses.courseId, chapters.courseId), eq(studentCourses.studentId, userId)),
)
.where(and(eq(chapters.isPublished, true), eq(lessons.id, id)));
}

// private async evaluationsQuestions(courseId: UUIDType, lessonId: UUIDType, userId: UUIDType) {
// const lesson = await this.chapterRepository.getLessonForUser(courseId, lessonId, userId);
// const questionLessonItems = await this.getLessonQuestionsToEvaluation(
Expand Down
2 changes: 1 addition & 1 deletion apps/api/src/seed/e2e-data-seeds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const e2eCourses: NiceCourseData[] = [
displayOrder: 1,
lessons: [
{
type: LESSON_TYPES.TEXT_BLOCK,
type: LESSON_TYPES.TEXT,
title: "E2E Testing Text Block",
description: "E2E Testing Text Block Body",
displayOrder: 1,
Expand Down
Loading

0 comments on commit 356a28b

Please sign in to comment.