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

Enrollment - Learning #5

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
10 changes: 9 additions & 1 deletion package-lock.json

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

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"version": "0.0.0",
"scripts": {
"build": "npx tsc ",
"dev": "NODE_ENV=development npx ts-node ./src",
"dev": " npx ts-node ./src",
"dev:hot": "nodemon --exec \"npm run dev\" --watch ./src -e ts",
"lint": "npx eslint ./src",
"lint:tests": "npx eslint ./spec",
Expand Down Expand Up @@ -55,6 +55,7 @@
"@types/supertest": "^6.0.2",
"eslint": "^9.12.0",
"eslint-plugin-n": "^17.10.3",
"express-async-handler": "^1.2.0",
"find": "^0.3.0",
"fs-extra": "^11.2.0",
"jasmine": "^5.3.1",
Expand Down
24 changes: 24 additions & 0 deletions src/controller/enrollment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Request, Response } from 'express';
import asyncHandler from 'express-async-handler';
import { EnrollmentService } from '../service/enrollment';

const enrollmentService = new EnrollmentService();

export const enrollInCourse = asyncHandler(async (req: Request, res: Response) => {
const { userId, courseId } = req.body;
const enrollment = await enrollmentService.enrollUserInCourse(userId, courseId);
res.status(201).json({ message: 'Enrolled successfully', enrollment });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Chưa có xử lý về mặt giao diện à e ơi

});

export const getUserEnrollments = asyncHandler(async (req: Request, res: Response) => {
const { userId } = req.params;
const enrollments = await enrollmentService.getUserEnrollments(Number(userId));
res.status(200).json(enrollments);
});

export const updateLessonProgress = asyncHandler(async (req: Request, res: Response) => {
const { enrollmentId, lessonId } = req.params;
const { progress } = req.body;
const enrollmentLesson = await enrollmentService.updateLessonProgress(Number(enrollmentId), Number(lessonId), progress);
res.status(200).json({ message: 'Lesson progress updated', enrollmentLesson });
});
9 changes: 1 addition & 8 deletions src/entity/Comment.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
import { Entity,
Column,
PrimaryGeneratedColumn,
ManyToOne,
JoinColumn,
CreateDateColumn,
UpdateDateColumn,
} from 'typeorm';
import { Entity,Column, PrimaryGeneratedColumn, ManyToOne, JoinColumn, CreateDateColumn, UpdateDateColumn, } from 'typeorm';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

các bạn trong nhóm dùng chung setting trên VScode để tránh bị re-format code khi push nha

import { Review } from './Review';

@Entity('comments')
Expand Down
9 changes: 1 addition & 8 deletions src/entity/Component.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
import { Entity,
Column,
PrimaryGeneratedColumn,
ManyToOne,
CreateDateColumn,
UpdateDateColumn,
JoinColumn
} from 'typeorm';
import { Entity, Column, PrimaryGeneratedColumn, ManyToOne, CreateDateColumn, UpdateDateColumn, JoinColumn } from 'typeorm';
import { Lesson } from './Lesson';

@Entity('components')
Expand Down
9 changes: 1 addition & 8 deletions src/entity/Course.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
import { Entity,
Column,
PrimaryGeneratedColumn,
ManyToOne,
CreateDateColumn,
UpdateDateColumn,
JoinColumn
} from 'typeorm';
import { Entity, Column, PrimaryGeneratedColumn, ManyToOne, CreateDateColumn, UpdateDateColumn, JoinColumn } from 'typeorm';
import { User } from './User';

@Entity('courses')
Expand Down
9 changes: 1 addition & 8 deletions src/entity/Enrollment.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
import { Entity,
Column,
PrimaryGeneratedColumn,
ManyToOne,
CreateDateColumn,
UpdateDateColumn,
JoinColumn
} from 'typeorm';
import { Entity, Column, PrimaryGeneratedColumn, ManyToOne, CreateDateColumn, UpdateDateColumn, JoinColumn } from 'typeorm';
import { User } from './User';
import { Course } from './Course';

Expand Down
9 changes: 1 addition & 8 deletions src/entity/EnrollmentLesson.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
import { Entity,
Column,
PrimaryGeneratedColumn,
ManyToOne,
CreateDateColumn,
UpdateDateColumn,
JoinColumn
} from 'typeorm';
import { Entity, Column, PrimaryGeneratedColumn, ManyToOne, CreateDateColumn, UpdateDateColumn, JoinColumn } from 'typeorm';
import { Enrollment } from './Enrollment';
import { Lesson } from './Lesson';

Expand Down
9 changes: 1 addition & 8 deletions src/entity/Lesson.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
import { Entity,
Column,
PrimaryGeneratedColumn,
ManyToOne,
CreateDateColumn,
UpdateDateColumn,
JoinColumn
} from 'typeorm';
import { Entity, Column, PrimaryGeneratedColumn, ManyToOne, CreateDateColumn, UpdateDateColumn, JoinColumn } from 'typeorm';
import { Section } from './Section';

@Entity('lessons')
Expand Down
9 changes: 1 addition & 8 deletions src/entity/Payment.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
import { Entity,
Column,
PrimaryGeneratedColumn,
ManyToOne,
CreateDateColumn,
UpdateDateColumn,
JoinColumn
} from 'typeorm';
import { Entity, Column, PrimaryGeneratedColumn, ManyToOne, CreateDateColumn, UpdateDateColumn, JoinColumn } from 'typeorm';
import { User } from './User';
import { Course } from './Course';

Expand Down
9 changes: 1 addition & 8 deletions src/entity/Review.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
import { Entity,
Column,
PrimaryGeneratedColumn,
ManyToOne,
CreateDateColumn,
UpdateDateColumn,
JoinColumn
} from 'typeorm';
import { Entity, Column, PrimaryGeneratedColumn, ManyToOne, CreateDateColumn, UpdateDateColumn, JoinColumn } from 'typeorm';
import { User } from './User';
import { Course } from './Course';

Expand Down
9 changes: 1 addition & 8 deletions src/entity/Section.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
import { Entity,
Column,
PrimaryGeneratedColumn,
ManyToOne,
CreateDateColumn,
UpdateDateColumn,
JoinColumn
} from 'typeorm';
import { Entity, Column, PrimaryGeneratedColumn, ManyToOne, CreateDateColumn, UpdateDateColumn, JoinColumn } from 'typeorm';
import { Course } from './Course';

@Entity('sections')
Expand Down
7 changes: 1 addition & 6 deletions src/entity/User.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
import { Entity,
Column,
PrimaryGeneratedColumn,
CreateDateColumn,
UpdateDateColumn
} from 'typeorm';
import { Entity, Column, PrimaryGeneratedColumn, CreateDateColumn, UpdateDateColumn } from 'typeorm';

@Entity('users')
export class User {
Expand Down
12 changes: 12 additions & 0 deletions src/route/enrollment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Router } from 'express';
import { enrollInCourse, getUserEnrollments, updateLessonProgress } from '../controller/enrollment';

const router = Router();

router.post('/', enrollInCourse);

router.get('/:userId', getUserEnrollments);

router.put('/:enrollmentId/lessons/:lessonId/progress', updateLessonProgress);

export default router;
8 changes: 8 additions & 0 deletions src/route/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Router } from 'express';
import enrollmentRoutes from './enrollment';

const router = Router();

router.use('/enrollments', enrollmentRoutes);

export default router;
70 changes: 70 additions & 0 deletions src/service/enrollment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { AppDataSource } from '../repos/db';
import { Enrollment } from '../entity/Enrollment';
import { User } from '../entity/User';
import { Course } from '../entity/Course';
import { EnrollmentLesson } from '../entity/EnrollmentLesson';
import { Lesson } from '../entity/Lesson';

export class EnrollmentService {
private enrollmentRepository = AppDataSource.getRepository(Enrollment);
private courseRepository = AppDataSource.getRepository(Course);
private userRepository = AppDataSource.getRepository(User);
private enrollmentLessonRepository = AppDataSource.getRepository(EnrollmentLesson);
private lessonRepository = AppDataSource.getRepository(Lesson);

async enrollUserInCourse(userId: number, courseId: number): Promise<Enrollment> {
const user = await this.userRepository.findOne({ where: { id: userId } });
const course = await this.courseRepository.findOne({ where: { id: courseId } });

if (!user || !course) {
throw new Error('User or Course not found');
}

const enrollment = this.enrollmentRepository.create({
user,
course,
enrollment_date: new Date(),
progress: 0,
});

await this.enrollmentRepository.save(enrollment);

const lessons = await this.lessonRepository.find({ where: { section: { course_id: courseId } } });
const enrollmentLessons = lessons.map(lesson => this.enrollmentLessonRepository.create({
enrollment,
lesson,
progress: 0,
}));

await this.enrollmentLessonRepository.save(enrollmentLessons);

return enrollment;
}

async getUserEnrollments(userId: number): Promise<Enrollment[]> {
return this.enrollmentRepository.find({
where: { user: { id: userId } },
relations: ['course'],
});
}

async updateLessonProgress(enrollmentId: number, lessonId: number, progress: number): Promise<EnrollmentLesson> {
const enrollmentLesson = await this.enrollmentLessonRepository.findOne({
where: { enrollment_id: enrollmentId, lesson_id: lessonId },
});

if (!enrollmentLesson) {
throw new Error('EnrollmentLesson not found');
}

enrollmentLesson.progress = progress;

if (progress === 100) {
enrollmentLesson.completion_date = new Date();
}

await this.enrollmentLessonRepository.save(enrollmentLesson);

return enrollmentLesson;
}
}