chore: add service list fetch for admin with filters
This commit is contained in:
@@ -1,9 +1,9 @@
|
|||||||
import { ApiPropertyOptional } from "@nestjs/swagger";
|
import { ApiPropertyOptional } from "@nestjs/swagger";
|
||||||
import { IsEnum, IsOptional, IsString } from "class-validator";
|
import { Type } from "class-transformer";
|
||||||
|
import { IsOptional, IsString } from "class-validator";
|
||||||
|
|
||||||
import { PaginationDto } from "../../../common/DTO/pagination.dto";
|
import { PaginationDto } from "../../../common/DTO/pagination.dto";
|
||||||
import { CategoryMessage } from "../../../common/enums/message.enum";
|
import { CategoryMessage } from "../../../common/enums/message.enum";
|
||||||
import { ServiceStatus } from "../enums/service-status.enum";
|
|
||||||
|
|
||||||
export class DanakServicesSearchQueryDto extends PaginationDto {
|
export class DanakServicesSearchQueryDto extends PaginationDto {
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@@ -12,12 +12,18 @@ export class DanakServicesSearchQueryDto extends PaginationDto {
|
|||||||
categoryId?: string;
|
categoryId?: string;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsEnum(ServiceStatus)
|
@Type(() => Number)
|
||||||
@ApiPropertyOptional({ description: "services status", enum: ServiceStatus, example: ServiceStatus.ACTIVE })
|
// @IsBoolean({ message: CategoryMessage.IS_ACTIVE_SHOULD_BE_BOOLEAN })
|
||||||
status?: ServiceStatus;
|
@ApiPropertyOptional({ description: "service status", example: 1 })
|
||||||
|
isActive?: number;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString({ message: CategoryMessage.SEARCH_QUERY_STRING })
|
@IsString({ message: CategoryMessage.SEARCH_QUERY_STRING })
|
||||||
@ApiPropertyOptional({ description: "Search query", example: "search query" })
|
@ApiPropertyOptional({ description: "Search query", example: "search query" })
|
||||||
q?: string;
|
q?: string;
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@Type(() => Number)
|
||||||
|
@ApiPropertyOptional({ description: "is danak suggest this service", example: 1 })
|
||||||
|
isDanakSuggest?: number;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,6 +70,15 @@ export class DanakServicesController {
|
|||||||
return this.danakServicesService.getServicesList(queryDto);
|
return this.danakServicesService.getServicesList(queryDto);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@AuthGuards()
|
||||||
|
@Roles(RoleEnum.ADMIN)
|
||||||
|
@ApiOperation({ summary: "toggle status of danak service => admin route" })
|
||||||
|
@HttpCode(HttpStatus.OK)
|
||||||
|
@Post("toggle-status/:id")
|
||||||
|
toggleServiceStatus(@Param() paramDto: ParamDto) {
|
||||||
|
return this.danakServicesService.toggleServiceStatus(paramDto);
|
||||||
|
}
|
||||||
|
|
||||||
@AuthGuards()
|
@AuthGuards()
|
||||||
@Roles(RoleEnum.USER)
|
@Roles(RoleEnum.USER)
|
||||||
@ApiOperation({ summary: "get all user purchased danak services" })
|
@ApiOperation({ summary: "get all user purchased danak services" })
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import { BaseEntity } from "../../../common/entities/base.entity";
|
|||||||
import { Announcement } from "../../announcements/entities/announcement.entity";
|
import { Announcement } from "../../announcements/entities/announcement.entity";
|
||||||
import { Ticket } from "../../tickets/entities/ticket.entity";
|
import { Ticket } from "../../tickets/entities/ticket.entity";
|
||||||
import { User } from "../../users/entities/user.entity";
|
import { User } from "../../users/entities/user.entity";
|
||||||
import { ServiceStatus } from "../enums/service-status.enum";
|
|
||||||
import { ServicesLanguage } from "../enums/services-language.enum";
|
import { ServicesLanguage } from "../enums/services-language.enum";
|
||||||
|
|
||||||
@Entity()
|
@Entity()
|
||||||
@@ -38,8 +37,8 @@ export class DanakService extends BaseEntity {
|
|||||||
@Column({ type: "text", nullable: false })
|
@Column({ type: "text", nullable: false })
|
||||||
metaDescription: string;
|
metaDescription: string;
|
||||||
|
|
||||||
@Column({ type: "enum", enum: ServiceStatus, nullable: false, default: ServiceStatus.IN_ACTIVE })
|
@Column({ type: "boolean", default: false })
|
||||||
status: ServiceStatus;
|
isActive: boolean;
|
||||||
|
|
||||||
@Column({ type: "varchar", length: 255, nullable: false })
|
@Column({ type: "varchar", length: 255, nullable: false })
|
||||||
link: string;
|
link: string;
|
||||||
|
|||||||
@@ -100,6 +100,17 @@ export class DanakServicesService {
|
|||||||
isActive: category.isActive,
|
isActive: category.isActive,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async toggleServiceStatus(paramDto: ParamDto) {
|
||||||
|
const service = await this.danakServicesRepository.findServiceById(paramDto.id);
|
||||||
|
if (!service) throw new BadRequestException(ServiceMessage.SERVICE_NOT_EXIST);
|
||||||
|
service.isActive = !service.isActive;
|
||||||
|
await this.danakServicesRepository.save(service);
|
||||||
|
return {
|
||||||
|
message: CommonMessage.UPDATE_SUCCESS,
|
||||||
|
isActive: service.isActive,
|
||||||
|
};
|
||||||
|
}
|
||||||
/******************************************** */
|
/******************************************** */
|
||||||
async createService(createDto: CreateServiceDto) {
|
async createService(createDto: CreateServiceDto) {
|
||||||
const category = await this.danakServicesCategoryRepository.findOneById(createDto.categoryId);
|
const category = await this.danakServicesCategoryRepository.findOneById(createDto.categoryId);
|
||||||
@@ -131,9 +142,14 @@ export class DanakServicesService {
|
|||||||
.skip(skip)
|
.skip(skip)
|
||||||
.take(limit);
|
.take(limit);
|
||||||
|
|
||||||
if (queryDto.status) {
|
if (queryDto.isActive) {
|
||||||
queryBuilder.andWhere("service.status = :status", { status: queryDto.status });
|
queryBuilder.andWhere("service.isActive = :isActive", { isActive: queryDto.isActive === 1 });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (queryDto.isDanakSuggest) {
|
||||||
|
queryBuilder.andWhere("service.isDanakSuggest = :isDanakSuggest", { isDanakSuggest: queryDto.isDanakSuggest === 1 });
|
||||||
|
}
|
||||||
|
|
||||||
if (queryDto.categoryId) {
|
if (queryDto.categoryId) {
|
||||||
queryBuilder.andWhere("service.categoryId = :categoryId", { categoryId: queryDto.categoryId });
|
queryBuilder.andWhere("service.categoryId = :categoryId", { categoryId: queryDto.categoryId });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,4 +13,8 @@ export class DanakServicesRepository extends Repository<DanakService> {
|
|||||||
async findOneByName(name: string): Promise<DanakService | null> {
|
async findOneByName(name: string): Promise<DanakService | null> {
|
||||||
return this.findOneBy({ name });
|
return this.findOneBy({ name });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async findServiceById(id: string): Promise<DanakService | null> {
|
||||||
|
return this.findOneBy({ id });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import { ApiProperty } from "@nestjs/swagger";
|
||||||
|
|
||||||
|
import { IFile } from "../../utils/interfaces/IFile";
|
||||||
|
|
||||||
|
export class UploadSingleFileDto {
|
||||||
|
@ApiProperty({ type: "string", format: "binary", nullable: false })
|
||||||
|
file: IFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class UploadMultipleFileDto {
|
||||||
|
@ApiProperty({
|
||||||
|
required: true,
|
||||||
|
type: "array",
|
||||||
|
items: {
|
||||||
|
type: "string",
|
||||||
|
format: "binary",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
files: IFile[];
|
||||||
|
}
|
||||||
@@ -2,7 +2,9 @@ import { FileInterceptor, FilesInterceptor } from "@nest-lab/fastify-multer";
|
|||||||
import { Controller, Post, UploadedFile, UploadedFiles, UseInterceptors } from "@nestjs/common";
|
import { Controller, Post, UploadedFile, UploadedFiles, UseInterceptors } from "@nestjs/common";
|
||||||
import { ApiBody, ApiConsumes, ApiOperation, ApiTags } from "@nestjs/swagger";
|
import { ApiBody, ApiConsumes, ApiOperation, ApiTags } from "@nestjs/swagger";
|
||||||
|
|
||||||
|
import { UploadMultipleFileDto, UploadSingleFileDto } from "./DTO/upload-file.dto";
|
||||||
import { UploaderService } from "./uploader.service";
|
import { UploaderService } from "./uploader.service";
|
||||||
|
import { AuthGuards } from "../../common/decorators/auth-guard.decorator";
|
||||||
import { IFile } from "../utils/interfaces/IFile";
|
import { IFile } from "../utils/interfaces/IFile";
|
||||||
|
|
||||||
@ApiTags("Uploader")
|
@ApiTags("Uploader")
|
||||||
@@ -10,45 +12,22 @@ import { IFile } from "../utils/interfaces/IFile";
|
|||||||
export class UploaderController {
|
export class UploaderController {
|
||||||
constructor(private readonly uploaderService: UploaderService) {}
|
constructor(private readonly uploaderService: UploaderService) {}
|
||||||
|
|
||||||
|
@AuthGuards()
|
||||||
@ApiOperation({ summary: "Uploads a single file" })
|
@ApiOperation({ summary: "Uploads a single file" })
|
||||||
@ApiConsumes("multipart/form-data")
|
@ApiConsumes("multipart/form-data")
|
||||||
@UseInterceptors(FileInterceptor("file"))
|
@UseInterceptors(FileInterceptor("file"))
|
||||||
@ApiBody({
|
@ApiBody({ type: UploadSingleFileDto })
|
||||||
required: true,
|
|
||||||
schema: {
|
|
||||||
type: "object",
|
|
||||||
properties: {
|
|
||||||
file: {
|
|
||||||
type: "string",
|
|
||||||
format: "binary",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
@Post("single-file")
|
@Post("single-file")
|
||||||
async uploadFile(@UploadedFile() file: IFile) {
|
async uploadFile(@UploadedFile() file: IFile) {
|
||||||
console.log(file);
|
console.log(file);
|
||||||
return await this.uploaderService.upload(file);
|
return await this.uploaderService.upload(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@AuthGuards()
|
||||||
@ApiOperation({ summary: "Uploads multiple files" })
|
@ApiOperation({ summary: "Uploads multiple files" })
|
||||||
@ApiConsumes("multipart/form-data")
|
@ApiConsumes("multipart/form-data")
|
||||||
@UseInterceptors(FilesInterceptor("files"))
|
@UseInterceptors(FilesInterceptor("files"))
|
||||||
@ApiBody({
|
@ApiBody({ type: UploadMultipleFileDto })
|
||||||
required: true,
|
|
||||||
schema: {
|
|
||||||
type: "object",
|
|
||||||
properties: {
|
|
||||||
files: {
|
|
||||||
type: "array",
|
|
||||||
items: {
|
|
||||||
type: "string",
|
|
||||||
format: "binary",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
@Post("multi-file")
|
@Post("multi-file")
|
||||||
async uploadFiles(@UploadedFiles() files: IFile[]) {
|
async uploadFiles(@UploadedFiles() files: IFile[]) {
|
||||||
console.log({ files });
|
console.log({ files });
|
||||||
|
|||||||
Reference in New Issue
Block a user