import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Patch, Post, Query, UseGuards, } from '@nestjs/common'; import { ApiBearerAuth, ApiTags } from '@nestjs/swagger'; import { Roles } from '~/auth/enums'; import { IJwtPayload } from '~/auth/interfaces'; import { AllowedRoles, AuthenticatedUser, Public } from '~/common/decorators'; import { RolesGuard } from '~/common/guards'; import { ApiDataPageResponse, ApiDataResponse, ApiLangRequestHeader } from '~/core/decorators'; import { PageOptionsRequestDto } from '~/core/dtos'; import { CustomParseUUIDPipe } from '~/core/pipes'; import { ResponseFactory } from '~/core/utils'; import { CreateJuniorRequestDto, SetThemeRequestDto, TransferToJuniorRequestDto, UpdateJuniorRequestDto, } from '../dtos/request'; import { JuniorResponseDto, QrCodeValidationResponseDto, ThemeResponseDto, TransferToJuniorResponseDto, } from '../dtos/response'; import { JuniorService } from '../services'; @Controller('juniors') @ApiTags('Juniors') @ApiBearerAuth() @ApiLangRequestHeader() export class JuniorController { constructor(private readonly juniorService: JuniorService) {} @Post() @UseGuards(RolesGuard) @AllowedRoles(Roles.GUARDIAN) @ApiDataResponse(JuniorResponseDto) async createJunior(@Body() body: CreateJuniorRequestDto, @AuthenticatedUser() user: IJwtPayload) { const token = await this.juniorService.createJuniors(body, user.sub); return ResponseFactory.data(token); } @Get() @UseGuards(RolesGuard) @AllowedRoles(Roles.GUARDIAN) @ApiDataPageResponse(JuniorResponseDto) async findJuniors(@AuthenticatedUser() user: IJwtPayload, @Query() pageOptions: PageOptionsRequestDto) { const [juniors, count] = await this.juniorService.findJuniorsByGuardianId(user.sub, pageOptions); return ResponseFactory.dataPage( juniors.map((juniors) => new JuniorResponseDto(juniors)), { page: pageOptions.page, size: pageOptions.size, itemCount: count, }, ); } @Get(':juniorId') @UseGuards(RolesGuard) @AllowedRoles(Roles.GUARDIAN) @ApiDataResponse(JuniorResponseDto) async findJuniorById( @AuthenticatedUser() user: IJwtPayload, @Param('juniorId', CustomParseUUIDPipe) juniorId: string, ) { const junior = await this.juniorService.findJuniorById(juniorId, false, user.sub); return ResponseFactory.data(new JuniorResponseDto(junior)); } @Patch(':juniorId') @UseGuards(RolesGuard) @AllowedRoles(Roles.GUARDIAN) @ApiDataResponse(JuniorResponseDto) async updateJunior( @AuthenticatedUser() user: IJwtPayload, @Param('juniorId', CustomParseUUIDPipe) juniorId: string, @Body() body: UpdateJuniorRequestDto, ) { const junior = await this.juniorService.updateJunior(juniorId, body, user.sub); return ResponseFactory.data(new JuniorResponseDto(junior)); } @Delete(':juniorId') @UseGuards(RolesGuard) @AllowedRoles(Roles.GUARDIAN) @HttpCode(HttpStatus.NO_CONTENT) async deleteJunior(@AuthenticatedUser() user: IJwtPayload, @Param('juniorId', CustomParseUUIDPipe) juniorId: string) { await this.juniorService.deleteJunior(juniorId, user.sub); } @Post('set-theme') @UseGuards(RolesGuard) @AllowedRoles(Roles.JUNIOR) @ApiDataResponse(JuniorResponseDto) async setTheme(@Body() body: SetThemeRequestDto, @AuthenticatedUser() user: IJwtPayload) { const theme = await this.juniorService.setTheme(body, user.sub); return ResponseFactory.data(new ThemeResponseDto(theme)); } @Get(':juniorId/qr-code') @UseGuards(RolesGuard) @AllowedRoles(Roles.GUARDIAN) @ApiDataResponse('string') async generateQrCode(@Param('juniorId', CustomParseUUIDPipe) juniorId: string) { const qrCode = await this.juniorService.generateToken(juniorId); return ResponseFactory.data(qrCode); } @Get('qr-code/:token/validate') @Public() @ApiDataResponse(QrCodeValidationResponseDto) async validateToken(@Param('token') token: string) { const junior = await this.juniorService.validateToken(token); return ResponseFactory.data(new QrCodeValidationResponseDto(junior)); } @Post(':juniorId/transfer') @UseGuards(RolesGuard) @AllowedRoles(Roles.GUARDIAN) @ApiDataResponse(TransferToJuniorResponseDto) async transferToJunior( @AuthenticatedUser() user: IJwtPayload, @Param('juniorId', CustomParseUUIDPipe) juniorId: string, @Body() body: TransferToJuniorRequestDto, ) { const newAmount = await this.juniorService.transferToJunior(juniorId, body, user.sub); return ResponseFactory.data(new TransferToJuniorResponseDto(newAmount)); } }