update approve center
This commit is contained in:
79
package-lock.json
generated
79
package-lock.json
generated
@@ -34,7 +34,7 @@
|
||||
"@pothos/plugin-scope-auth": "^4.1.0",
|
||||
"@pothos/plugin-simple-objects": "^4.1.0",
|
||||
"@pothos/plugin-smart-subscriptions": "^4.1.0",
|
||||
"@prisma/client": "^5.20.0",
|
||||
"@prisma/client": "^5.21.1",
|
||||
"@smatch-corp/nestjs-pothos": "^0.3.0",
|
||||
"@smatch-corp/nestjs-pothos-apollo-driver": "^0.1.0",
|
||||
"apollo-server-express": "^3.13.0",
|
||||
@@ -88,7 +88,7 @@
|
||||
"globals": "^15.10.0",
|
||||
"jest": "^29.5.0",
|
||||
"prettier": "^3.0.0",
|
||||
"prisma": "^5.20.0",
|
||||
"prisma": "^5.21.1",
|
||||
"source-map-support": "^0.5.21",
|
||||
"supertest": "^7.0.0",
|
||||
"ts-jest": "^29.1.0",
|
||||
@@ -5239,9 +5239,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@prisma/client": {
|
||||
"version": "5.20.0",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.20.0.tgz",
|
||||
"integrity": "sha512-CLv55ZuMuUawMsxoqxGtLT3bEZoa2W8L3Qnp6rDIFWy+ZBrUcOFKdoeGPSnbBqxc3SkdxJrF+D1veN/WNynZYA==",
|
||||
"version": "5.21.1",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.21.1.tgz",
|
||||
"integrity": "sha512-3n+GgbAZYjaS/k0M03yQsQfR1APbr411r74foknnsGpmhNKBG49VuUkxIU6jORgvJPChoD4WC4PqoHImN1FP0w==",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
@@ -5263,38 +5263,52 @@
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/@prisma/engines": {
|
||||
"version": "5.20.0",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.20.0.tgz",
|
||||
"integrity": "sha512-DtqkP+hcZvPEbj8t8dK5df2b7d3B8GNauKqaddRRqQBBlgkbdhJkxhoJTrOowlS3vaRt2iMCkU0+CSNn0KhqAQ==",
|
||||
"version": "5.21.1",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.21.1.tgz",
|
||||
"integrity": "sha512-hGVTldUkIkTwoV8//hmnAAiAchi4oMEKD3aW5H2RrnI50tTdwza7VQbTTAyN3OIHWlK5DVg6xV7X8N/9dtOydA==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@prisma/debug": "5.20.0",
|
||||
"@prisma/engines-version": "5.20.0-12.06fc58a368dc7be9fbbbe894adf8d445d208c284",
|
||||
"@prisma/fetch-engine": "5.20.0",
|
||||
"@prisma/get-platform": "5.20.0"
|
||||
"@prisma/debug": "5.21.1",
|
||||
"@prisma/engines-version": "5.21.1-1.bf0e5e8a04cada8225617067eaa03d041e2bba36",
|
||||
"@prisma/fetch-engine": "5.21.1",
|
||||
"@prisma/get-platform": "5.21.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@prisma/engines-version": {
|
||||
"version": "5.20.0-12.06fc58a368dc7be9fbbbe894adf8d445d208c284",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.20.0-12.06fc58a368dc7be9fbbbe894adf8d445d208c284.tgz",
|
||||
"integrity": "sha512-Lg8AS5lpi0auZe2Mn4gjuCg081UZf88k3cn0RCwHgR+6cyHHpttPZBElJTHf83ZGsRNAmVCZCfUGA57WB4u4JA==",
|
||||
"version": "5.21.1-1.bf0e5e8a04cada8225617067eaa03d041e2bba36",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.21.1-1.bf0e5e8a04cada8225617067eaa03d041e2bba36.tgz",
|
||||
"integrity": "sha512-qvnEflL0//lh44S/T9NcvTMxfyowNeUxTunPcDfKPjyJNrCNf2F1zQLcUv5UHAruECpX+zz21CzsC7V2xAeM7Q==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/@prisma/engines/node_modules/@prisma/debug": {
|
||||
"version": "5.21.1",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.21.1.tgz",
|
||||
"integrity": "sha512-uY8SAhcnORhvgtOrNdvWS98Aq/nkQ9QDUxrWAgW8XrCZaI3j2X7zb7Xe6GQSh6xSesKffFbFlkw0c2luHQviZA==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/@prisma/fetch-engine": {
|
||||
"version": "5.20.0",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-5.20.0.tgz",
|
||||
"integrity": "sha512-JVcaPXC940wOGpCOwuqQRTz6I9SaBK0c1BAyC1pcz9xBi+dzFgUu3G/p9GV1FhFs9OKpfSpIhQfUJE9y00zhqw==",
|
||||
"version": "5.21.1",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-5.21.1.tgz",
|
||||
"integrity": "sha512-70S31vgpCGcp9J+mh/wHtLCkVezLUqe/fGWk3J3JWZIN7prdYSlr1C0niaWUyNK2VflLXYi8kMjAmSxUVq6WGQ==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@prisma/debug": "5.20.0",
|
||||
"@prisma/engines-version": "5.20.0-12.06fc58a368dc7be9fbbbe894adf8d445d208c284",
|
||||
"@prisma/get-platform": "5.20.0"
|
||||
"@prisma/debug": "5.21.1",
|
||||
"@prisma/engines-version": "5.21.1-1.bf0e5e8a04cada8225617067eaa03d041e2bba36",
|
||||
"@prisma/get-platform": "5.21.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@prisma/fetch-engine/node_modules/@prisma/debug": {
|
||||
"version": "5.21.1",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.21.1.tgz",
|
||||
"integrity": "sha512-uY8SAhcnORhvgtOrNdvWS98Aq/nkQ9QDUxrWAgW8XrCZaI3j2X7zb7Xe6GQSh6xSesKffFbFlkw0c2luHQviZA==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/@prisma/generator-helper": {
|
||||
"version": "5.20.0",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/generator-helper/-/generator-helper-5.20.0.tgz",
|
||||
@@ -5305,15 +5319,22 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@prisma/get-platform": {
|
||||
"version": "5.20.0",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-5.20.0.tgz",
|
||||
"integrity": "sha512-8/+CehTZZNzJlvuryRgc77hZCWrUDYd/PmlZ7p2yNXtmf2Una4BWnTbak3us6WVdqoz5wmptk6IhsXdG2v5fmA==",
|
||||
"version": "5.21.1",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-5.21.1.tgz",
|
||||
"integrity": "sha512-sRxjL3Igst3ct+e8ya/x//cDXmpLbZQ5vfps2N4tWl4VGKQAmym77C/IG/psSMsQKszc8uFC/q1dgmKFLUgXZQ==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@prisma/debug": "5.20.0"
|
||||
"@prisma/debug": "5.21.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@prisma/get-platform/node_modules/@prisma/debug": {
|
||||
"version": "5.21.1",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.21.1.tgz",
|
||||
"integrity": "sha512-uY8SAhcnORhvgtOrNdvWS98Aq/nkQ9QDUxrWAgW8XrCZaI3j2X7zb7Xe6GQSh6xSesKffFbFlkw0c2luHQviZA==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/@protobufjs/aspromise": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
|
||||
@@ -14914,14 +14935,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/prisma": {
|
||||
"version": "5.20.0",
|
||||
"resolved": "https://registry.npmjs.org/prisma/-/prisma-5.20.0.tgz",
|
||||
"integrity": "sha512-6obb3ucKgAnsGS9x9gLOe8qa51XxvJ3vLQtmyf52CTey1Qcez3A6W6ROH5HIz5Q5bW+0VpmZb8WBohieMFGpig==",
|
||||
"version": "5.21.1",
|
||||
"resolved": "https://registry.npmjs.org/prisma/-/prisma-5.21.1.tgz",
|
||||
"integrity": "sha512-PB+Iqzld/uQBPaaw2UVIk84kb0ITsLajzsxzsadxxl54eaU5Gyl2/L02ysivHxK89t7YrfQJm+Ggk37uvM70oQ==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@prisma/engines": "5.20.0"
|
||||
"@prisma/engines": "5.21.1"
|
||||
},
|
||||
"bin": {
|
||||
"prisma": "build/index.js"
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
"prisma:reset": "npx prisma migrate reset --schema=./epess-database/prisma/schema.prisma",
|
||||
"prisma:seed": "npx prisma db seed --schema=./epess-database/prisma/schema.prisma",
|
||||
"prisma:format": "npx prisma format --schema=./epess-database/prisma/schema.prisma",
|
||||
"prisma:studio": "npx prisma studio --schema=./epess-database/prisma/schema.prisma",
|
||||
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
|
||||
"prettier": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
|
||||
"test": "jest",
|
||||
@@ -53,7 +54,7 @@
|
||||
"@pothos/plugin-scope-auth": "^4.1.0",
|
||||
"@pothos/plugin-simple-objects": "^4.1.0",
|
||||
"@pothos/plugin-smart-subscriptions": "^4.1.0",
|
||||
"@prisma/client": "^5.20.0",
|
||||
"@prisma/client": "^5.21.1",
|
||||
"@smatch-corp/nestjs-pothos": "^0.3.0",
|
||||
"@smatch-corp/nestjs-pothos-apollo-driver": "^0.1.0",
|
||||
"apollo-server-express": "^3.13.0",
|
||||
@@ -107,7 +108,7 @@
|
||||
"globals": "^15.10.0",
|
||||
"jest": "^29.5.0",
|
||||
"prettier": "^3.0.0",
|
||||
"prisma": "^5.20.0",
|
||||
"prisma": "^5.21.1",
|
||||
"source-map-support": "^0.5.21",
|
||||
"supertest": "^7.0.0",
|
||||
"ts-jest": "^29.1.0",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { Inject, Injectable, Logger } from '@nestjs/common';
|
||||
import {
|
||||
Pothos,
|
||||
PothosRef,
|
||||
@@ -9,13 +9,14 @@ import { Builder } from '../Graphql/graphql.builder';
|
||||
import { PrismaService } from '../Prisma/prisma.service';
|
||||
import { MinioService } from '../Minio/minio.service';
|
||||
import { CenterStatus } from '@prisma/client';
|
||||
|
||||
import { MailService } from '../Mail/mail.service';
|
||||
@Injectable()
|
||||
export class CenterSchema extends PothosSchema {
|
||||
constructor(
|
||||
@Inject(SchemaBuilderToken) private readonly builder: Builder,
|
||||
private readonly prisma: PrismaService,
|
||||
private readonly minioService: MinioService,
|
||||
private readonly mailService: MailService,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
@@ -189,6 +190,77 @@ export class CenterSchema extends PothosSchema {
|
||||
});
|
||||
},
|
||||
}),
|
||||
approveOrRejectCenter: t.prismaField({
|
||||
type: this.center(),
|
||||
description: 'Approve a center and promote centerstaff to staff',
|
||||
args: {
|
||||
centerId: t.arg({
|
||||
type: 'String',
|
||||
required: true,
|
||||
}),
|
||||
approve: t.arg({
|
||||
type: 'Boolean',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
resolve: async (query, root, args, ctx, info) => {
|
||||
return await this.prisma.$transaction(async (prisma) => {
|
||||
const center = await prisma.center.findUnique({
|
||||
...query,
|
||||
where: {
|
||||
id: args.centerId,
|
||||
},
|
||||
});
|
||||
if (!center) {
|
||||
throw new Error('Center not found');
|
||||
}
|
||||
// check if center is already approved or rejected
|
||||
if (
|
||||
center.centerStatus === CenterStatus.APPROVED ||
|
||||
center.centerStatus === CenterStatus.REJECTED
|
||||
) {
|
||||
throw new Error('Center is already approved or rejected');
|
||||
}
|
||||
// find center owner and promote to staff
|
||||
const centerOwnerId = center.centerOwnerId;
|
||||
if (!centerOwnerId) {
|
||||
throw new Error('Center owner not found');
|
||||
}
|
||||
const centerOwner = await prisma.user.findUnique({
|
||||
where: {
|
||||
id: centerOwnerId,
|
||||
},
|
||||
});
|
||||
if (!centerOwner) {
|
||||
throw new Error('Center owner not found');
|
||||
}
|
||||
const updatedCenter = await prisma.center.update({
|
||||
...query,
|
||||
where: {
|
||||
id: args.centerId,
|
||||
},
|
||||
data: {
|
||||
centerStatus: args.approve
|
||||
? CenterStatus.APPROVED
|
||||
: CenterStatus.REJECTED,
|
||||
},
|
||||
});
|
||||
// mail to center owner
|
||||
try {
|
||||
await this.mailService.sendEmail(
|
||||
centerOwner.email,
|
||||
args.approve
|
||||
? 'Your center has been approved'
|
||||
: 'Your center has been rejected',
|
||||
args.approve ? 'center-approved' : 'center-rejected',
|
||||
);
|
||||
} catch (error) {
|
||||
Logger.error(error, 'CenterSchema');
|
||||
}
|
||||
return updatedCenter;
|
||||
});
|
||||
},
|
||||
}),
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,17 +13,15 @@ export class MailService {
|
||||
|
||||
async sendEmail(to: string, subject: string, text: string) {
|
||||
try {
|
||||
const mailContent =
|
||||
await this.openaiService.generateInvitationMailContent(
|
||||
to,
|
||||
'John Doe',
|
||||
'https://epess.org',
|
||||
);
|
||||
const mailContent = `
|
||||
<h1>${subject}</h1>
|
||||
<p>${text}</p>
|
||||
`;
|
||||
|
||||
const result = await this.mailerService.sendMail({
|
||||
to,
|
||||
subject,
|
||||
text: mailContent ?? text,
|
||||
text: mailContent ?? text,
|
||||
});
|
||||
Logger.log(result, 'MailService');
|
||||
} catch (error) {
|
||||
|
||||
71
src/Mail/templates/StaffInvitation.pug
Normal file
71
src/Mail/templates/StaffInvitation.pug
Normal file
@@ -0,0 +1,71 @@
|
||||
doctype html
|
||||
html
|
||||
head
|
||||
meta(charset="UTF-8")
|
||||
title Thư mời làm việc từ Trung tâm [center_name]
|
||||
style.
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
background-color: #f0f8ff;
|
||||
color: #333;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.container {
|
||||
max-width: 600px;
|
||||
margin: 20px auto;
|
||||
padding: 20px;
|
||||
background-color: #ffffff;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
.header {
|
||||
text-align: center;
|
||||
background-color: #457D84; /* Medium teal */
|
||||
color: #ffffff;
|
||||
padding: 15px;
|
||||
border-radius: 8px 8px 0 0;
|
||||
}
|
||||
.header h1 {
|
||||
margin: 0;
|
||||
font-size: 24px;
|
||||
}
|
||||
.content {
|
||||
padding: 20px;
|
||||
color: #333;
|
||||
}
|
||||
.content p {
|
||||
font-size: 16px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.button {
|
||||
display: inline-block;
|
||||
padding: 12px 20px;
|
||||
background-color: #2BD4E2; /* Bright aqua */
|
||||
color: #ffffff;
|
||||
text-decoration: none;
|
||||
font-size: 16px;
|
||||
border-radius: 5px;
|
||||
text-align: center;
|
||||
margin: 20px 0;
|
||||
}
|
||||
.footer {
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
color: #555;
|
||||
padding: 10px;
|
||||
border-top: 1px solid #e0e0e0;
|
||||
}
|
||||
body
|
||||
.container
|
||||
.header
|
||||
h1 Thư mời làm việc từ Trung tâm [center_name]
|
||||
.content
|
||||
p Chào bạn,
|
||||
p Chúng tôi rất vui mừng thông báo rằng bạn đã được mời làm nhân viên tại trung tâm [center_name].
|
||||
p Để tiếp tục quá trình ứng tuyển, vui lòng nhấn vào nút dưới đây để truy cập vào trang nộp resume của bạn.
|
||||
a.button(href="http://localhost:3000/upload-cv?centerId=[center_id]") Nộp Resume
|
||||
p Nếu bạn có bất kỳ thắc mắc nào, đừng ngần ngại liên hệ với chúng tôi.
|
||||
.footer
|
||||
p Trân trọng,
|
||||
p EPESS
|
||||
Reference in New Issue
Block a user