Loading backend/src/user/dto/update-user.dto.ts +12 −3 Original line number Diff line number Diff line import { PartialType } from '@nestjs/swagger'; import { CreateUserDto } from './create-user.dto'; import { ApiProperty } from '@nestjs/swagger'; export class UpdateUserDto extends PartialType(CreateUserDto) {} export class UpdateUserDto { @ApiProperty() name: string; @ApiProperty() lastName: string; } export class UpdateImageUserDto { @ApiProperty({ type: 'string', format: 'binary' }) image; } backend/src/user/dto/user-response.ts 0 → 100644 +16 −0 Original line number Diff line number Diff line import { ApiProperty } from '@nestjs/swagger'; export class UserResponse { @ApiProperty() name: string; @ApiProperty() lastName: string; @ApiProperty() imageUrl: string; @ApiProperty() email: string; @ApiProperty() emailConfirmed: boolean; } backend/src/user/entities/user.entity.ts +3 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,9 @@ export class User { @Column() password: string; @Column({ nullable: true }) imageUrl: string; @Column({ default: false }) isEmailConfirmed: boolean; Loading backend/src/user/user.controller.ts +39 −6 Original line number Diff line number Diff line import { Body, Controller, Get, Patch, Query, Req, UseGuards } from '@nestjs/common'; import { Body, Controller, Get, Patch, Query, Req, UseGuards, UseInterceptors } from '@nestjs/common'; import { UserService } from './user.service'; import { UpdatePreferedCategoriesDto } from './dto/update-preferedCategories.dto'; import { CustomUserRequest } from 'src/auth/user/interface/customUserReq'; import { ApiBearerAuth, ApiBody, ApiQuery, ApiTags } from '@nestjs/swagger'; import { ApiBearerAuth, ApiBody, ApiConsumes, ApiQuery, ApiTags } from '@nestjs/swagger'; import { AuthUserGuard } from 'src/auth/user/authUser.guard'; import { LANGUAGES } from 'src/shared/enum/languages.enum'; import { UpdateImageUserDto, UpdateUserDto } from './dto/update-user.dto'; import { fileInterceptor } from 'src/shared/interceptors/file-save.interceptor'; import { CustomAdminRequest } from 'src/auth/admin/interface/customAdminReq'; @Controller('user') @ApiTags('User') Loading Loading @@ -41,14 +44,44 @@ export class UserController { } } @Get('is-verfied') @Patch('info') @ApiBearerAuth('jwt') @ApiBody({ type: UpdateUserDto }) @UseGuards(AuthUserGuard) async isVerified(@Req() req: CustomUserRequest) { async updateInfo(@Body() updateUserDto: UpdateUserDto, @Req() req: CustomUserRequest) { try { const { email } = req.user; const isVerified = await this.userService.isVerified(email); return { isVerified }; await this.userService.updateInfo(email, updateUserDto); return { message: 'User info updated successfully' }; } catch (error) { throw error; } } @Patch('photo') @ApiBearerAuth('jwt') @UseGuards(AuthUserGuard) @ApiConsumes('multipart/form-data') @ApiBody({ type: UpdateImageUserDto }) @UseInterceptors(fileInterceptor('image', 'static/user/', ['.jpg', '.jpeg', '.png'])) async updatePhoto(@Req() reqImg: CustomAdminRequest, @Req() req: CustomUserRequest) { try { const { email } = req.user; const image = reqImg.file.filename; await this.userService.updatePhoto(email, image); return { message: 'User photo updated successfully' }; } catch (error) { throw error; } } @Get('info') @ApiBearerAuth('jwt') @UseGuards(AuthUserGuard) async getInfo(@Req() req: CustomUserRequest) { try { const { email } = req.user; return await this.userService.getUserInfo(email); } catch (error) { throw error; } Loading backend/src/user/user.service.ts +30 −3 Original line number Diff line number Diff line Loading @@ -6,6 +6,9 @@ import { CreateUserDto } from './dto/create-user.dto'; import { Category } from 'src/category/entities/category.entity'; import { CategoryService } from 'src/category/category.service'; import { LANGUAGES } from 'src/shared/enum/languages.enum'; import { UpdateUserDto } from './dto/update-user.dto'; import { UserResponse } from './dto/user-response'; import { ServerConstants } from 'src/constants/server.contants'; @Injectable() /** Loading Loading @@ -77,12 +80,36 @@ export class UserService { } } async isVerified(email: string): Promise<boolean> { async updateInfo(email: string, updateUserDto: UpdateUserDto) { try { await this.userRepository.update({ email }, updateUserDto); } catch (error) { throw new BadRequestException('Error updating user info'); } } async updatePhoto(email: string, photo: string) { try { await this.userRepository.update({ email }, { imageUrl: photo }); } catch (error) { throw new BadRequestException('Error updating user photo'); } } async getUserInfo(email: string) { try { const user = await this.userRepository.findOneBy({ email }); return user.isEmailConfirmed; user.imageUrl = `${ServerConstants.HOST}/user/${user.imageUrl}`; const res: UserResponse = { imageUrl: user.imageUrl, lastName: user.lastName, email: user.email, name: user.name, emailConfirmed: user.isEmailConfirmed, }; return res; } catch (error) { throw new BadRequestException('Error getting email verification status'); throw new BadRequestException('Error getting user info'); } } } Loading
backend/src/user/dto/update-user.dto.ts +12 −3 Original line number Diff line number Diff line import { PartialType } from '@nestjs/swagger'; import { CreateUserDto } from './create-user.dto'; import { ApiProperty } from '@nestjs/swagger'; export class UpdateUserDto extends PartialType(CreateUserDto) {} export class UpdateUserDto { @ApiProperty() name: string; @ApiProperty() lastName: string; } export class UpdateImageUserDto { @ApiProperty({ type: 'string', format: 'binary' }) image; }
backend/src/user/dto/user-response.ts 0 → 100644 +16 −0 Original line number Diff line number Diff line import { ApiProperty } from '@nestjs/swagger'; export class UserResponse { @ApiProperty() name: string; @ApiProperty() lastName: string; @ApiProperty() imageUrl: string; @ApiProperty() email: string; @ApiProperty() emailConfirmed: boolean; }
backend/src/user/entities/user.entity.ts +3 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,9 @@ export class User { @Column() password: string; @Column({ nullable: true }) imageUrl: string; @Column({ default: false }) isEmailConfirmed: boolean; Loading
backend/src/user/user.controller.ts +39 −6 Original line number Diff line number Diff line import { Body, Controller, Get, Patch, Query, Req, UseGuards } from '@nestjs/common'; import { Body, Controller, Get, Patch, Query, Req, UseGuards, UseInterceptors } from '@nestjs/common'; import { UserService } from './user.service'; import { UpdatePreferedCategoriesDto } from './dto/update-preferedCategories.dto'; import { CustomUserRequest } from 'src/auth/user/interface/customUserReq'; import { ApiBearerAuth, ApiBody, ApiQuery, ApiTags } from '@nestjs/swagger'; import { ApiBearerAuth, ApiBody, ApiConsumes, ApiQuery, ApiTags } from '@nestjs/swagger'; import { AuthUserGuard } from 'src/auth/user/authUser.guard'; import { LANGUAGES } from 'src/shared/enum/languages.enum'; import { UpdateImageUserDto, UpdateUserDto } from './dto/update-user.dto'; import { fileInterceptor } from 'src/shared/interceptors/file-save.interceptor'; import { CustomAdminRequest } from 'src/auth/admin/interface/customAdminReq'; @Controller('user') @ApiTags('User') Loading Loading @@ -41,14 +44,44 @@ export class UserController { } } @Get('is-verfied') @Patch('info') @ApiBearerAuth('jwt') @ApiBody({ type: UpdateUserDto }) @UseGuards(AuthUserGuard) async isVerified(@Req() req: CustomUserRequest) { async updateInfo(@Body() updateUserDto: UpdateUserDto, @Req() req: CustomUserRequest) { try { const { email } = req.user; const isVerified = await this.userService.isVerified(email); return { isVerified }; await this.userService.updateInfo(email, updateUserDto); return { message: 'User info updated successfully' }; } catch (error) { throw error; } } @Patch('photo') @ApiBearerAuth('jwt') @UseGuards(AuthUserGuard) @ApiConsumes('multipart/form-data') @ApiBody({ type: UpdateImageUserDto }) @UseInterceptors(fileInterceptor('image', 'static/user/', ['.jpg', '.jpeg', '.png'])) async updatePhoto(@Req() reqImg: CustomAdminRequest, @Req() req: CustomUserRequest) { try { const { email } = req.user; const image = reqImg.file.filename; await this.userService.updatePhoto(email, image); return { message: 'User photo updated successfully' }; } catch (error) { throw error; } } @Get('info') @ApiBearerAuth('jwt') @UseGuards(AuthUserGuard) async getInfo(@Req() req: CustomUserRequest) { try { const { email } = req.user; return await this.userService.getUserInfo(email); } catch (error) { throw error; } Loading
backend/src/user/user.service.ts +30 −3 Original line number Diff line number Diff line Loading @@ -6,6 +6,9 @@ import { CreateUserDto } from './dto/create-user.dto'; import { Category } from 'src/category/entities/category.entity'; import { CategoryService } from 'src/category/category.service'; import { LANGUAGES } from 'src/shared/enum/languages.enum'; import { UpdateUserDto } from './dto/update-user.dto'; import { UserResponse } from './dto/user-response'; import { ServerConstants } from 'src/constants/server.contants'; @Injectable() /** Loading Loading @@ -77,12 +80,36 @@ export class UserService { } } async isVerified(email: string): Promise<boolean> { async updateInfo(email: string, updateUserDto: UpdateUserDto) { try { await this.userRepository.update({ email }, updateUserDto); } catch (error) { throw new BadRequestException('Error updating user info'); } } async updatePhoto(email: string, photo: string) { try { await this.userRepository.update({ email }, { imageUrl: photo }); } catch (error) { throw new BadRequestException('Error updating user photo'); } } async getUserInfo(email: string) { try { const user = await this.userRepository.findOneBy({ email }); return user.isEmailConfirmed; user.imageUrl = `${ServerConstants.HOST}/user/${user.imageUrl}`; const res: UserResponse = { imageUrl: user.imageUrl, lastName: user.lastName, email: user.email, name: user.name, emailConfirmed: user.isEmailConfirmed, }; return res; } catch (error) { throw new BadRequestException('Error getting email verification status'); throw new BadRequestException('Error getting user info'); } } }