cover me email request routine

This commit is contained in:
Dobromir Popov
2024-04-06 11:09:22 +03:00
parent fa5d3f4f99
commit 09db5ca8b9
11 changed files with 433 additions and 246 deletions

View File

@@ -5,6 +5,7 @@ import type { NextApiRequest, NextApiResponse } from 'next';
import { createRouter, expressWrapper } from "next-connect";
const common = require('../../src/helpers/common');
const emailHelper = require('../../src/helpers/email');
const { v4: uuidv4 } = require('uuid');
import fs from 'fs';
import path from 'path';
@@ -24,125 +25,60 @@ const router = createRouter<NextApiRequest, NextApiResponse>();
export default async function handler(req, res) {
const prisma = common.getPrismaClient();
var action = req.query.action;
const action = req.query.action;
const emailaction = req.query.emailaction;
// Retrieve and validate the JWT token
const token = await getToken({ req: req });
//response is a special action that does not require a token
if (action !== "email_response") {
if (!token) {
// If no token or invalid token, return unauthorized status
return res.status(401).json({ message: "Unauthorized to call this API endpoint" });
}
}
var userId = req.query.userId;
var email = req.query.email;
let date = new Date();
if (!userId && !email) {
return res.status(400).json({ message: "User ID or email is not provided" });
}
// Retrieve the user
const user = await prisma.publisher.findUnique({
where: {
id: userId,
email: email
}
});
if (!user) {
return res.status(404).json({ message: "User not found" });
}
var emailaction = req.query.emailaction;
switch (action) {
case "send_coverme_request":
// Send CoverMe request to the user
//get from POST data: shiftId, assignmentId, date
let shiftId = req.body.shiftId;
let assignmentId = req.body.assignmentId;
let date = req.body.date;
console.log("User: " + user.email + " sent a CoverMe request: " +
shiftId + " " + assignmentId + " " + date);
//get all subscribed publisers
const subscribedPublishers = await prisma.publisher.findMany({
where: {
isSubscribedToCoverMe: true
}
});
//send email to all subscribed publishers
for (let i = 0; i < subscribedPublishers.length; i++) {
//send email to subscribed publisher
let shift = await prisma.shift.findUnique({
where: {
id: parseInt(shiftId)
},
include: {
cartEvent: {
include: {
location: true
}
},
}
}
);
let acceptUrl = process.env.NEXTAUTH_URL + "/api/emailActions?action=coverme_accept&userId=" + user.id + "&shiftId=" + shiftId + "&assignmentId=" + assignmentId;
let model = {
user: user,
shiftId: shiftId,
assignmentId: assignmentId,
acceptUrl: acceptUrl,
prefix: subscribedPublishers[i].isMale ? "Брат" : "Сестра",
firstName: subscribedPublishers[i].firstName,
lastName: subscribedPublishers[i].lastName,
placeName: shift.cartEvent.location.name,
dateStr: date.toLocaleDateString(),
sentDate: date.toLocaleTimeString()
};
emailHelper.SendEmailHandlebars(subscribedPublishers[i].email, "coverMe", model);
}
break;
case "email_response":
//get email action
if (!emailaction) {
return res.status(400).json({ message: "Email action is not provided" });
}
break;
default:
return res.status(400).json({ message: "Invalid action" });
}
if (action !== "email_response") {
if (action == "email_response") {
switch (emailaction) {
case "coverme_accept":
// Update the user status to accepted
console.log("User: " + user.firstName + " " + user.lastName + " accepted the CoverMe request");
case "coverMeAccept":
//validate shiftId and assignmentId
let shiftId = req.query.shiftId;
let assignmentId = req.query.assignmentId;
if (!shiftId || !assignmentId) {
return res.status(400).json({ message: "Shift ID or Assignment ID is not provided" });
}
//get the assignment
const assignment = await prisma.assignment.findUnique({
let userId = req.query.userId;
let user = await prisma.publisher.findUnique({
where: {
id: parseInt(assignmentId)
id: userId
}
});
// Update the user status to accepted
console.log("User: " + user.firstName + " " + user.lastName + " accepted the CoverMe request");
let assignmentPID = req.query.assignmentPID;
if (!shiftId) {
return res.status(400).json({ message: "Shift ID is not provided" });
}
if (!assignmentPID) {
return res.status(400).json({ message: "Assignment PID is not provided" });
}
//check if the assignment request is still open
const assignment = await prisma.assignment.findFirst({
where: {
publicGuid: assignmentPID,
shiftId: parseInt(shiftId),
isConfirmed: false
},
include: {
shift: {
include: {
cartEvent: {
include: {
location: true
}
}
}
}
}
});
if (!assignment) {
return res.status(404).json({ message: "Assignment not found" });
}
if (assignment.shiftId != parseInt(shiftId)) {
return res.status(400).json({ message: "Shift ID does not match" });
const messagePageUrl = `/message?message=${encodeURIComponent('Някой друг вече е отговорил на рази заявка за заместване')}&type=info&caption=${encodeURIComponent('Заявката е вече обработена')}`;
res.redirect(messagePageUrl);
return;
}
emailHelper.SendEmail_NewShifts(user, [assignment.shift]);
// await prisma.user.update({
// where: {
// id: parseInt(userId)
@@ -189,13 +125,109 @@ export default async function handler(req, res) {
// const emailResponse = await common.sendEmail(user.email, "Email Action Processed",
// "Your email action was processed successfully");
}
return res.status(200).json({ message: "User action processed" });
}
else {
const token = await getToken({ req: req });
if (!token) {
// If no token or invalid token, return unauthorized status
return res.status(401).json({ message: "Unauthorized to call this API endpoint" });
}
const user = await prisma.publisher.findUnique({
where: {
email: token.email
}
});
switch (action) {
case "sendCoverMeRequestByEmail":
// Send CoverMe request to the user
//get from POST data: shiftId, assignmentId, date
//let shiftId = req.body.shiftId;
let assignmentId = req.body.assignmentId;
let date = req.body.date;
console.log("User: " + user.email + " sent a 'CoverMe' request for his assignment " + assignmentId + " " + date);
let assignment = await prisma.assignment.findUnique({
where: {
id: parseInt(assignmentId)
},
include: {
shift: {
include: {
cartEvent: {
include: {
location: true
}
}
}
}
}
});
// update the assignment. generate new publicGuid, isConfirmed to false
let newPublicGuid = uuidv4();
await prisma.assignment.update({
where: {
id: parseInt(assignmentId)
},
data: {
publicGuid: newPublicGuid, // if this exists, we consider the request open
isConfirmed: false
}
});
//get all subscribed publisers
const subscribedPublishers = await prisma.publisher.findMany({
where: {
isSubscribedToCoverMe: true
}
});
//send email to all subscribed publishers
for (let i = 0; i < subscribedPublishers.length; i++) {
if (subscribedPublishers[i].id == user.id) {
continue;
}
//send email to subscribed publisher
let acceptUrl = process.env.NEXTAUTH_URL + "/api/email?action=email_response&emailaction=coverMeAccept&userId=" + subscribedPublishers[i].id + "&shiftId=" + assignment.shiftId + "&assignmentPID=" + newPublicGuid;
let model = {
user: user,
shiftId: assignment.shiftId,
acceptUrl: acceptUrl,
prefix: user.isMale ? "Брат" : "Сестра",
firstName: subscribedPublishers[i].firstName,
lastName: subscribedPublishers[i].lastName,
placeName: assignment.shift.cartEvent.location.name,
dateStr: common.getDateFormated(assignment.shift.startTime),
time: common.formatTimeHHmm(assignment.shift.startTime),
sentDate: common.getDateFormated(new Date())
};
let results = emailHelper.SendEmailHandlebars(
{
name: subscribedPublishers[i].firstName + " " + subscribedPublishers[i].lastName,
email: subscribedPublishers[i].email
}, "coverMe", model);
// if (results) {
// console.log("Error sending email: " + error);
// return res.status(500).json({ message: "Error sending email:" + error });
//}
if (results) {
console.log("Email sent to: " + subscribedPublishers[i].email);
}
}
break;
default:
return res.status(400).json({ message: "Invalid action" });
}
return res.status(200).json({ message: "User action processed" });
}
}
router.use(expressWrapper(handler));

View File

@@ -51,6 +51,23 @@ export default function MySchedulePage({ assignments }) {
console.log("error", error);
});
};
const searchReplacement = (assignmentId) => {
axiosInstance.post('/api/email?action=sendCoverMeRequestByEmail', {
assignmentId: assignmentId,
}).then(response => {
console.log("response", response);
//toast success and confirm the change
toast.success("Заявката за заместник е изпратена!", {
onClose: () => {
window.location.reload();
}
});
}).catch(error => {
console.log("error", error);
});
}
return (
<Layout>
<ProtectedRoute allowedRoles={[UserRole.ADMIN, UserRole.POWERUSER, UserRole.USER]}>
@@ -101,14 +118,14 @@ export default function MySchedulePage({ assignments }) {
setIsModalOpen(true)
}}
>
Заместник
Избери Заместник
</button>
{/* <button
className="inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md shadow-sm text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
<button
className="inline-flex items-center px-3 mx-2 py-2 border border-transparent text-sm leading-4 font-medium rounded-md shadow-sm text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
onClick={() => searchReplacement(assignment.id)}
>
Търси заместник
</button> */}
</button>
</dd>
</div>
</dl>

27
pages/message.tsx Normal file
View File

@@ -0,0 +1,27 @@
// pages/message.js
import { useRouter } from 'next/router';
import Layout from "../components/layout";
export default function MessagePage() {
const router = useRouter();
const messageStyles = {
error: "text-red-500",
warning: "text-yellow-500",
info: "text-blue-500",
};
const { message, type = messageStyles.info, caption } = router.query;
return (
<Layout>
<div className="flex items-center justify-center min-h-screen">
<div className="text-center">
<h1 className={`text-2xl font-bold mb-4 ${messageStyles[type]}`}>{caption || 'Информация'}</h1>
<p className="mb-6">
{message || 'Така ще получавате различни съобщения.'}
</p>
</div>
</div>
</Layout>
);
}