fix
This commit is contained in:
@@ -1,4 +1,17 @@
|
||||
import { BadRequestException, Body, Controller, Delete, Get, NotFoundException, Param, ParseIntPipe, Post, Put, UploadedFile, UseInterceptors } from '@nestjs/common';
|
||||
import {
|
||||
BadRequestException,
|
||||
Body,
|
||||
Controller,
|
||||
Delete,
|
||||
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';
|
||||
@@ -11,8 +24,10 @@ import { unlink } from 'fs';
|
||||
@ApiTags('App')
|
||||
@Controller('app')
|
||||
export class AppController {
|
||||
constructor(private prisma: PrismaService, private socketService: AppGetaway) { }
|
||||
|
||||
constructor(
|
||||
private prisma: PrismaService,
|
||||
private socketService: AppGetaway,
|
||||
) {}
|
||||
|
||||
@Get('candidates')
|
||||
async getCandidateList() {
|
||||
@@ -23,12 +38,12 @@ export class AppController {
|
||||
age: true,
|
||||
cityOrRegion: true,
|
||||
profileImage: true,
|
||||
}
|
||||
})
|
||||
},
|
||||
});
|
||||
|
||||
data.forEach((candidate) => {
|
||||
candidate.profileImage = `${process.env.HOST_URL as string}/uploads/${candidate.profileImage}`;
|
||||
})
|
||||
});
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -42,21 +57,23 @@ export class AppController {
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
@Post('register')
|
||||
@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}`);
|
||||
}
|
||||
})
|
||||
}))
|
||||
@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
|
||||
@Body() dto: RegisterDto,
|
||||
) {
|
||||
const imagePath = file ? file.filename : null;
|
||||
const savedCandidate = await this.prisma.candidate.create({
|
||||
@@ -72,27 +89,34 @@ export class AppController {
|
||||
}
|
||||
|
||||
@Put('candidate/:id')
|
||||
@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}`);
|
||||
}
|
||||
})
|
||||
}))
|
||||
@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
|
||||
@Body() dto: RegisterDto,
|
||||
) {
|
||||
const candidate = await this.prisma.candidate.findFirst({ where: { id } });
|
||||
if (!candidate) throw new NotFoundException(`Candidate with id ${id} not found`);
|
||||
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(`Cannot edit candidate form after 3 days`);
|
||||
const expirationDate = new Date(
|
||||
candidate.createdAt.valueOf() + 3 * dayMilliseconds,
|
||||
);
|
||||
if (expirationDate < new Date())
|
||||
throw new BadRequestException(`Cannot edit candidate form after 3 days`);
|
||||
|
||||
const profileImagePath = file ? file.filename : candidate.profileImage;
|
||||
|
||||
@@ -108,16 +132,21 @@ export class AppController {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@Delete('candidate/:id')
|
||||
async deleteCandidate(@Param('id', ParseIntPipe) id: number) {
|
||||
const candidate = await this.prisma.candidate.findFirst({ where: { id } });
|
||||
if (!candidate) throw new NotFoundException(`Candidate with id ${id} not found`);
|
||||
if (!candidate)
|
||||
throw new NotFoundException(`Candidate with id ${id} not found`);
|
||||
|
||||
await this.prisma.candidate.delete({ where: { id } });
|
||||
|
||||
if (candidate.profileImage) {
|
||||
const filePath = join(process.cwd(), 'assets', 'uploads', candidate.profileImage);
|
||||
const filePath = join(
|
||||
process.cwd(),
|
||||
'assets',
|
||||
'uploads',
|
||||
candidate.profileImage,
|
||||
);
|
||||
unlink(filePath, (err) => {
|
||||
if (err) {
|
||||
console.error('Failed to delete file:', err);
|
||||
|
||||
@@ -1,30 +1,34 @@
|
||||
import { MessageBody, OnGatewayConnection, OnGatewayDisconnect, SubscribeMessage, WebSocketGateway, WebSocketServer } from "@nestjs/websockets";
|
||||
import { Server, Socket } from "socket.io";
|
||||
import {
|
||||
OnGatewayConnection,
|
||||
OnGatewayDisconnect,
|
||||
WebSocketGateway,
|
||||
WebSocketServer,
|
||||
} from '@nestjs/websockets';
|
||||
import { Server, Socket } from 'socket.io';
|
||||
|
||||
@WebSocketGateway({
|
||||
cors: true
|
||||
cors: true,
|
||||
})
|
||||
|
||||
export class AppGetaway implements OnGatewayDisconnect, OnGatewayConnection {
|
||||
@WebSocketServer() server: Server
|
||||
@WebSocketServer() server: Server;
|
||||
|
||||
handleDisconnect(client: Socket) {
|
||||
console.log(`${client.id} disconnected`)
|
||||
}
|
||||
handleDisconnect(client: Socket) {
|
||||
console.log(`${client.id} disconnected`);
|
||||
}
|
||||
|
||||
handleConnection(client: Socket, ...args: any[]) {
|
||||
console.log(`${client.id} connected`)
|
||||
}
|
||||
handleConnection(client: Socket /*...args: any[]*/) {
|
||||
console.log(`${client.id} connected`);
|
||||
}
|
||||
|
||||
onAddCandidate(registrationData: any) {
|
||||
this.server.emit('candidateRegistered', registrationData);
|
||||
}
|
||||
onAddCandidate(registrationData: any) {
|
||||
this.server.emit('candidateRegistered', registrationData);
|
||||
}
|
||||
|
||||
onUpdateCandidate(updatedData: any) {
|
||||
this.server.emit('candidateUpdated', updatedData);
|
||||
}
|
||||
onUpdateCandidate(updatedData: any) {
|
||||
this.server.emit('candidateUpdated', updatedData);
|
||||
}
|
||||
|
||||
onDeleteCandidate(deletedId: number) {
|
||||
this.server.emit('candidateDeleted', deletedId);
|
||||
}
|
||||
}
|
||||
onDeleteCandidate(deletedId: number) {
|
||||
this.server.emit('candidateDeleted', deletedId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,14 +14,15 @@ import { ConfigModule } from '@nestjs/config';
|
||||
ServeStaticModule.forRoot(
|
||||
{
|
||||
rootPath: join(__dirname, 'assets/client'),
|
||||
renderPath: '/'
|
||||
renderPath: '/',
|
||||
},
|
||||
{
|
||||
rootPath: join(__dirname, 'assets/uploads'),
|
||||
serveRoot: '/uploads',
|
||||
}),
|
||||
},
|
||||
),
|
||||
],
|
||||
controllers: [AppController, StatsController],
|
||||
providers: [PrismaService, StatsService, AppGetaway],
|
||||
})
|
||||
export class AppModule { }
|
||||
export class AppModule {}
|
||||
|
||||
14
src/main.ts
14
src/main.ts
@@ -15,19 +15,11 @@ async function bootstrap() {
|
||||
setupSwagger(app);
|
||||
app.enableCors({
|
||||
origin: [true],
|
||||
methods: [
|
||||
'GET',
|
||||
'HEAD',
|
||||
'PUT',
|
||||
'PATCH',
|
||||
'POST',
|
||||
'DELETE',
|
||||
'OPTIONS',
|
||||
],
|
||||
methods: ['GET', 'HEAD', 'PUT', 'PATCH', 'POST', 'DELETE', 'OPTIONS'],
|
||||
allowedHeaders: ['*'],
|
||||
optionsSuccessStatus: 204,
|
||||
credentials: true,
|
||||
preflightContinue: false
|
||||
preflightContinue: false,
|
||||
});
|
||||
await app.listen(process.env.PORT ?? 3000);
|
||||
}
|
||||
@@ -43,5 +35,5 @@ function setupSwagger(app: INestApplication<any>) {
|
||||
SwaggerModule.setup('api', app, document);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
bootstrap();
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { PrismaClient } from 'generated/prisma';
|
||||
|
||||
@Injectable()
|
||||
export class PrismaService extends PrismaClient implements OnModuleInit {
|
||||
async onModuleInit() {
|
||||
await this.$connect();
|
||||
}
|
||||
}
|
||||
async onModuleInit() {
|
||||
await this.$connect();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,34 +1,33 @@
|
||||
import { Injectable } from "@nestjs/common";
|
||||
import { PrismaService } from "./prisma.service";
|
||||
import { AppGetaway } from "src/app.getaway";
|
||||
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { PrismaService } from './prisma.service';
|
||||
import { AppGetaway } from 'src/app.getaway';
|
||||
|
||||
@Injectable()
|
||||
export class StatsService {
|
||||
constructor(
|
||||
private prisma: PrismaService,
|
||||
private socketService: AppGetaway
|
||||
) { }
|
||||
constructor(
|
||||
private prisma: PrismaService,
|
||||
private socketService: AppGetaway,
|
||||
) {}
|
||||
|
||||
async incrementVisits() {
|
||||
const stats = await this.prisma.stats.update({
|
||||
where: { id: 1 },
|
||||
data: { totalVisits: { increment: 1 } },
|
||||
});
|
||||
this.socketService.server.emit('statsUpdated', stats);
|
||||
return stats;
|
||||
}
|
||||
async incrementVisits() {
|
||||
const stats = await this.prisma.stats.update({
|
||||
where: { id: 1 },
|
||||
data: { totalVisits: { increment: 1 } },
|
||||
});
|
||||
this.socketService.server.emit('statsUpdated', stats);
|
||||
return stats;
|
||||
}
|
||||
|
||||
async incrementClicks() {
|
||||
const stats = await this.prisma.stats.update({
|
||||
where: { id: 1 },
|
||||
data: { totalClicks: { increment: 1 } },
|
||||
});
|
||||
this.socketService.server.emit('statsUpdated', stats);
|
||||
return stats;
|
||||
}
|
||||
async incrementClicks() {
|
||||
const stats = await this.prisma.stats.update({
|
||||
where: { id: 1 },
|
||||
data: { totalClicks: { increment: 1 } },
|
||||
});
|
||||
this.socketService.server.emit('statsUpdated', stats);
|
||||
return stats;
|
||||
}
|
||||
|
||||
async getStats() {
|
||||
return this.prisma.stats.findUnique({ where: { id: 1 } });
|
||||
}
|
||||
async getStats() {
|
||||
return this.prisma.stats.findUnique({ where: { id: 1 } });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,20 +3,20 @@ import { StatsService } from './services/stats.service';
|
||||
|
||||
@Controller('stats')
|
||||
export class StatsController {
|
||||
constructor(private readonly statsService: StatsService) { }
|
||||
constructor(private readonly statsService: StatsService) {}
|
||||
|
||||
@Get()
|
||||
getStats() {
|
||||
return this.statsService.getStats();
|
||||
}
|
||||
@Get()
|
||||
getStats() {
|
||||
return this.statsService.getStats();
|
||||
}
|
||||
|
||||
@Post('visit')
|
||||
incrementVisit() {
|
||||
return this.statsService.incrementVisits();
|
||||
}
|
||||
@Post('visit')
|
||||
incrementVisit() {
|
||||
return this.statsService.incrementVisits();
|
||||
}
|
||||
|
||||
@Post('click')
|
||||
incrementClick() {
|
||||
return this.statsService.incrementClicks();
|
||||
}
|
||||
@Post('click')
|
||||
incrementClick() {
|
||||
return this.statsService.incrementClicks();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user