diff --git a/backend/src/admin/admin.controller.ts b/backend/src/admin/admin.controller.ts new file mode 100644 index 0000000..73db7fc --- /dev/null +++ b/backend/src/admin/admin.controller.ts @@ -0,0 +1,17 @@ +import { Controller, Get, UseGuards } from "@nestjs/common"; +import { AuthGuard } from "../auth/guards/auth.guard"; +import { RolesGuard } from "../auth/guards/roles.guard"; +import { Roles } from "../auth/decorators/roles.decorator"; +import { AdminService } from "./admin.service"; + +@Controller("admin") +@UseGuards(AuthGuard, RolesGuard) +@Roles("admin") +export class AdminController { + constructor(private readonly adminService: AdminService) {} + + @Get("stats") + getStats() { + return this.adminService.getStats(); + } +} diff --git a/backend/src/admin/admin.module.ts b/backend/src/admin/admin.module.ts new file mode 100644 index 0000000..3e684a0 --- /dev/null +++ b/backend/src/admin/admin.module.ts @@ -0,0 +1,14 @@ +import { Module } from "@nestjs/common"; +import { AuthModule } from "../auth/auth.module"; +import { UsersModule } from "../users/users.module"; +import { ContentsModule } from "../contents/contents.module"; +import { CategoriesModule } from "../categories/categories.module"; +import { AdminController } from "./admin.controller"; +import { AdminService } from "./admin.service"; + +@Module({ + imports: [AuthModule, UsersModule, ContentsModule, CategoriesModule], + controllers: [AdminController], + providers: [AdminService], +}) +export class AdminModule {} diff --git a/backend/src/admin/admin.service.ts b/backend/src/admin/admin.service.ts new file mode 100644 index 0000000..7fce6c5 --- /dev/null +++ b/backend/src/admin/admin.service.ts @@ -0,0 +1,27 @@ +import { Injectable } from "@nestjs/common"; +import { UsersRepository } from "../users/repositories/users.repository"; +import { ContentsRepository } from "../contents/repositories/contents.repository"; +import { CategoriesRepository } from "../categories/repositories/categories.repository"; + +@Injectable() +export class AdminService { + constructor( + private readonly usersRepository: UsersRepository, + private readonly contentsRepository: ContentsRepository, + private readonly categoriesRepository: CategoriesRepository, + ) {} + + async getStats() { + const [userCount, contentCount, categoryCount] = await Promise.all([ + this.usersRepository.countAll(), + this.contentsRepository.count({}), + this.categoriesRepository.countAll(), + ]); + + return { + users: userCount, + contents: contentCount, + categories: categoryCount, + }; + } +} diff --git a/frontend/src/services/admin.service.ts b/frontend/src/services/admin.service.ts new file mode 100644 index 0000000..7ffa5cf --- /dev/null +++ b/frontend/src/services/admin.service.ts @@ -0,0 +1,14 @@ +import { api } from "./api"; + +export interface AdminStats { + users: number; + contents: number; + categories: number; +} + +export const adminService = { + getStats: async (): Promise => { + const response = await api.get("/admin/stats"); + return response.data; + }, +};