chore: add update and delete of learning and learnign category
This commit is contained in:
@@ -448,6 +448,7 @@ export const enum LearningMessage {
|
|||||||
CATEGORY_NOT_FOUND = "دسته بندی با این مشخصات یافت نشد",
|
CATEGORY_NOT_FOUND = "دسته بندی با این مشخصات یافت نشد",
|
||||||
CATEGORY_MUST_BE_ID = "دستهبندی باید شناسه باشد",
|
CATEGORY_MUST_BE_ID = "دستهبندی باید شناسه باشد",
|
||||||
CATEGORY_MUST_BE_UUID = "دستهبندی باید UUID باشد",
|
CATEGORY_MUST_BE_UUID = "دستهبندی باید UUID باشد",
|
||||||
|
CATEGORY_NAME_EXIST = "دسته بندی با این نام قبلا ثبت شده است",
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enum DiscountMessage {
|
export const enum DiscountMessage {
|
||||||
|
|||||||
@@ -259,6 +259,8 @@ export class DanakServicesService {
|
|||||||
const serviceQueryBuilder = this.danakServicesRepository
|
const serviceQueryBuilder = this.danakServicesRepository
|
||||||
.createQueryBuilder("service")
|
.createQueryBuilder("service")
|
||||||
.where("service.deletedAt IS NULL")
|
.where("service.deletedAt IS NULL")
|
||||||
|
.leftJoin("service.category", "category")
|
||||||
|
.addSelect(["category.id", "category.title"])
|
||||||
.leftJoinAndSelect("service.images", "images")
|
.leftJoinAndSelect("service.images", "images")
|
||||||
.leftJoinAndSelect("service.subscriptionPlans", "subscriptionPlans")
|
.leftJoinAndSelect("service.subscriptionPlans", "subscriptionPlans")
|
||||||
.leftJoin("service.reviews", "reviews", "reviews.status = :reviewStatus", { reviewStatus: ReviewStatus.APPROVED })
|
.leftJoin("service.reviews", "reviews", "reviews.status = :reviewStatus", { reviewStatus: ReviewStatus.APPROVED })
|
||||||
@@ -286,7 +288,7 @@ export class DanakServicesService {
|
|||||||
// "averageRating",
|
// "averageRating",
|
||||||
// )
|
// )
|
||||||
.andWhere("service.id = :serviceId", { serviceId })
|
.andWhere("service.id = :serviceId", { serviceId })
|
||||||
.groupBy("service.id, images.id, subscriptionPlans.id, reviews.id, user.id");
|
.groupBy("service.id,category.id, images.id, subscriptionPlans.id, reviews.id, user.id");
|
||||||
|
|
||||||
if (!isAdmin) {
|
if (!isAdmin) {
|
||||||
serviceQueryBuilder
|
serviceQueryBuilder
|
||||||
|
|||||||
@@ -1,40 +1,37 @@
|
|||||||
import { ApiProperty } from "@nestjs/swagger";
|
import { ApiProperty } from "@nestjs/swagger";
|
||||||
import { IsNotEmpty, IsOptional, IsString, IsUUID } from "class-validator";
|
import { IsNotEmpty, IsNumberString, IsString, IsUUID, IsUrl } from "class-validator";
|
||||||
|
|
||||||
import { LearningMessage } from "../../../common/enums/message.enum";
|
import { LearningMessage } from "../../../common/enums/message.enum";
|
||||||
|
|
||||||
export class CreateLearningDto {
|
export class CreateLearningDto {
|
||||||
|
@IsNotEmpty({ message: LearningMessage.CATEGORY_MUST_BE_ID })
|
||||||
|
@IsUUID("4", { message: LearningMessage.CATEGORY_MUST_BE_UUID })
|
||||||
|
@ApiProperty({ description: "Category ID", example: "d290f1ee-6c54-4b01-90e6-d701748f0851" })
|
||||||
|
categoryId: string;
|
||||||
|
|
||||||
@ApiProperty({ description: "Title of the learning", maxLength: 200 })
|
@ApiProperty({ description: "Title of the learning", maxLength: 200 })
|
||||||
@IsString({ message: LearningMessage.TITLE_STRING })
|
@IsString({ message: LearningMessage.TITLE_STRING })
|
||||||
@IsNotEmpty({ message: LearningMessage.TITLE_REQUIRED })
|
@IsNotEmpty({ message: LearningMessage.TITLE_REQUIRED })
|
||||||
title: string;
|
title: string;
|
||||||
|
|
||||||
@ApiProperty({ description: "Description of the learning" })
|
|
||||||
@IsString({ message: LearningMessage.DESCRIPTION_STRING })
|
|
||||||
@IsNotEmpty({ message: LearningMessage.DESCRIPTION_REQUIRED })
|
@IsNotEmpty({ message: LearningMessage.DESCRIPTION_REQUIRED })
|
||||||
|
@IsString({ message: LearningMessage.DESCRIPTION_STRING })
|
||||||
|
@ApiProperty({ description: "Description of the learning" })
|
||||||
description: string;
|
description: string;
|
||||||
|
|
||||||
@ApiProperty({ description: "Cover image URL" })
|
|
||||||
@IsString({ message: LearningMessage.COVER_URL_INVALID })
|
|
||||||
@IsNotEmpty({ message: LearningMessage.COVER_URL_REQUIRED })
|
@IsNotEmpty({ message: LearningMessage.COVER_URL_REQUIRED })
|
||||||
|
@IsUrl({ protocols: ["http", "https"], require_protocol: true }, { message: LearningMessage.COVER_URL_INVALID })
|
||||||
|
@IsString({ message: LearningMessage.COVER_URL_INVALID })
|
||||||
|
@ApiProperty({ description: "Cover image URL" })
|
||||||
coverUrl: string;
|
coverUrl: string;
|
||||||
|
|
||||||
|
@IsString({ message: LearningMessage.VIDEO_URL_INVALID })
|
||||||
|
@IsUrl({ protocols: ["http", "https"], require_protocol: true }, { message: LearningMessage.VIDEO_URL_INVALID })
|
||||||
@ApiProperty({ description: "Video URL", required: false })
|
@ApiProperty({ description: "Video URL", required: false })
|
||||||
@IsString({ message: LearningMessage.VIDEO_URL_INVALID })
|
videoUrl: string;
|
||||||
@IsOptional()
|
|
||||||
videoUrl?: string;
|
|
||||||
|
|
||||||
|
@IsNotEmpty({ message: LearningMessage.VIDEO_DURATION_INVALID })
|
||||||
|
@IsNumberString({ no_symbols: true }, { message: LearningMessage.VIDEO_DURATION_INVALID })
|
||||||
@ApiProperty({ description: "Video Duration", required: false })
|
@ApiProperty({ description: "Video Duration", required: false })
|
||||||
@IsString({ message: LearningMessage.VIDEO_URL_INVALID })
|
videoDuration: string;
|
||||||
@IsOptional()
|
|
||||||
videoDuration?: string;
|
|
||||||
|
|
||||||
@IsOptional()
|
|
||||||
@IsNotEmpty({ message: LearningMessage.CATEGORY_MUST_BE_ID })
|
|
||||||
@IsUUID("4", { message: LearningMessage.CATEGORY_MUST_BE_UUID })
|
|
||||||
@ApiProperty({
|
|
||||||
description: "Category ID",
|
|
||||||
example: "d290f1ee-6c54-4b01-90e6-d701748f0851",
|
|
||||||
})
|
|
||||||
categoryId: string;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import { PartialType } from "@nestjs/swagger";
|
||||||
|
|
||||||
|
import { CreateLearningCategoryDto } from "./create-learning-category.dto";
|
||||||
|
|
||||||
|
export class UpdateLearningCategoryDto extends PartialType(CreateLearningCategoryDto) {}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import { PartialType } from "@nestjs/swagger";
|
||||||
|
|
||||||
|
import { CreateLearningDto } from "./create-learning.dto";
|
||||||
|
|
||||||
|
export class UpdateLearningDto extends PartialType(CreateLearningDto) {}
|
||||||
@@ -1,13 +1,16 @@
|
|||||||
import { Column, Entity, OneToMany } from "typeorm";
|
import { Column, DeleteDateColumn, Entity, OneToMany } from "typeorm";
|
||||||
|
|
||||||
import { Learning } from "./learning.entity";
|
import { Learning } from "./learning.entity";
|
||||||
import { BaseEntity } from "../../../common/entities/base.entity";
|
import { BaseEntity } from "../../../common/entities/base.entity";
|
||||||
|
|
||||||
@Entity()
|
@Entity()
|
||||||
export class LearningCategory extends BaseEntity {
|
export class LearningCategory extends BaseEntity {
|
||||||
@Column({ type: "varchar", length: 100 })
|
@Column({ type: "varchar", length: 100, unique: true })
|
||||||
name: string;
|
name: string;
|
||||||
|
|
||||||
@OneToMany(() => Learning, (learning) => learning.category)
|
@OneToMany(() => Learning, (learning) => learning.category)
|
||||||
learnings: Learning[];
|
learnings: Learning[];
|
||||||
|
|
||||||
|
@DeleteDateColumn()
|
||||||
|
deletedAt?: Date;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,6 @@ export class LearningProgress extends BaseEntity {
|
|||||||
@ManyToOne(() => Learning, (learning) => learning.learningProgress)
|
@ManyToOne(() => Learning, (learning) => learning.learningProgress)
|
||||||
learning: Learning;
|
learning: Learning;
|
||||||
|
|
||||||
@Column({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
|
@Column({ type: "timestamptz", default: () => "CURRENT_TIMESTAMP" })
|
||||||
watchedAt: Date;
|
watchedAt: Date;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Column, Entity, ManyToOne, OneToMany } from "typeorm";
|
import { Column, DeleteDateColumn, Entity, ManyToOne, OneToMany } from "typeorm";
|
||||||
|
|
||||||
import { LearningCategory } from "./learning-category.entity";
|
import { LearningCategory } from "./learning-category.entity";
|
||||||
import { LearningProgress } from "./learning-progress.entity";
|
import { LearningProgress } from "./learning-progress.entity";
|
||||||
@@ -26,4 +26,7 @@ export class Learning extends BaseEntity {
|
|||||||
|
|
||||||
@OneToMany(() => LearningProgress, (learningProgress) => learningProgress.learning)
|
@OneToMany(() => LearningProgress, (learningProgress) => learningProgress.learning)
|
||||||
learningProgress: LearningProgress[];
|
learningProgress: LearningProgress[];
|
||||||
|
|
||||||
|
@DeleteDateColumn()
|
||||||
|
deletedAt?: Date;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { Body, Controller, Get, Param, Post } from "@nestjs/common";
|
import { Body, Controller, Delete, Get, Param, Patch, Post } from "@nestjs/common";
|
||||||
import { ApiOperation, ApiTags } from "@nestjs/swagger";
|
import { ApiOperation, ApiTags } from "@nestjs/swagger";
|
||||||
|
|
||||||
import { CreateLearningCategoryDto } from "./DTO/create-learning-category.dto";
|
import { CreateLearningCategoryDto } from "./DTO/create-learning-category.dto";
|
||||||
import { CreateLearningDto } from "./DTO/create-learning.dto";
|
import { CreateLearningDto } from "./DTO/create-learning.dto";
|
||||||
|
import { UpdateLearningCategoryDto } from "./DTO/update-learning-category.dto";
|
||||||
import { LearningService } from "./providers/learning.service";
|
import { LearningService } from "./providers/learning.service";
|
||||||
import { AuthGuards } from "../../common/decorators/auth-guard.decorator";
|
import { AuthGuards } from "../../common/decorators/auth-guard.decorator";
|
||||||
import { PermissionsDec } from "../../common/decorators/permission.decorator";
|
import { PermissionsDec } from "../../common/decorators/permission.decorator";
|
||||||
@@ -15,16 +16,26 @@ import { PermissionEnum } from "../users/enums/permission.enum";
|
|||||||
export class LearningController {
|
export class LearningController {
|
||||||
constructor(private readonly learningService: LearningService) {}
|
constructor(private readonly learningService: LearningService) {}
|
||||||
|
|
||||||
//************************ */
|
@ApiOperation({ summary: "Create learning video" })
|
||||||
|
|
||||||
@ApiOperation({ summary: "Create learning" })
|
|
||||||
@PermissionsDec(PermissionEnum.LEARNINGS)
|
@PermissionsDec(PermissionEnum.LEARNINGS)
|
||||||
@Post()
|
@Post()
|
||||||
create(@Body() createDto: CreateLearningDto) {
|
createLearningVideo(@Body() createDto: CreateLearningDto) {
|
||||||
return this.learningService.createLearning(createDto);
|
return this.learningService.createLearningVideo(createDto);
|
||||||
}
|
}
|
||||||
|
|
||||||
//************************ */
|
@ApiOperation({ summary: "find learnings video" })
|
||||||
|
@Get()
|
||||||
|
findAllLearnings() {
|
||||||
|
return this.learningService.findLearningsVideos();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation({ summary: "find learning video by id" })
|
||||||
|
@Get(":id")
|
||||||
|
findLearningVideoById(@Param() paramDto: ParamDto) {
|
||||||
|
return this.learningService.findLearningVideoById(paramDto.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------- category management ----------------------
|
||||||
|
|
||||||
@ApiOperation({ summary: "Create learning category" })
|
@ApiOperation({ summary: "Create learning category" })
|
||||||
@PermissionsDec(PermissionEnum.LEARNINGS)
|
@PermissionsDec(PermissionEnum.LEARNINGS)
|
||||||
@@ -33,37 +44,29 @@ export class LearningController {
|
|||||||
return this.learningService.createLearningCategory(createDto);
|
return this.learningService.createLearningCategory(createDto);
|
||||||
}
|
}
|
||||||
|
|
||||||
//************************ */
|
@ApiOperation({ summary: "find learning categories" })
|
||||||
|
|
||||||
@ApiOperation({ summary: "find all learnings" })
|
|
||||||
@Get()
|
|
||||||
findAllLearnings() {
|
|
||||||
return this.learningService.findAllLearnings();
|
|
||||||
}
|
|
||||||
|
|
||||||
//************************ */
|
|
||||||
|
|
||||||
@ApiOperation({ summary: "find one learning by id" })
|
|
||||||
@Get(":id")
|
|
||||||
findOneLearning(@Param() paramDto: ParamDto) {
|
|
||||||
return this.learningService.findOneLearning(paramDto.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
//************************ */
|
|
||||||
|
|
||||||
@ApiOperation({ summary: "find all learning category" })
|
|
||||||
@Get("category")
|
@Get("category")
|
||||||
findAllCategories() {
|
findCategories() {
|
||||||
return this.learningService.findAllCategories();
|
return this.learningService.findCategories();
|
||||||
}
|
}
|
||||||
|
|
||||||
//************************ */
|
|
||||||
|
|
||||||
@ApiOperation({ summary: "find one learning category by id" })
|
@ApiOperation({ summary: "find one learning category by id" })
|
||||||
@Get("category/:id")
|
@Get("category/:id")
|
||||||
findOneCategory(@Param() paramDto: ParamDto) {
|
findCategoryById(@Param() paramDto: ParamDto) {
|
||||||
return this.learningService.findOneCategory(paramDto.id);
|
return this.learningService.findCategoryById(paramDto.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
//************************ */
|
@ApiOperation({ summary: "update learning category ==> admin route" })
|
||||||
|
@PermissionsDec(PermissionEnum.LEARNINGS)
|
||||||
|
@Patch("category/:id")
|
||||||
|
updateLearningCategory(@Param() paramDto: ParamDto, @Body() updateDto: UpdateLearningCategoryDto) {
|
||||||
|
return this.learningService.updateLearningCategory(paramDto.id, updateDto);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation({ summary: "delete category by id" })
|
||||||
|
@PermissionsDec(PermissionEnum.LEARNINGS)
|
||||||
|
@Delete("category/:id")
|
||||||
|
deleteCategoryById(@Param() paramDto: ParamDto) {
|
||||||
|
return this.learningService.deleteCategoryById(paramDto.id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
import { BadRequestException, Injectable } from "@nestjs/common";
|
import { BadRequestException, Injectable } from "@nestjs/common";
|
||||||
|
import { IsNull, Not } from "typeorm";
|
||||||
|
|
||||||
import { CommonMessage, LearningMessage } from "../../../common/enums/message.enum";
|
import { CommonMessage, LearningMessage } from "../../../common/enums/message.enum";
|
||||||
import { UsersService } from "../../users/providers/users.service";
|
import { UsersService } from "../../users/providers/users.service";
|
||||||
import { CreateLearningCategoryDto } from "../DTO/create-learning-category.dto";
|
import { CreateLearningCategoryDto } from "../DTO/create-learning-category.dto";
|
||||||
import { CreateLearningDto } from "../DTO/create-learning.dto";
|
import { CreateLearningDto } from "../DTO/create-learning.dto";
|
||||||
|
import { UpdateLearningCategoryDto } from "../DTO/update-learning-category.dto";
|
||||||
|
import { UpdateLearningDto } from "../DTO/update-learning.dto";
|
||||||
import { LearningCategoryRepository } from "../repositories/learning-category.repository";
|
import { LearningCategoryRepository } from "../repositories/learning-category.repository";
|
||||||
import { LearningProgressRepository } from "../repositories/learning-progress.repository";
|
import { LearningProgressRepository } from "../repositories/learning-progress.repository";
|
||||||
import { LearningRepository } from "../repositories/learning.repository";
|
import { LearningRepository } from "../repositories/learning.repository";
|
||||||
@@ -17,15 +20,12 @@ export class LearningService {
|
|||||||
private readonly usersService: UsersService,
|
private readonly usersService: UsersService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
//******************** */
|
//********************************************* */
|
||||||
|
|
||||||
async createLearning(createDto: CreateLearningDto) {
|
async createLearningVideo(createDto: CreateLearningDto) {
|
||||||
const { category } = await this.findOneCategory(createDto.categoryId);
|
const { category } = await this.findCategoryById(createDto.categoryId);
|
||||||
|
|
||||||
const learning = this.learningRepository.create({
|
const learning = this.learningRepository.create({ ...createDto, category });
|
||||||
...createDto,
|
|
||||||
category,
|
|
||||||
});
|
|
||||||
await this.learningRepository.save(learning);
|
await this.learningRepository.save(learning);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -33,74 +33,113 @@ export class LearningService {
|
|||||||
learning,
|
learning,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
//********************************************* */
|
||||||
|
|
||||||
//******************** */
|
async updateLearningVideo(learningId: string, updateDto: UpdateLearningDto) {
|
||||||
|
const { learning } = await this.findLearningVideoById(learningId);
|
||||||
|
|
||||||
async findAllLearnings() {
|
if (updateDto.categoryId) {
|
||||||
const learnings = await this.learningRepository.find();
|
const { category } = await this.findCategoryById(updateDto.categoryId);
|
||||||
|
learning.category = category;
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.learningRepository.save({ ...learning, ...updateDto });
|
||||||
|
return {
|
||||||
|
message: CommonMessage.UPDATE_SUCCESS,
|
||||||
|
learning,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
//********************************************* */
|
||||||
|
|
||||||
|
async deleteLearningVideoById(learningId: string) {
|
||||||
|
await this.findLearningVideoById(learningId);
|
||||||
|
await this.learningRepository.softDelete(learningId);
|
||||||
|
|
||||||
|
return {
|
||||||
|
message: CommonMessage.DELETED,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
//********************************************* */
|
||||||
|
|
||||||
|
async findLearningsVideos() {
|
||||||
|
const learnings = await this.learningRepository.findBy({ deletedAt: IsNull() });
|
||||||
|
|
||||||
return { learnings };
|
return { learnings };
|
||||||
}
|
}
|
||||||
|
//********************************************* */
|
||||||
|
|
||||||
//******************** */
|
async findLearningVideoById(id: string) {
|
||||||
|
const learning = await this.learningRepository.findOneBy({ id, deletedAt: IsNull() });
|
||||||
async findOneLearning(id: string) {
|
|
||||||
const learning = await this.learningRepository.findOneBy({
|
|
||||||
id,
|
|
||||||
});
|
|
||||||
if (!learning) throw new BadRequestException(LearningMessage.NOT_FOUND);
|
if (!learning) throw new BadRequestException(LearningMessage.NOT_FOUND);
|
||||||
|
|
||||||
return { learning };
|
return { learning };
|
||||||
}
|
}
|
||||||
|
//********************************************* */
|
||||||
//******************** */
|
|
||||||
|
|
||||||
async createLearningCategory(createDto: CreateLearningCategoryDto) {
|
async createLearningCategory(createDto: CreateLearningCategoryDto) {
|
||||||
|
const existCategory = await this.learningCategoryRepository.findOneBy({ name: createDto.name });
|
||||||
|
if (existCategory) throw new BadRequestException(LearningMessage.CATEGORY_NAME_EXIST);
|
||||||
|
|
||||||
const category = this.learningCategoryRepository.create(createDto);
|
const category = this.learningCategoryRepository.create(createDto);
|
||||||
await this.learningCategoryRepository.save(category);
|
await this.learningCategoryRepository.save(category);
|
||||||
|
|
||||||
return { category };
|
return { category };
|
||||||
}
|
}
|
||||||
|
//********************************************* */
|
||||||
|
|
||||||
//******************** */
|
async updateLearningCategory(categoryId: string, updateDto: UpdateLearningCategoryDto) {
|
||||||
|
const category = await this.learningCategoryRepository.findOneBy({ id: categoryId });
|
||||||
|
if (!category) throw new BadRequestException(LearningMessage.CATEGORY_NOT_FOUND);
|
||||||
|
|
||||||
async findAllCategories() {
|
if (updateDto.name) {
|
||||||
const categories = await this.learningCategoryRepository.find();
|
const existCategory = await this.learningCategoryRepository.findOneBy({ name: updateDto.name, id: Not(categoryId) });
|
||||||
|
if (existCategory) throw new BadRequestException(LearningMessage.CATEGORY_NAME_EXIST);
|
||||||
|
category.name = updateDto.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.learningCategoryRepository.save({ ...category });
|
||||||
|
return {
|
||||||
|
message: CommonMessage.UPDATE_SUCCESS,
|
||||||
|
category,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
//********************************************* */
|
||||||
|
|
||||||
|
async deleteCategoryById(categoryId: string) {
|
||||||
|
await this.findCategoryById(categoryId);
|
||||||
|
|
||||||
|
await this.learningCategoryRepository.softDelete(categoryId);
|
||||||
|
return {
|
||||||
|
message: CommonMessage.DELETED,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
//********************************************* */
|
||||||
|
|
||||||
|
async findCategories() {
|
||||||
|
const categories = await this.learningCategoryRepository.findBy({ deletedAt: IsNull() });
|
||||||
|
|
||||||
return { categories };
|
return { categories };
|
||||||
}
|
}
|
||||||
|
//********************************************* */
|
||||||
|
|
||||||
//******************** */
|
async findCategoryById(id: string) {
|
||||||
|
const category = await this.learningCategoryRepository.findOneBy({ id, deletedAt: IsNull() });
|
||||||
async findOneCategory(id: string) {
|
|
||||||
const category = await this.learningCategoryRepository.findOneBy({
|
|
||||||
id,
|
|
||||||
});
|
|
||||||
if (!category) throw new BadRequestException(LearningMessage.CATEGORY_NOT_FOUND);
|
if (!category) throw new BadRequestException(LearningMessage.CATEGORY_NOT_FOUND);
|
||||||
|
|
||||||
return { category };
|
return { category };
|
||||||
}
|
}
|
||||||
|
//********************************************* */
|
||||||
//******************** */
|
|
||||||
|
|
||||||
async trackProgress(userId: string, learningId: string) {
|
async trackProgress(userId: string, learningId: string) {
|
||||||
const { user } = await this.usersService.findOneById(userId);
|
const { user } = await this.usersService.findOneById(userId);
|
||||||
const { learning } = await this.findOneLearning(learningId);
|
const { learning } = await this.findLearningVideoById(learningId);
|
||||||
|
|
||||||
const progress = this.learningProgressRepository.create({
|
const progress = this.learningProgressRepository.create({ user, learning });
|
||||||
user,
|
|
||||||
learning,
|
|
||||||
watchedAt: new Date(),
|
|
||||||
});
|
|
||||||
return this.learningProgressRepository.save(progress);
|
return this.learningProgressRepository.save(progress);
|
||||||
}
|
}
|
||||||
|
//********************************************* */
|
||||||
//******************** */
|
|
||||||
|
|
||||||
async getUserProgress(userId: string) {
|
async getUserProgress(userId: string) {
|
||||||
return this.learningProgressRepository.find({
|
return this.learningProgressRepository.find({ where: { user: { id: userId } }, relations: { learning: true } });
|
||||||
where: { user: { id: userId } },
|
|
||||||
relations: ["learning"],
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user