Files
gg-backend/backend/src/controllers/healthCheck.controller.js
T
2026-05-26 11:56:22 +05:30

528 lines
13 KiB
JavaScript

import prisma from "../prisma/client.js";
import { sendEmail } from "../utils/sendEmail.js";
import { getEmailsByType } from "../utils/getEmailByTypes.js";
export const getAllCategories = async (req, res) => {
try {
const { admin } = req.query;
const categories = await prisma.healthCheckCategory.findMany({
where: admin === "true" ? {} : { isActive: true },
orderBy: { sortOrder: "asc" },
include: {
_count: { select: { packages: true } },
},
});
return res.status(200).json({ success: true, data: categories });
} catch (error) {
return res
.status(500)
.json({ success: false, message: "Failed to fetch categories" });
}
};
export const createCategory = async (req, res) => {
try {
const { name, slug, description, isActive, sortOrder } = req.body;
const category = await prisma.healthCheckCategory.create({
data: {
name,
slug: slug || null,
description,
isActive: isActive ?? true,
sortOrder: sortOrder ? Number(sortOrder) : 1000,
},
});
return res
.status(201)
.json({ success: true, message: "Category created", data: category });
} catch (error) {
console.error(error);
return res
.status(500)
.json({ success: false, message: "Failed to create category" });
}
};
export const updateCategory = async (req, res) => {
try {
const { id } = req.params;
const data = { ...req.body };
delete data.id;
delete data._count;
delete data.createdAt;
delete data.updatedAt;
if (data.sortOrder !== undefined) data.sortOrder = Number(data.sortOrder);
if (data.slug === "") data.slug = null;
const updatedCategory = await prisma.$transaction(async (tx) => {
const category = await tx.healthCheckCategory.update({
where: { id: Number(id) },
data,
});
if (data.isActive === false) {
await tx.healthPackage.updateMany({
where: { categoryId: Number(id) },
data: { isActive: false },
});
}
return category;
});
return res.status(200).json({
success: true,
message: "Category updated",
data: updatedCategory,
});
} catch (error) {
console.error(error);
return res
.status(500)
.json({ success: false, message: "Failed to update category" });
}
};
export const deleteCategory = async (req, res) => {
try {
const { id } = req.params;
await prisma.healthCheckCategory.delete({
where: { id: Number(id) },
});
return res
.status(200)
.json({ success: true, message: "Category deleted successfully" });
} catch (error) {
console.error(error);
return res.status(500).json({
success: false,
message:
"Failed to delete category. Ensure no packages are linked to it.",
});
}
};
export const getAllPackages = async (req, res) => {
try {
const { admin, categorySlug } = req.query;
const packages = await prisma.healthPackage.findMany({
where: {
AND: [
admin === "true" ? {} : { isActive: true },
categorySlug ? { category: { slug: categorySlug } } : {},
],
},
include: {
category: true,
seo: true,
},
orderBy: [{ sortOrder: "asc" }, { createdAt: "desc" }],
});
return res.status(200).json({ success: true, data: packages });
} catch (error) {
console.error(error);
return res
.status(500)
.json({ success: false, message: "Failed to fetch packages" });
}
};
export const createPackage = async (req, res) => {
try {
const {
name,
slug,
description,
price,
image,
discountedPrice,
inclusions,
categoryId,
isActive,
isFeatured,
sortOrder,
seo,
} = req.body;
const healthPackage = await prisma.healthPackage.create({
data: {
name,
slug,
description,
price,
image,
discountedPrice,
inclusions,
categoryId: Number(categoryId),
isActive: isActive ?? true,
isFeatured: isFeatured ?? false,
sortOrder: sortOrder ? Number(sortOrder) : 1000,
...(seo && {
seo: {
create: {
seoTitle: seo.seoTitle,
metaDescription: seo.metaDescription,
focusKeyphrase: seo.focusKeyphrase,
slug: slug,
tags: seo.tags || [],
ogTitle: seo.ogTitle,
ogDescription: seo.ogDescription,
ogImage: seo.ogImage,
},
},
}),
},
include: {
category: true,
seo: true,
},
});
return res
.status(201)
.json({ success: true, message: "Package created", data: healthPackage });
} catch (error) {
console.error(error);
return res
.status(500)
.json({ success: false, message: "Failed to create package" });
}
};
export const updatePackage = async (req, res) => {
try {
const { id } = req.params;
const data = { ...req.body };
delete data.id;
delete data.category;
delete data.createdAt;
delete data.updatedAt;
delete data.seoId;
if (data.categoryId) data.categoryId = Number(data.categoryId);
if (data.sortOrder) data.sortOrder = Number(data.sortOrder);
const existingPackage = await prisma.healthPackage.findUnique({
where: { id: Number(id) },
select: { slug: true },
});
const seoSlug = data.slug || existingPackage.slug;
const updated = await prisma.healthPackage.update({
where: { id: Number(id) },
data: {
...data,
seo: data.seo
? {
upsert: {
create: {
seoTitle: data.seo.seoTitle,
metaDescription: data.seo.metaDescription,
focusKeyphrase: data.seo.focusKeyphrase,
slug: seoSlug,
tags: data.seo.tags || [],
ogTitle: data.seo.ogTitle,
ogDescription: data.seo.ogDescription,
ogImage: data.seo.ogImage,
},
update: {
seoTitle: data.seo.seoTitle,
metaDescription: data.seo.metaDescription,
focusKeyphrase: data.seo.focusKeyphrase,
slug: seoSlug,
tags: data.seo.tags || [],
ogTitle: data.seo.ogTitle,
ogDescription: data.seo.ogDescription,
ogImage: data.seo.ogImage,
},
},
}
: undefined,
},
include: {
category: true,
seo: true,
},
});
return res
.status(200)
.json({ success: true, message: "Package updated", data: updated });
} catch (error) {
console.error(error);
return res.status(500).json({ success: false, message: "Update failed" });
}
};
export const deletePackage = async (req, res) => {
try {
const { id } = req.params;
await prisma.healthPackage.delete({
where: { id: Number(id) },
});
return res.status(200).json({
success: true,
message: "Package deleted",
});
} catch (error) {
console.error(error);
return res.status(500).json({
success: false,
message: "Delete failed",
});
}
};
export const createPackageInquiry = async (req, res) => {
try {
const {
fullName,
mobileNumber,
email,
age,
gender,
preferredDate,
packageId,
message,
} = req.body;
const inquiry = await prisma.healthPackageInquiry.create({
data: {
fullName,
mobileNumber,
email,
age: age ? Number(age) : null,
gender,
preferredDate: preferredDate ? new Date(preferredDate) : null,
message,
packageId: Number(packageId),
},
include: {
healthPackage: true,
},
});
try {
const emailList = await getEmailsByType("HCINQUIRY");
if (emailList) {
await sendEmail({
to: emailList,
subject: "New Health Checkup Package Inquiry",
html: `
<div style="font-family: Arial, sans-serif; background-color: #f4f6f8; padding: 20px;">
<div style="max-width: 600px; margin: auto; background: #ffffff; border-radius: 10px; overflow: hidden; box-shadow: 0 4px 10px rgba(0,0,0,0.05);">
<!-- Header -->
<div style="background-color: #0d6efd; color: #ffffff; padding: 20px;">
<h2 style="margin: 0;">GG Hospital</h2>
<p style="margin: 5px 0 0; font-size: 14px;">
New Health Checkup Package Inquiry
</p>
</div>
<!-- Body -->
<div style="padding: 20px; color: #333;">
<h3 style="margin-top: 0;">Inquirer Details</h3>
<table style="width: 100%; border-collapse: collapse;">
<tr>
<td style="padding: 8px 0; width: 35%;"><b>Name:</b></td>
<td style="padding: 8px 0;">${fullName}</td>
</tr>
<tr>
<td style="padding: 8px 0;"><b>Phone:</b></td>
<td style="padding: 8px 0;">${mobileNumber}</td>
</tr>
<tr>
<td style="padding: 8px 0;"><b>Email:</b></td>
<td style="padding: 8px 0;">${email || "-"}</td>
</tr>
<tr>
<td style="padding: 8px 0;"><b>Age:</b></td>
<td style="padding: 8px 0;">${age || "-"}</td>
</tr>
<tr>
<td style="padding: 8px 0;"><b>Gender:</b></td>
<td style="padding: 8px 0;">${gender || "-"}</td>
</tr>
</table>
<h3 style="margin-top: 20px;">Package Details</h3>
<table style="width: 100%; border-collapse: collapse;">
<tr>
<td style="padding: 8px 0; width: 35%;"><b>Package Name:</b></td>
<td style="padding: 8px 0;">${inquiry.healthPackage?.name || "Unknown Package"}</td>
</tr>
<tr>
<td style="padding: 8px 0;"><b>Preferred Date:</b></td>
<td style="padding: 8px 0;">
${
preferredDate
? new Date(preferredDate).toLocaleDateString("en-GB", {
day: "2-digit",
month: "long",
year: "numeric",
})
: "Not specified"
}
</td>
</tr>
</table>
<!-- Message Box -->
<div style="margin-top: 20px;">
<h3>Message</h3>
<div style="
background: #f8f9fa;
padding: 15px;
border-radius: 6px;
line-height: 1.6;
white-space: pre-wrap;
word-break: break-word;
overflow-wrap: anywhere;
">
${message ? message.replace(/\n/g, "<br/>") : "-"}
</div>
</div>
</div>
<!-- Footer -->
<div style="background: #f1f1f1; padding: 15px; text-align: center; font-size: 12px; color: #666;">
This inquiry was submitted via the GG Hospital website.
</div>
</div>
</div>
`,
});
}
} catch (err) {
console.error("Email failed:", err);
}
return res.status(201).json({
success: true,
message: "Booking inquiry sent successfully",
data: inquiry,
});
} catch (error) {
console.error(error);
return res
.status(500)
.json({ success: false, message: "Failed to submit inquiry" });
}
};
export const getPackageBySlug = async (req, res) => {
try {
const { slug } = req.params;
const healthPackage = await prisma.healthPackage.findFirst({
where: { slug, isActive: true },
include: {
category: true,
seo: true,
},
});
if (!healthPackage) {
return res
.status(404)
.json({ success: false, message: "Package not found" });
}
return res.status(200).json({
success: true,
data: healthPackage,
});
} catch (error) {
console.error(error);
return res
.status(500)
.json({ success: false, message: "Failed to fetch package" });
}
};
export const getAllInquiries = async (req, res) => {
try {
const { page = 1, limit = 10, filterDate, startDate, endDate } = req.query;
const queryPage = parseInt(page);
const queryLimit = parseInt(limit);
const skip = (queryPage - 1) * queryLimit;
let where = {};
if (filterDate) {
where.preferredDate = {
gte: new Date(`${filterDate}T00:00:00.000Z`),
lte: new Date(`${filterDate}T23:59:59.999Z`),
};
} else if (startDate || endDate) {
where.preferredDate = {};
if (startDate) {
where.preferredDate.gte = new Date(`${startDate}T00:00:00.000Z`);
}
if (endDate) {
where.preferredDate.lte = new Date(`${endDate}T23:59:59.999Z`);
}
}
const [total, inquiries] = await prisma.$transaction([
prisma.healthPackageInquiry.count({ where }),
prisma.healthPackageInquiry.findMany({
where,
skip,
take: queryLimit,
include: {
healthPackage: {
include: {
category: true,
},
},
},
orderBy: { createdAt: "desc" },
}),
]);
return res.status(200).json({
success: true,
data: inquiries,
pagination: {
total,
page: queryPage,
limit: queryLimit,
totalPages: Math.ceil(total / queryLimit),
},
});
} catch (error) {
console.error(error);
return res
.status(500)
.json({ success: false, message: "Failed to fetch inquiries" });
}
};