diff --git a/assets/uploads/profileImage-1756051504425-576080142.png b/assets/uploads/profileImage-1756051504425-576080142.png new file mode 100644 index 0000000..060c1d4 Binary files /dev/null and b/assets/uploads/profileImage-1756051504425-576080142.png differ diff --git a/assets/uploads/profileImage-1756051558334-70000459.png b/assets/uploads/profileImage-1756051558334-70000459.png new file mode 100644 index 0000000..7b81a8b Binary files /dev/null and b/assets/uploads/profileImage-1756051558334-70000459.png differ diff --git a/assets/uploads/profileImage-1756052029006-61410254.png b/assets/uploads/profileImage-1756052029006-61410254.png new file mode 100644 index 0000000..119ef1b Binary files /dev/null and b/assets/uploads/profileImage-1756052029006-61410254.png differ diff --git a/assets/uploads/profileImage-1756052103150-110638977.png b/assets/uploads/profileImage-1756052103150-110638977.png new file mode 100644 index 0000000..b610509 Binary files /dev/null and b/assets/uploads/profileImage-1756052103150-110638977.png differ diff --git a/assets/uploads/profileImage-1756052162400-772820453.png b/assets/uploads/profileImage-1756052162400-772820453.png new file mode 100644 index 0000000..86f2deb Binary files /dev/null and b/assets/uploads/profileImage-1756052162400-772820453.png differ diff --git a/assets/uploads/profileImage-1756052194078-183457847.png b/assets/uploads/profileImage-1756052194078-183457847.png new file mode 100644 index 0000000..834b6ce Binary files /dev/null and b/assets/uploads/profileImage-1756052194078-183457847.png differ diff --git a/assets/uploads/profileImage-1756052231467-661374958.png b/assets/uploads/profileImage-1756052231467-661374958.png new file mode 100644 index 0000000..7c4cc45 Binary files /dev/null and b/assets/uploads/profileImage-1756052231467-661374958.png differ diff --git a/assets/uploads/profileImage-1756052427617-312691193.jpg b/assets/uploads/profileImage-1756052427617-312691193.jpg new file mode 100644 index 0000000..7a3b4c1 Binary files /dev/null and b/assets/uploads/profileImage-1756052427617-312691193.jpg differ diff --git a/assets/uploads/profileImage-1756053237450-897610114.jpg b/assets/uploads/profileImage-1756053237450-897610114.jpg new file mode 100644 index 0000000..7a3b4c1 Binary files /dev/null and b/assets/uploads/profileImage-1756053237450-897610114.jpg differ diff --git a/assets/uploads/profileImage-1756059946876-912349692.jpg b/assets/uploads/profileImage-1756059946876-912349692.jpg new file mode 100644 index 0000000..7a3b4c1 Binary files /dev/null and b/assets/uploads/profileImage-1756059946876-912349692.jpg differ diff --git a/assets/uploads/profileImage-1756212925924-35299885.png b/assets/uploads/profileImage-1756212925924-35299885.png new file mode 100644 index 0000000..060c1d4 Binary files /dev/null and b/assets/uploads/profileImage-1756212925924-35299885.png differ diff --git a/assets/uploads/profileImage-1756212996591-498695492.png b/assets/uploads/profileImage-1756212996591-498695492.png new file mode 100644 index 0000000..86f2deb Binary files /dev/null and b/assets/uploads/profileImage-1756212996591-498695492.png differ diff --git a/assets/uploads/profileImage-1756213111781-8673126.jpg b/assets/uploads/profileImage-1756213111781-8673126.jpg new file mode 100644 index 0000000..7a3b4c1 Binary files /dev/null and b/assets/uploads/profileImage-1756213111781-8673126.jpg differ diff --git a/assets/uploads/profileImage-1756213893152-387543064.jpg b/assets/uploads/profileImage-1756213893152-387543064.jpg new file mode 100644 index 0000000..7a3b4c1 Binary files /dev/null and b/assets/uploads/profileImage-1756213893152-387543064.jpg differ diff --git a/prisma/migrations/20250824170509_init/migration.sql b/prisma/migrations/20250824170509_init/migration.sql new file mode 100644 index 0000000..8d4050a --- /dev/null +++ b/prisma/migrations/20250824170509_init/migration.sql @@ -0,0 +1,8 @@ +-- CreateTable +CREATE TABLE "public"."Stats" ( + "id" INTEGER NOT NULL DEFAULT 1, + "totalVisits" INTEGER NOT NULL DEFAULT 0, + "totalClicks" INTEGER NOT NULL DEFAULT 0, + + CONSTRAINT "Stats_pkey" PRIMARY KEY ("id") +); diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 58ba974..03edd18 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -26,3 +26,9 @@ model Candidate { profileImage String? createdAt DateTime @default(now()) } + +model Stats { + id Int @id @default(1) + totalVisits Int @default(0) + totalClicks Int @default(0) +} diff --git a/src/app.controller.ts b/src/app.controller.ts index 6737f51..30ca365 100644 --- a/src/app.controller.ts +++ b/src/app.controller.ts @@ -1,4 +1,4 @@ -import { BadRequestException, Body, Controller, 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'; @@ -31,6 +31,7 @@ export class AppController { return this.prisma.candidate.findFirst({ where: { id: id } }); } + @Post('register') @UseInterceptors(FileInterceptor('profileImage', { storage: diskStorage({ @@ -95,4 +96,17 @@ 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`); + + await this.prisma.candidate.delete({ where: { id } }); + + this.socketService.onDeleteCandidate(id); + + return candidate; + } } diff --git a/src/app.getaway.ts b/src/app.getaway.ts index 7f833cf..1db517a 100644 --- a/src/app.getaway.ts +++ b/src/app.getaway.ts @@ -23,4 +23,8 @@ export class AppGetaway implements OnGatewayDisconnect, OnGatewayConnection { onUpdateCandidate(updatedData: any) { this.server.emit('candidateUpdated', updatedData); } + + onDeleteCandidate(deletedId: number) { + this.server.emit('candidateDeleted', deletedId); + } } \ No newline at end of file diff --git a/src/app.module.ts b/src/app.module.ts index 577c7fb..bd2fb09 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -4,6 +4,8 @@ import { ServeStaticModule } from '@nestjs/serve-static'; import { join } from 'path'; import { PrismaService } from './services/prisma.service'; import { AppGetaway } from './app.getaway'; +import { StatsController } from './stats.controller'; +import { StatsService } from './services/stats.service'; @Module({ imports: [ @@ -17,7 +19,7 @@ import { AppGetaway } from './app.getaway'; serveRoot: '/uploads', }), ], - controllers: [AppController], - providers: [PrismaService, AppGetaway], + controllers: [AppController, StatsController], + providers: [PrismaService, StatsService, AppGetaway], }) export class AppModule { } diff --git a/src/services/stats.service.ts b/src/services/stats.service.ts new file mode 100644 index 0000000..cfa83ee --- /dev/null +++ b/src/services/stats.service.ts @@ -0,0 +1,34 @@ +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 + ) { } + + 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 getStats() { + return this.prisma.stats.findUnique({ where: { id: 1 } }); + } +} diff --git a/src/stats.controller.ts b/src/stats.controller.ts new file mode 100644 index 0000000..4be41e8 --- /dev/null +++ b/src/stats.controller.ts @@ -0,0 +1,22 @@ +import { Controller, Get, Post } from '@nestjs/common'; +import { StatsService } from './services/stats.service'; + +@Controller('stats') +export class StatsController { + constructor(private readonly statsService: StatsService) { } + + @Get() + getStats() { + return this.statsService.getStats(); + } + + @Post('visit') + incrementVisit() { + return this.statsService.incrementVisits(); + } + + @Post('click') + incrementClick() { + return this.statsService.incrementClicks(); + } +}