chore: add is pinned to the blog entity and also add route for it

This commit is contained in:
mahyargdz
2025-04-12 16:28:02 +03:30
parent 39cce1c380
commit d76b9326e6
6 changed files with 53 additions and 2 deletions
+1
View File
@@ -664,4 +664,5 @@ export const enum BlogMessage {
INVALID_DATE = "تاریخ نامعتبر است",
IS_ACTIVE_SHOULD_BE_1_0 = "وضعیت فعال بودن باید یکی از ۱ یا ۰ باشد",
SEARCH_QUERY_STRING = "رشته جستجو باید یک رشته باشد",
IS_PINNED_SHOULD_BE_A_BOOLEAN = "وضعیت سنجاق بودن باید یک بولین باشد",
}
+10 -2
View File
@@ -1,5 +1,5 @@
import { ApiProperty } from "@nestjs/swagger";
import { ArrayMinSize, IsArray, IsBoolean, IsNotEmpty, IsString, IsUUID, MaxLength } from "class-validator";
import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger";
import { ArrayMinSize, IsArray, IsBoolean, IsNotEmpty, IsOptional, IsString, IsUUID, MaxLength } from "class-validator";
import { BlogMessage } from "../../../common/enums/message.enum";
@@ -55,4 +55,12 @@ export class CreateBlogDto {
@IsBoolean({ message: BlogMessage.IS_ACTIVE_SHOULD_BE_A_BOOLEAN })
@ApiProperty({ description: "Is active of the blog", example: true })
isActive: boolean;
@ApiPropertyOptional({
description: "Whether the blog is pinned or not",
default: false,
})
@IsOptional()
@IsBoolean({ message: BlogMessage.IS_PINNED_SHOULD_BE_A_BOOLEAN })
isPinned?: boolean;
}
@@ -61,6 +61,12 @@ export class BlogsController {
return this.blogsService.getMostVisitedBlogs();
}
@ApiOperation({ summary: "Get most pinned blogs" })
@SkipAuth()
@Get("pinned")
getPinnedBlogs() {
return this.blogsService.getPinnedBlogs();
}
@ApiOperation({ summary: "Create a new blog (admin route)" })
@Post()
@AdminRoute()
@@ -37,6 +37,9 @@ export class Blog extends BaseEntity {
@Column({ type: "int", default: 0 })
viewCount: number;
@Column({ type: "boolean", default: false })
isPinned: boolean;
@ManyToOne(() => User, (user) => user.blogs)
author: User;
@@ -262,4 +262,16 @@ export class BlogsService {
const blogs = await this.blogsRepository.getMostVisitedBlogs();
return { blogs };
}
async getPinnedBlogs() {
const blogs = await this.blogsRepository.getPinnedBlogs();
return { blogs };
}
async togglePinnedStatus(id: string) {
const blog = await this.findBlogById(id);
blog.isPinned = !blog.isPinned;
await this.blogsRepository.save(blog);
return { message: CommonMessage.UPDATE_SUCCESS, blog };
}
}
@@ -191,4 +191,25 @@ export class BlogsRepository extends Repository<Blog> {
.take(limit)
.getMany();
}
async getPinnedBlogs(limit: number = 4) {
return this.createQueryBuilder("blog")
.where("blog.deletedAt IS NULL")
.andWhere("blog.isActive = :isActive", { isActive: true })
.andWhere("blog.isPinned = :isPinned", { isPinned: true })
.select([
"blog.id",
"blog.title",
"blog.previewContent",
"blog.metaTitle",
"blog.metaDescription",
"blog.imageUrl",
"blog.slug",
"blog.createdAt",
"blog.viewCount",
])
.orderBy("blog.createdAt", "DESC")
.take(limit)
.getMany();
}
}