wip
This commit is contained in:
@@ -1,12 +1,17 @@
|
||||
import { BadRequestException, Body, Controller, Get, NotFoundException, Param, ParseIntPipe, Post, Put } from '@nestjs/common';
|
||||
import { BadRequestException, Body, Controller, Get, NotFoundException, Param, ParseIntPipe, Post, Put, UploadedFile, UseInterceptors } from '@nestjs/common';
|
||||
import { RegisterDto } from './dto/register.dto';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import { PrismaService } from './services/prisma.service';
|
||||
import { FileInterceptor } from '@nestjs/platform-express';
|
||||
import { diskStorage } from 'multer';
|
||||
import { extname } from 'path';
|
||||
import { AppGetaway } from './app.getaway';
|
||||
|
||||
@ApiTags('App')
|
||||
@Controller('app')
|
||||
export class AppController {
|
||||
constructor(private prisma: PrismaService) { }
|
||||
constructor(private prisma: PrismaService, private socketService: AppGetaway) { }
|
||||
|
||||
|
||||
@Get('candidates')
|
||||
getCandidateList() {
|
||||
@@ -14,30 +19,80 @@ export class AppController {
|
||||
select: {
|
||||
id: true,
|
||||
fullName: true,
|
||||
image: true,
|
||||
age: true,
|
||||
cityOrRegion: true,
|
||||
profileImage: true,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@Get('candidate/:id')
|
||||
getCandidateDetails(@Param('id', ParseIntPipe) id: number) {
|
||||
return this.prisma.candidate.findFirst({where: {id : id}});
|
||||
return this.prisma.candidate.findFirst({ where: { id: id } });
|
||||
}
|
||||
|
||||
@Post('register')
|
||||
register(@Body() dto: RegisterDto) {
|
||||
return this.prisma.candidate.create({ data: { ...dto, createdAt: new Date() } });
|
||||
@UseInterceptors(FileInterceptor('profileImage', {
|
||||
storage: diskStorage({
|
||||
destination: 'assets/uploads',
|
||||
filename: (req, file, cb) => {
|
||||
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9);
|
||||
const ext = extname(file.originalname);
|
||||
cb(null, `${file.fieldname}-${uniqueSuffix}${ext}`);
|
||||
}
|
||||
})
|
||||
}))
|
||||
async register(
|
||||
@UploadedFile() file: Express.Multer.File,
|
||||
@Body() dto: RegisterDto
|
||||
) {
|
||||
const imagePath = file ? file.filename : null;
|
||||
const savedCandidate = await this.prisma.candidate.create({
|
||||
data: {
|
||||
...dto,
|
||||
profileImage: imagePath,
|
||||
createdAt: new Date(),
|
||||
},
|
||||
});
|
||||
this.socketService.onAddCandidate(savedCandidate);
|
||||
|
||||
return savedCandidate;
|
||||
}
|
||||
|
||||
@Put('candidate/:id')
|
||||
async update(@Param('id', ParseIntPipe) id: number, @Body() dto: RegisterDto) {
|
||||
const candidate = await this.prisma.candidate.findFirst({ where: { id: id } });
|
||||
if (!candidate) throw new NotFoundException(`candidate with id ${id} not found`);
|
||||
@UseInterceptors(FileInterceptor('profileImage', {
|
||||
storage: diskStorage({
|
||||
destination: 'assets/uploads',
|
||||
filename: (req, file, cb) => {
|
||||
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9);
|
||||
const ext = extname(file.originalname);
|
||||
cb(null, `${file.fieldname}-${uniqueSuffix}${ext}`);
|
||||
}
|
||||
})
|
||||
}))
|
||||
async update(
|
||||
@Param('id', ParseIntPipe) id: number,
|
||||
@UploadedFile() file: Express.Multer.File,
|
||||
@Body() dto: RegisterDto
|
||||
) {
|
||||
const candidate = await this.prisma.candidate.findFirst({ where: { id } });
|
||||
if (!candidate) throw new NotFoundException(`Candidate with id ${id} not found`);
|
||||
|
||||
const dayMilliseconds = 86400000;
|
||||
const expirationDate = new Date(candidate.createdAt.valueOf() + 3 * dayMilliseconds);
|
||||
if (expirationDate < new Date()) throw new BadRequestException(`can not edit candidate form after 3 days`);
|
||||
await this.prisma.candidate.update({ where: { id: id }, data: { id, ...dto } });
|
||||
if (expirationDate < new Date()) throw new BadRequestException(`Cannot edit candidate form after 3 days`);
|
||||
|
||||
const profileImagePath = file ? file.filename : candidate.profileImage;
|
||||
|
||||
const updatedCandidate = await this.prisma.candidate.update({
|
||||
where: { id },
|
||||
data: {
|
||||
...dto,
|
||||
profileImage: profileImagePath,
|
||||
},
|
||||
});
|
||||
this.socketService.onUpdateCandidate(updatedCandidate);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
26
src/app.getaway.ts
Normal file
26
src/app.getaway.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { MessageBody, OnGatewayConnection, OnGatewayDisconnect, SubscribeMessage, WebSocketGateway, WebSocketServer } from "@nestjs/websockets";
|
||||
import { Server, Socket } from "socket.io";
|
||||
|
||||
@WebSocketGateway({
|
||||
cors: true
|
||||
})
|
||||
|
||||
export class AppGetaway implements OnGatewayDisconnect, OnGatewayConnection {
|
||||
@WebSocketServer() server: Server
|
||||
|
||||
handleDisconnect(client: Socket) {
|
||||
console.log(`${client.id} disconnected`)
|
||||
}
|
||||
|
||||
handleConnection(client: Socket, ...args: any[]) {
|
||||
console.log(`${client.id} connected`)
|
||||
}
|
||||
|
||||
onAddCandidate(registrationData: any) {
|
||||
this.server.emit('candidateRegistered', registrationData);
|
||||
}
|
||||
|
||||
onUpdateCandidate(updatedData: any) {
|
||||
this.server.emit('candidateUpdated', updatedData);
|
||||
}
|
||||
}
|
||||
@@ -3,14 +3,21 @@ import { AppController } from './app.controller';
|
||||
import { ServeStaticModule } from '@nestjs/serve-static';
|
||||
import { join } from 'path';
|
||||
import { PrismaService } from './services/prisma.service';
|
||||
import { AppGetaway } from './app.getaway';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
ServeStaticModule.forRoot({
|
||||
rootPath: join(__dirname, 'client'),
|
||||
}),
|
||||
ServeStaticModule.forRoot(
|
||||
{
|
||||
rootPath: join(__dirname, 'assets/client'),
|
||||
renderPath: '/'
|
||||
},
|
||||
{
|
||||
rootPath: join(__dirname, 'assets/uploads'),
|
||||
serveRoot: '/uploads',
|
||||
}),
|
||||
],
|
||||
controllers: [AppController],
|
||||
providers: [PrismaService],
|
||||
providers: [PrismaService, AppGetaway],
|
||||
})
|
||||
export class AppModule { }
|
||||
|
||||
@@ -1,22 +1,27 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { IsInt } from 'class-validator';
|
||||
import { IsInt, IsOptional, IsString } from 'class-validator';
|
||||
|
||||
export class RegisterDto {
|
||||
@ApiProperty({ required: true })
|
||||
@IsString()
|
||||
fullName: string;
|
||||
@ApiProperty({ required: true })
|
||||
@IsString()
|
||||
email: string;
|
||||
@ApiProperty({ required: true })
|
||||
@IsString()
|
||||
phoneNumber: string;
|
||||
@ApiProperty({ required: true })
|
||||
@IsInt()
|
||||
age: number;
|
||||
@ApiProperty({ required: true })
|
||||
@IsString()
|
||||
cityOrRegion: string;
|
||||
@ApiProperty({ required: false })
|
||||
hobbies: string;
|
||||
@ApiProperty({ required: false })
|
||||
text: string;
|
||||
@ApiProperty({ required: false })
|
||||
image: string;
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
hobbies?: string;
|
||||
@ApiProperty({ required: true })
|
||||
@IsString()
|
||||
justification: string;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ async function bootstrap() {
|
||||
);
|
||||
setupSwagger(app);
|
||||
app.enableCors({
|
||||
origin: true,
|
||||
origin: [true],
|
||||
methods: [
|
||||
'GET',
|
||||
'HEAD',
|
||||
|
||||
Reference in New Issue
Block a user