From ea7160c1de95dce2a9a01ae342408795e2a68cb0 Mon Sep 17 00:00:00 2001 From: morteza-mortezai Date: Tue, 16 Dec 2025 16:31:53 +0330 Subject: [PATCH] update dmenu module --- src/app.module.ts | 4 +- src/configs/icons.config.ts | 4 +- .../{icons => dmenu}/DTO/create-group.dto.ts | 0 .../{icons => dmenu}/DTO/create-icon.dto.ts | 0 .../{icons => dmenu}/DTO/update-group.dto.ts | 0 .../{icons => dmenu}/DTO/update-icon.dto.ts | 0 src/modules/dmenu/constants/index.ts | 1 + .../dmenu.controller.ts} | 98 ++++++++++--------- src/modules/dmenu/dmenu.module.ts | 22 +++++ .../dmenu/providers/contact.service.ts | 60 ++++++++++++ .../providers/icons.service.ts | 6 +- src/modules/icons/constants/index.ts | 2 - src/modules/icons/icons.module.ts | 21 ---- src/modules/users/enums/permission.enum.ts | 4 +- 14 files changed, 146 insertions(+), 76 deletions(-) rename src/modules/{icons => dmenu}/DTO/create-group.dto.ts (100%) rename src/modules/{icons => dmenu}/DTO/create-icon.dto.ts (100%) rename src/modules/{icons => dmenu}/DTO/update-group.dto.ts (100%) rename src/modules/{icons => dmenu}/DTO/update-icon.dto.ts (100%) create mode 100644 src/modules/dmenu/constants/index.ts rename src/modules/{icons/icons.controller.ts => dmenu/dmenu.controller.ts} (71%) create mode 100644 src/modules/dmenu/dmenu.module.ts create mode 100644 src/modules/dmenu/providers/contact.service.ts rename src/modules/{icons => dmenu}/providers/icons.service.ts (97%) delete mode 100644 src/modules/icons/constants/index.ts delete mode 100644 src/modules/icons/icons.module.ts diff --git a/src/app.module.ts b/src/app.module.ts index f8aaf4c..5c81400 100755 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -28,7 +28,7 @@ import { DanakServicesModule } from "./modules/danak-services/danak-services.mod import { DashboardModule } from "./modules/dashboards/dashboard.module"; import { DiscountsModule } from "./modules/discounts/discounts.module"; import { InvoicesModule } from "./modules/invoices/invoices.module"; -import { IconsModule } from "./modules/icons/icons.module"; +import { DmenuModule } from "./modules/dmenu/dmenu.module"; import { LandingModule } from "./modules/landing/landing.module"; import { LearningModule } from "./modules/learnings/learning.module"; import { LoggerModule } from "./modules/logger/logger.module"; @@ -86,7 +86,7 @@ import { WalletsModule } from "./modules/wallets/wallets.module"; DiscountsModule, SupportPlansModule, AccessLogsModule, - IconsModule, + DmenuModule, ], controllers: [], }) diff --git a/src/configs/icons.config.ts b/src/configs/icons.config.ts index f81918b..09c1798 100644 --- a/src/configs/icons.config.ts +++ b/src/configs/icons.config.ts @@ -1,6 +1,6 @@ import { ConfigService } from "@nestjs/config"; -export function iconsConfig() { +export function dmenuConfig() { return { inject: [ConfigService], useFactory: async (configService: ConfigService) => { @@ -13,7 +13,7 @@ export function iconsConfig() { }; } -export interface IIconsConfig { +export interface IDmenuConfig { baseUrl: string; username: string; password: string; diff --git a/src/modules/icons/DTO/create-group.dto.ts b/src/modules/dmenu/DTO/create-group.dto.ts similarity index 100% rename from src/modules/icons/DTO/create-group.dto.ts rename to src/modules/dmenu/DTO/create-group.dto.ts diff --git a/src/modules/icons/DTO/create-icon.dto.ts b/src/modules/dmenu/DTO/create-icon.dto.ts similarity index 100% rename from src/modules/icons/DTO/create-icon.dto.ts rename to src/modules/dmenu/DTO/create-icon.dto.ts diff --git a/src/modules/icons/DTO/update-group.dto.ts b/src/modules/dmenu/DTO/update-group.dto.ts similarity index 100% rename from src/modules/icons/DTO/update-group.dto.ts rename to src/modules/dmenu/DTO/update-group.dto.ts diff --git a/src/modules/icons/DTO/update-icon.dto.ts b/src/modules/dmenu/DTO/update-icon.dto.ts similarity index 100% rename from src/modules/icons/DTO/update-icon.dto.ts rename to src/modules/dmenu/DTO/update-icon.dto.ts diff --git a/src/modules/dmenu/constants/index.ts b/src/modules/dmenu/constants/index.ts new file mode 100644 index 0000000..819d17e --- /dev/null +++ b/src/modules/dmenu/constants/index.ts @@ -0,0 +1 @@ +export const DMENU_CONFIG = "ICONS_CONFIG"; diff --git a/src/modules/icons/icons.controller.ts b/src/modules/dmenu/dmenu.controller.ts similarity index 71% rename from src/modules/icons/icons.controller.ts rename to src/modules/dmenu/dmenu.controller.ts index 32dec84..42b510c 100644 --- a/src/modules/icons/icons.controller.ts +++ b/src/modules/dmenu/dmenu.controller.ts @@ -1,92 +1,102 @@ import { Body, Controller, Delete, Get, Param, Patch, Post } from "@nestjs/common"; -import { ApiBearerAuth, ApiBody, ApiOperation, ApiParam, ApiTags } from "@nestjs/swagger"; +import { ApiBearerAuth, ApiOperation, ApiParam, ApiTags } from "@nestjs/swagger"; -import { CreateGroupDto } from "./DTO/create-group.dto"; -import { CreateIconDto } from "./DTO/create-icon.dto"; -import { UpdateGroupDto } from "./DTO/update-group.dto"; -import { UpdateIconDto } from "./DTO/update-icon.dto"; +import { ContactService } from "./providers/contact.service"; import { IconsService } from "./providers/icons.service"; +import { CreateIconDto } from "./DTO/create-icon.dto"; +import { UpdateIconDto } from "./DTO/update-icon.dto"; +import { CreateGroupDto } from "./DTO/create-group.dto"; +import { UpdateGroupDto } from "./DTO/update-group.dto"; import { AuthGuards } from "../../common/decorators/auth-guard.decorator"; import { PermissionsDec } from "../../common/decorators/permission.decorator"; import { PermissionEnum } from "../users/enums/permission.enum"; -@ApiTags("icons") -@Controller("admin/icons") +@ApiTags("d-menu") +@Controller("admin/dmenu") @AuthGuards() -@PermissionsDec(PermissionEnum.ICONS) +@PermissionsDec(PermissionEnum.DMENU) @ApiBearerAuth() -export class IconsController { - constructor(private readonly iconsService: IconsService) {} +export class DmenuController { + constructor( + private readonly iconsService: IconsService, + private readonly contactService: ContactService, + + ) {} // Icon endpoints - @Post() + @Post('icons') @ApiOperation({ summary: "Create icon" }) - @ApiBody({ type: CreateIconDto }) createIcon(@Body() dto: CreateIconDto) { return this.iconsService.createIcon(dto); } - @Get() + @Get('icons') @ApiOperation({ summary: "Get all icons" }) findAllIcons() { return this.iconsService.findAllIcons(); } - - @Get(":id") - @ApiOperation({ summary: "Get icon by id" }) - @ApiParam({ name: "id", required: true, type: String }) - findOneIcon(@Param("id") id: string) { - return this.iconsService.findOneIcon(id); - } - - @Patch(":id") - @ApiOperation({ summary: "Update icon" }) - @ApiParam({ name: "id" }) - @ApiBody({ type: UpdateIconDto }) - updateIcon(@Param("id") id: string, @Body() dto: UpdateIconDto) { - return this.iconsService.updateIcon(id, dto); - } - - @Delete(":id") - @ApiOperation({ summary: "Delete icon" }) - @ApiParam({ name: "id" }) - removeIcon(@Param("id") id: string) { - return this.iconsService.removeIcon(id); - } - - // Group endpoints (must come before :id routes to avoid route conflicts) - @Post("groups") + // Group endpoints: place BEFORE `icons/:id` routes to avoid route conflicts + @Post("icons/groups") @ApiOperation({ summary: "Create icon group" }) - @ApiBody({ type: CreateGroupDto }) createGroup(@Body() dto: CreateGroupDto) { return this.iconsService.createGroup(dto); } - @Get("groups") + @Get("icons/groups") @ApiOperation({ summary: "Get all icon groups" }) findAllGroups() { return this.iconsService.findAllGroups(); } - @Get("groups/:id") + @Get("icons/groups/:id") @ApiOperation({ summary: "Get icon group by id" }) @ApiParam({ name: "id", required: true, type: String }) findOneGroup(@Param("id") id: string) { return this.iconsService.findOneGroup(id); } - @Patch("groups/:id") + @Patch("icons/groups/:id") @ApiOperation({ summary: "Update icon group" }) @ApiParam({ name: "id" }) - @ApiBody({ type: UpdateGroupDto }) updateGroup(@Param("id") id: string, @Body() dto: UpdateGroupDto) { return this.iconsService.updateGroup(id, dto); } - @Delete("groups/:id") + @Delete("icons/groups/:id") @ApiOperation({ summary: "Delete icon group" }) @ApiParam({ name: "id" }) removeGroup(@Param("id") id: string) { return this.iconsService.removeGroup(id); } + + @Get("icons/:id") + @ApiOperation({ summary: "Get icon by id" }) + @ApiParam({ name: "id", required: true, type: String }) + findOneIcon(@Param("id") id: string) { + return this.iconsService.findOneIcon(id); + } + + @Patch("icons/:id") + @ApiOperation({ summary: "Update icon" }) + @ApiParam({ name: "id" }) + updateIcon(@Param("id") id: string, @Body() dto: UpdateIconDto) { + return this.iconsService.updateIcon(id, dto); + } + + @Delete("icons/:id") + @ApiOperation({ summary: "Delete icon" }) + @ApiParam({ name: "id" }) + removeIcon(@Param("id") id: string) { + return this.iconsService.removeIcon(id); + } + // contacts + @Get('contacts') + findAll() { + return this.contactService.findAll(); + } + + @Get("contacts/:id") + findOne(@Param("id") id: string) { + return this.contactService.findOne(+id); + } } diff --git a/src/modules/dmenu/dmenu.module.ts b/src/modules/dmenu/dmenu.module.ts new file mode 100644 index 0000000..b57ccd8 --- /dev/null +++ b/src/modules/dmenu/dmenu.module.ts @@ -0,0 +1,22 @@ +import { Module } from "@nestjs/common"; + +import { DMENU_CONFIG } from "./constants"; +import { DmenuController } from "./dmenu.controller"; +import { ContactService } from "./providers/contact.service"; +import { IconsService } from "./providers/icons.service"; +import { dmenuConfig } from "../../configs/icons.config"; + +@Module({ + imports: [], + controllers: [DmenuController], + providers: [ + IconsService, + ContactService, + { + provide: DMENU_CONFIG, + useFactory: dmenuConfig().useFactory, + inject: dmenuConfig().inject, + }, + ], + }) +export class DmenuModule {} diff --git a/src/modules/dmenu/providers/contact.service.ts b/src/modules/dmenu/providers/contact.service.ts new file mode 100644 index 0000000..1af1fa3 --- /dev/null +++ b/src/modules/dmenu/providers/contact.service.ts @@ -0,0 +1,60 @@ +import { HttpService } from "@nestjs/axios"; +import { Injectable, Logger } from "@nestjs/common"; +import { Inject } from "@nestjs/common"; +import { AxiosError } from "axios"; +import { catchError, firstValueFrom, throwError } from "rxjs"; + +import { IDmenuConfig } from "../../../configs/icons.config"; +import { DMENU_CONFIG } from "../constants"; + +@Injectable() +export class ContactService { + private readonly logger = new Logger(ContactService.name); + + constructor( + @Inject(DMENU_CONFIG) private readonly config: IDmenuConfig, + private readonly httpService: HttpService, + ) {} + + private getHeaders(): Record { + const credentials = Buffer.from(`${this.config.username}:${this.config.password}`).toString("base64"); + return { + "Content-Type": "application/json", + Authorization: `Basic ${credentials}`, + }; + } + + async findAll() { + try { + const { data } = await firstValueFrom( + this.httpService.get(`${this.config.baseUrl}/super-admin/contacts`, { headers: this.getHeaders() }).pipe( + catchError((err: AxiosError) => { + this.logger.error(`Failed to fetch contacts: ${err.message}`, err.stack); + return throwError(() => err); + }), + ), + ); + return data; + } catch (error: unknown) { + this.logger.error(`Error fetching contacts: ${error instanceof Error ? error.message : "Unknown error"}`); + throw error; + } + } + + async findOne(id: number) { + try { + const { data } = await firstValueFrom( + this.httpService.get(`${this.config.baseUrl}/super-admin/contacts/${id}`, { headers: this.getHeaders() }).pipe( + catchError((err: AxiosError) => { + this.logger.error(`Failed to fetch contact: ${err.message}`, err.stack); + return throwError(() => err); + }), + ), + ); + return data; + } catch (error: unknown) { + this.logger.error(`Error fetching contact: ${error instanceof Error ? error.message : "Unknown error"}`); + throw error; + } + } +} diff --git a/src/modules/icons/providers/icons.service.ts b/src/modules/dmenu/providers/icons.service.ts similarity index 97% rename from src/modules/icons/providers/icons.service.ts rename to src/modules/dmenu/providers/icons.service.ts index 6d3a2ef..2cf4d18 100644 --- a/src/modules/icons/providers/icons.service.ts +++ b/src/modules/dmenu/providers/icons.service.ts @@ -3,8 +3,8 @@ import { Inject, Injectable, Logger } from "@nestjs/common"; import { AxiosError } from "axios"; import { catchError, firstValueFrom, throwError } from "rxjs"; -import { IIconsConfig } from "../../../configs/icons.config"; -import { ICONS_CONFIG } from "../constants"; +import { IDmenuConfig } from "../../../configs/icons.config"; +import { DMENU_CONFIG } from "../constants"; import { CreateGroupDto } from "../DTO/create-group.dto"; import { CreateIconDto } from "../DTO/create-icon.dto"; import { UpdateGroupDto } from "../DTO/update-group.dto"; @@ -15,7 +15,7 @@ export class IconsService { private readonly logger = new Logger(IconsService.name); constructor( - @Inject(ICONS_CONFIG) private readonly config: IIconsConfig, + @Inject(DMENU_CONFIG) private readonly config: IDmenuConfig, private readonly httpService: HttpService, ) {} diff --git a/src/modules/icons/constants/index.ts b/src/modules/icons/constants/index.ts deleted file mode 100644 index 26e9f90..0000000 --- a/src/modules/icons/constants/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const ICONS_CONFIG = "ICONS_CONFIG"; - diff --git a/src/modules/icons/icons.module.ts b/src/modules/icons/icons.module.ts deleted file mode 100644 index a814f88..0000000 --- a/src/modules/icons/icons.module.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Module } from "@nestjs/common"; - -import { ICONS_CONFIG } from "./constants"; -import { IconsController } from "./icons.controller"; -import { IconsService } from "./providers/icons.service"; -import { iconsConfig } from "../../configs/icons.config"; - -@Module({ - imports: [], - controllers: [IconsController], - providers: [ - IconsService, - { - provide: ICONS_CONFIG, - useFactory: iconsConfig().useFactory, - inject: iconsConfig().inject, - }, - ], - exports: [IconsService], -}) -export class IconsModule {} diff --git a/src/modules/users/enums/permission.enum.ts b/src/modules/users/enums/permission.enum.ts index aa4657d..588dc65 100755 --- a/src/modules/users/enums/permission.enum.ts +++ b/src/modules/users/enums/permission.enum.ts @@ -20,5 +20,5 @@ export enum PermissionEnum { PAYMENTS = "payments", MANAGE_SSO_CLIENTS = "manage_sso_clients", SUPPORT_PLAN = "support_plan", - ICONS = "icons", -} + DMENU = "dmenu", + }