Skip to content

Commit

Permalink
feat: lesson details and lesson progress (#310)
Browse files Browse the repository at this point in the history
* fix: available courses

* feat: add lesson endpoint

* feat: update lesson progress module

* feat: add display order and types to lesson response
  • Loading branch information
wielopolski authored Dec 23, 2024
1 parent ccea161 commit 34342cc
Show file tree
Hide file tree
Showing 31 changed files with 3,391 additions and 3,531 deletions.
4 changes: 2 additions & 2 deletions apps/api/src/chapter/adminChapter.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export class AdminChapterService {
// },
// };
// }
// async processLessonItems(lessonItemsList: LessonItemWithContentSchema[]) {
// async processLessonItems(lessonItemsList: AdminLessonWithContentSchema[]) {
// const getFileUrl = async (url: string) => {
// if (!url || url.startsWith("https://")) return url;
// return await this.s3Service.getSignedUrl(url);
Expand Down Expand Up @@ -123,7 +123,7 @@ export class AdminChapterService {

// const lessonItemsList = await this.adminChapterRepository.getLessonItems(id);

// const items = await this.processLessonItems(lessonItemsList as LessonItemWithContentSchema[]);
// const items = await this.processLessonItems(lessonItemsList as AdminLessonWithContentSchema[]);

// return {
// ...lesson,
Expand Down
2 changes: 1 addition & 1 deletion apps/api/src/chapter/chapter.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Inject, Injectable, NotFoundException, UnauthorizedException } from "@n
import { EventBus } from "@nestjs/cqrs";

import { DatabasePg } from "src/common";
import { LessonRepository } from "src/lesson/lesson.repository";
import { LessonRepository } from "src/lesson/repositories/lesson.repository";

import { ChapterRepository } from "./repositories/chapter.repository";

Expand Down
6 changes: 1 addition & 5 deletions apps/api/src/chapter/chapter.type.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
export const LESSON_TYPE = {
quiz: { key: "quiz", value: "Quiz" },
multimedia: { key: "multimedia", value: "Multimedia" },
} as const;

// TODO: remove unused types
export const LESSON_ITEM_TYPE = {
text_block: { key: "text_block", value: "Text Block" },
file: { key: "file", value: "File" },
Expand Down
4 changes: 2 additions & 2 deletions apps/api/src/chapter/repositories/adminChapter.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { chapters, lessons, questionAnswerOptions, questions } from "src/storage

import type { UpdateChapterBody } from "../schemas/chapter.schema";
import type { PostgresJsDatabase } from "drizzle-orm/postgres-js";
import type { LessonItemWithContentSchema, QuestionSchema } from "src/lesson/lesson.schema";
import type { AdminLessonWithContentSchema, QuestionSchema } from "src/lesson/lesson.schema";
import type * as schema from "src/storage/schema";

@Injectable()
Expand Down Expand Up @@ -209,7 +209,7 @@ export class AdminChapterRepository {
// // : await this.fileService.getFileUrl(lesson.imageUrl),
// // };

async getBetaChapterLessons(chapterId: UUIDType): Promise<LessonItemWithContentSchema[]> {
async getBetaChapterLessons(chapterId: UUIDType): Promise<AdminLessonWithContentSchema[]> {
return await this.db
.select({
updatedAt: sql<string>`${lessons.updatedAt}`,
Expand Down
1 change: 1 addition & 0 deletions apps/api/src/courses/course.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ export class CourseController {
})
async getTeacherCourses(
@Query("authorId") authorId: UUIDType,
// TODO: extract to const
@Query("scope") scope: "all" | "enrolled" | "available" = "all",
@Query("excludeCourseId") excludeCourseId: UUIDType,
@CurrentUser("userId") currentUserId: UUIDType,
Expand Down
44 changes: 22 additions & 22 deletions apps/api/src/courses/course.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import {
sql,
} from "drizzle-orm";

import { LESSON_TYPE } from "src/chapter/chapter.type";
import { AdminChapterRepository } from "src/chapter/repositories/adminChapter.repository";
import { DatabasePg } from "src/common";
import { addPagination, DEFAULT_PAGE_SIZE } from "src/common/pagination";
Expand Down Expand Up @@ -58,7 +57,7 @@ import type { CommonShowCourse } from "./schemas/showCourseCommon.schema";
import type { UpdateCourseBody } from "./schemas/updateCourse.schema";
import type { PostgresJsDatabase } from "drizzle-orm/postgres-js";
import type { Pagination, UUIDType } from "src/common";
import type { LessonItemWithContentSchema } from "src/lesson/lesson.schema";
import type { AdminLessonWithContentSchema } from "src/lesson/lesson.schema";
import type * as schema from "src/storage/schema";
import type { ProgressStatus } from "src/utils/types/progress.type";

Expand All @@ -84,6 +83,7 @@ export class CourseService {
currentUserRole,
} = query;

// TODO: repair it
// const { sortOrder, sortedField } = getSortOptions(sort);
const sortOrder = asc;
const sortedField = CourseSortFields.title;
Expand Down Expand Up @@ -261,15 +261,15 @@ export class CourseService {
priceInCents: courses.priceInCents,
currency: courses.currency,
hasFreeChapters: sql<boolean>`
EXISTS (
SELECT 1
FROM ${chapters}
WHERE ${chapters.courseId} = ${courses.id}
AND ${chapters.isFreemium} = TRUE
)`,
EXISTS (
SELECT 1
FROM ${chapters}
WHERE ${chapters.courseId} = ${courses.id}
AND ${chapters.isFreemium} = TRUE
)
`,
})
.from(courses)
.leftJoin(studentCourses, eq(studentCourses.courseId, courses.id))
.leftJoin(categories, eq(courses.categoryId, categories.id))
.leftJoin(users, eq(courses.authorId, users.id))
.leftJoin(coursesSummaryStats, eq(courses.id, coursesSummaryStats.courseId))
Expand All @@ -283,11 +283,9 @@ export class CourseService {
users.firstName,
users.lastName,
users.email,
studentCourses.studentId,
categories.title,
coursesSummaryStats.freePurchasedCount,
coursesSummaryStats.paidPurchasedCount,
studentCourses.finishedChapterCount,
)
.orderBy(sortOrder(this.getColumnToSortBy(sortedField as CourseSortField)));

Expand All @@ -297,7 +295,6 @@ export class CourseService {
const [{ totalItems }] = await trx
.select({ totalItems: countDistinct(courses.id) })
.from(courses)
.leftJoin(studentCourses, eq(studentCourses.courseId, courses.id))
.leftJoin(categories, eq(courses.categoryId, categories.id))
.leftJoin(users, eq(courses.authorId, users.id))
.where(and(...conditions));
Expand Down Expand Up @@ -369,7 +366,7 @@ export class CourseService {
(SELECT COUNT(*)
FROM ${lessons}
WHERE ${lessons.chapterId} = ${chapters.id}
AND ${lessons.type} = ${LESSON_TYPE.quiz.key})::INTEGER`,
AND ${lessons.type} = ${LESSON_TYPES.QUIZ})::INTEGER`,
completedLessonCount: sql<number>`COALESCE(${studentChapterProgress.completedLessonCount}, 0)`,
chapterProgress: sql<ProgressStatus>`
CASE
Expand Down Expand Up @@ -398,7 +395,7 @@ export class CourseService {
ELSE 'not_started'
END AS status,
CASE
WHEN ${lessons.type} = ${LESSON_TYPES.quiz} THEN COUNT(${questions.id})
WHEN ${lessons.type} = ${LESSON_TYPES.QUIZ} THEN COUNT(${questions.id})
ELSE NULL
END AS "quizQuestionCount"
FROM ${lessons}
Expand Down Expand Up @@ -493,7 +490,7 @@ export class CourseService {

const updatedCourseLessonList = await Promise.all(
courseChapterList?.map(async (chapter) => {
const lessons: LessonItemWithContentSchema[] =
const lessons: AdminLessonWithContentSchema[] =
await this.adminChapterRepository.getBetaChapterLessons(chapter.id);

const lessonsWithSignedUrls = await this.addS3SignedUrlsToLessonsAndQuestions(lessons);
Expand Down Expand Up @@ -590,9 +587,9 @@ export class CourseService {
excludeCourseId,
);

if (availableCourseIds.length) {
conditions.push(inArray(courses.id, availableCourseIds));
}
if (!availableCourseIds.length) return [];

conditions.push(inArray(courses.id, availableCourseIds));
}

return this.db
Expand Down Expand Up @@ -620,7 +617,10 @@ export class CourseService {
)`,
})
.from(courses)
.leftJoin(studentCourses, eq(studentCourses.courseId, courses.id))
.leftJoin(
studentCourses,
and(eq(studentCourses.courseId, courses.id), eq(studentCourses.studentId, currentUserId)),
)
.leftJoin(categories, eq(courses.categoryId, categories.id))
.leftJoin(users, eq(courses.authorId, users.id))
.where(and(...conditions))
Expand Down Expand Up @@ -823,7 +823,7 @@ export class CourseService {
studentId,
lessonId: lesson.id,
completedQuestionCount: 0,
quizScore: lesson.type === LESSON_TYPES.quiz ? 0 : null,
quizScore: lesson.type === LESSON_TYPES.QUIZ ? 0 : null,
completedAt: null,
})),
);
Expand Down Expand Up @@ -928,13 +928,13 @@ export class CourseService {
);
}

private async addS3SignedUrlsToLessonsAndQuestions(lessons: LessonItemWithContentSchema[]) {
private async addS3SignedUrlsToLessonsAndQuestions(lessons: AdminLessonWithContentSchema[]) {
return await Promise.all(
lessons.map(async (lesson) => {
const updatedLesson = { ...lesson };
if (
lesson.fileS3Key &&
(lesson.type === LESSON_TYPES.video || lesson.type === LESSON_TYPES.presentation)
(lesson.type === LESSON_TYPES.VIDEO || lesson.type === LESSON_TYPES.PRESENTATION)
) {
if (!lesson.fileS3Key.startsWith("https://")) {
try {
Expand Down
Loading

0 comments on commit 34342cc

Please sign in to comment.