diff --git a/backend/src/app.module.ts b/backend/src/app.module.ts index ae25ffd92..2b211ed41 100644 --- a/backend/src/app.module.ts +++ b/backend/src/app.module.ts @@ -4,6 +4,7 @@ import { ConfigModule, ConfigService } from '@nestjs/config'; import { AppController } from './app.controller'; import { AppService } from './app.service'; import { AssetCategoriesModule } from './asset-categories/asset-categories.module'; +import { SettingsModule } from './settings/settings.module'; import { AssetCategory } from './asset-categories/asset-category.entity'; import { DepartmentsModule } from './departments/departments.module'; import { Department } from './departments/department.entity'; diff --git a/backend/src/settings/dto/create-settings.dto.ts b/backend/src/settings/dto/create-settings.dto.ts new file mode 100644 index 000000000..55b81ba2b --- /dev/null +++ b/backend/src/settings/dto/create-settings.dto.ts @@ -0,0 +1,12 @@ +import { IsString } from 'class-validator'; + +export class CreateSettingsDto { + @IsString() + defaultCurrency: string; + + @IsString() + timezone: string; + + @IsString() + depreciationMethod: string; +} diff --git a/backend/src/settings/dto/update-settings.dto.ts b/backend/src/settings/dto/update-settings.dto.ts new file mode 100644 index 000000000..52de23198 --- /dev/null +++ b/backend/src/settings/dto/update-settings.dto.ts @@ -0,0 +1,15 @@ +import { IsOptional, IsString } from 'class-validator'; + +export class UpdateSettingsDto { + @IsOptional() + @IsString() + defaultCurrency?: string; + + @IsOptional() + @IsString() + timezone?: string; + + @IsOptional() + @IsString() + depreciationMethod?: string; +} diff --git a/backend/src/settings/entities/settings.entity.ts b/backend/src/settings/entities/settings.entity.ts new file mode 100644 index 000000000..4d9648a91 --- /dev/null +++ b/backend/src/settings/entities/settings.entity.ts @@ -0,0 +1,6 @@ +export class Settings { + id: string; + defaultCurrency: string; + timezone: string; + depreciationMethod: string; +} diff --git a/backend/src/settings/settings.controller.ts b/backend/src/settings/settings.controller.ts new file mode 100644 index 000000000..f5551f138 --- /dev/null +++ b/backend/src/settings/settings.controller.ts @@ -0,0 +1,34 @@ +import { Controller, Get, Post, Put, Delete, Body, Param } from '@nestjs/common'; +import { SettingsService } from './settings.service'; +import { CreateSettingsDto } from './dto/create-settings.dto'; +import { UpdateSettingsDto } from './dto/update-settings.dto'; + +@Controller('settings') +export class SettingsController { + constructor(private readonly settingsService: SettingsService) {} + + @Get() + findAll() { + return this.settingsService.findAll(); + } + + @Get(':id') + findOne(@Param('id') id: string) { + return this.settingsService.findOne(id); + } + + @Post() + create(@Body() createSettingsDto: CreateSettingsDto) { + return this.settingsService.create(createSettingsDto); + } + + @Put(':id') + update(@Param('id') id: string, @Body() updateSettingsDto: UpdateSettingsDto) { + return this.settingsService.update(id, updateSettingsDto); + } + + @Delete(':id') + remove(@Param('id') id: string) { + return this.settingsService.remove(id); + } +} diff --git a/backend/src/settings/settings.module.ts b/backend/src/settings/settings.module.ts new file mode 100644 index 000000000..63e54df50 --- /dev/null +++ b/backend/src/settings/settings.module.ts @@ -0,0 +1,9 @@ +import { Module } from '@nestjs/common'; +import { SettingsController } from './settings.controller'; +import { SettingsService } from './settings.service'; + +@Module({ + controllers: [SettingsController], + providers: [SettingsService], +}) +export class SettingsModule {} diff --git a/backend/src/settings/settings.service.ts b/backend/src/settings/settings.service.ts new file mode 100644 index 000000000..e21e1c5c0 --- /dev/null +++ b/backend/src/settings/settings.service.ts @@ -0,0 +1,38 @@ +import { Injectable } from '@nestjs/common'; +import { CreateSettingsDto } from './dto/create-settings.dto'; +import { UpdateSettingsDto } from './dto/update-settings.dto'; + +@Injectable() +export class SettingsService { + private settings = []; + + findAll() { + return this.settings; + } + + findOne(id: string) { + return this.settings.find(s => s.id === id); + } + + create(createSettingsDto: CreateSettingsDto) { + const newSetting = { id: Date.now().toString(), ...createSettingsDto }; + this.settings.push(newSetting); + return newSetting; + } + + update(id: string, updateSettingsDto: UpdateSettingsDto) { + const setting = this.findOne(id); + if (setting) { + Object.assign(setting, updateSettingsDto); + } + return setting; + } + + remove(id: string) { + const idx = this.settings.findIndex(s => s.id === id); + if (idx > -1) { + return this.settings.splice(idx, 1); + } + return null; + } +} diff --git a/backend/src/user-profile/dto/update-profile.dto.ts b/backend/src/user-profile/dto/update-profile.dto.ts new file mode 100644 index 000000000..732dedf3d --- /dev/null +++ b/backend/src/user-profile/dto/update-profile.dto.ts @@ -0,0 +1,19 @@ +import { IsOptional, IsString, IsEmail, IsPhoneNumber } from 'class-validator'; + +export class UpdateProfileDto { + @IsOptional() + @IsString() + name?: string; + + @IsOptional() + @IsEmail() + email?: string; + + @IsOptional() + @IsPhoneNumber() + phone?: string; + + @IsOptional() + @IsString() + avatarUrl?: string; +} diff --git a/backend/src/user-profile/entities/user-profile.entity.ts b/backend/src/user-profile/entities/user-profile.entity.ts new file mode 100644 index 000000000..4f28dd19d --- /dev/null +++ b/backend/src/user-profile/entities/user-profile.entity.ts @@ -0,0 +1,7 @@ +export class UserProfile { + id: string; + name: string; + email: string; + phone: string; + avatarUrl: string; +} diff --git a/backend/src/user-profile/user-profile.controller.ts b/backend/src/user-profile/user-profile.controller.ts new file mode 100644 index 000000000..551d3b0fb --- /dev/null +++ b/backend/src/user-profile/user-profile.controller.ts @@ -0,0 +1,26 @@ +import { Controller, Get, Put, Body, UseInterceptors, UploadedFile, Post, Req } from '@nestjs/common'; +import { FileInterceptor } from '@nestjs/platform-express'; +import { UpdateProfileDto } from './dto/update-profile.dto'; +import { UserProfileService } from './user-profile.service'; + +@Controller('profile') +export class UserProfileController { + constructor(private readonly userProfileService: UserProfileService) {} + + @Get() + getProfile(@Req() req) { + // TODO: Get user from request + return this.userProfileService.getProfile(req.user.id); + } + + @Put() + updateProfile(@Req() req, @Body() updateProfileDto: UpdateProfileDto) { + return this.userProfileService.updateProfile(req.user.id, updateProfileDto); + } + + @Post('avatar') + @UseInterceptors(FileInterceptor('file')) + uploadAvatar(@Req() req, @UploadedFile() file: any) { + return this.userProfileService.uploadAvatar(req.user.id, file); + } +} diff --git a/backend/src/user-profile/user-profile.module.ts b/backend/src/user-profile/user-profile.module.ts new file mode 100644 index 000000000..23c3566e5 --- /dev/null +++ b/backend/src/user-profile/user-profile.module.ts @@ -0,0 +1,9 @@ +import { Module } from '@nestjs/common'; +import { UserProfileController } from './user-profile.controller'; +import { UserProfileService } from './user-profile.service'; + +@Module({ + controllers: [UserProfileController], + providers: [UserProfileService], +}) +export class UserProfileModule {} diff --git a/backend/src/user-profile/user-profile.service.ts b/backend/src/user-profile/user-profile.service.ts new file mode 100644 index 000000000..e5fe583ae --- /dev/null +++ b/backend/src/user-profile/user-profile.service.ts @@ -0,0 +1,20 @@ +import { Injectable } from '@nestjs/common'; +import { UpdateProfileDto } from './dto/update-profile.dto'; + +@Injectable() +export class UserProfileService { + async getProfile(userId: string) { + // TODO: Fetch user profile from DB + return {}; + } + + async updateProfile(userId: string, updateProfileDto: UpdateProfileDto) { + // TODO: Update user profile in DB + return {}; + } + + async uploadAvatar(userId: string, file: any) { + // TODO: Save avatar file and update user profile + return {}; + } +}