feat: facility and google review crud
This commit is contained in:
@@ -0,0 +1,421 @@
|
||||
import prisma from '../prisma/client.js';
|
||||
|
||||
export const getAllFacilities = async (req, res) => {
|
||||
try {
|
||||
const { admin } = req.query;
|
||||
|
||||
const facilities = await prisma.facility.findMany({
|
||||
where: admin === 'true' ? {} : { isActive: true },
|
||||
include: {
|
||||
seo: true,
|
||||
department: true,
|
||||
images: true,
|
||||
},
|
||||
orderBy: [{ sortOrder: 'asc' }, { name: 'asc' }],
|
||||
});
|
||||
|
||||
const formatted = facilities.map((fac, index) => ({
|
||||
SL_NO: String(index + 1),
|
||||
id: fac.id,
|
||||
facilityId: fac.facilityId,
|
||||
name: fac.name,
|
||||
slug: fac.slug,
|
||||
shortDescription: fac.shortDescription,
|
||||
description: fac.description,
|
||||
videoUrl: fac.videoUrl ?? '',
|
||||
isActive: fac.isActive,
|
||||
isFeatured: fac.isFeatured,
|
||||
sortOrder: fac.sortOrder,
|
||||
department: fac.department
|
||||
? {
|
||||
id: fac.department.id,
|
||||
departmentId: fac.department.departmentId,
|
||||
name: fac.department.name,
|
||||
}
|
||||
: null,
|
||||
images: fac.images.map((img) => ({
|
||||
id: img.id,
|
||||
url: img.url,
|
||||
altText: img.altText ?? '',
|
||||
description: img.description ?? '',
|
||||
})),
|
||||
seo: {
|
||||
seoTitle: fac.seo?.seoTitle ?? '',
|
||||
metaDescription: fac.seo?.metaDescription ?? '',
|
||||
focusKeyphrase: fac.seo?.focusKeyphrase ?? '',
|
||||
slug: fac.seo?.slug ?? '',
|
||||
tags: fac.seo?.tags ?? [],
|
||||
ogTitle: fac.seo?.ogTitle ?? '',
|
||||
ogDescription: fac.seo?.ogDescription ?? '',
|
||||
ogImage: fac.seo?.ogImage ?? '',
|
||||
},
|
||||
}));
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
data: formatted,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: 'Failed to fetch facilities',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const getFacilityByFacilityId = async (req, res) => {
|
||||
try {
|
||||
const { facilityId } = req.params;
|
||||
const { admin } = req.query;
|
||||
|
||||
const facility = await prisma.facility.findFirst({
|
||||
where: {
|
||||
facilityId,
|
||||
...(admin === 'true' ? {} : { isActive: true }),
|
||||
},
|
||||
include: {
|
||||
seo: true,
|
||||
department: true,
|
||||
images: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!facility) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: 'Facility not found',
|
||||
});
|
||||
}
|
||||
|
||||
const response = {
|
||||
facilityId: facility.facilityId,
|
||||
name: facility.name,
|
||||
slug: facility.slug,
|
||||
shortDescription: facility.shortDescription,
|
||||
description: facility.description,
|
||||
videoUrl: facility.videoUrl ?? '',
|
||||
isActive: facility.isActive,
|
||||
isFeatured: facility.isFeatured,
|
||||
sortOrder: facility.sortOrder,
|
||||
department: facility.department
|
||||
? {
|
||||
departmentId: facility.department.departmentId,
|
||||
name: facility.department.name,
|
||||
}
|
||||
: null,
|
||||
images: facility.images.map((img) => ({
|
||||
id: img.id,
|
||||
url: img.url,
|
||||
altText: img.altText ?? '',
|
||||
description: img.description ?? '',
|
||||
})),
|
||||
seo: {
|
||||
seoTitle: facility.seo?.seoTitle ?? '',
|
||||
metaDescription: facility.seo?.metaDescription ?? '',
|
||||
focusKeyphrase: facility.seo?.focusKeyphrase ?? '',
|
||||
slug: facility.seo?.slug ?? '',
|
||||
tags: facility.seo?.tags ?? [],
|
||||
ogTitle: facility.seo?.ogTitle ?? '',
|
||||
ogDescription: facility.seo?.ogDescription ?? '',
|
||||
ogImage: facility.seo?.ogImage ?? '',
|
||||
},
|
||||
};
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
data: response,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: 'Failed to fetch facility',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const createFacility = async (req, res) => {
|
||||
try {
|
||||
const {
|
||||
facilityId,
|
||||
name,
|
||||
slug,
|
||||
shortDescription,
|
||||
description,
|
||||
videoUrl,
|
||||
isActive,
|
||||
isFeatured,
|
||||
sortOrder,
|
||||
departmentId,
|
||||
images,
|
||||
seoTitle,
|
||||
metaDescription,
|
||||
focusKeyphrase,
|
||||
tags,
|
||||
ogTitle,
|
||||
ogDescription,
|
||||
ogImage,
|
||||
} = req.body;
|
||||
|
||||
const messages = [];
|
||||
if (!facilityId) messages.push('Facility ID is required');
|
||||
if (!name?.trim()) messages.push('Facility name is required');
|
||||
if (!slug?.trim()) messages.push('Slug is required');
|
||||
|
||||
if (messages.length > 0) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: messages.join(', '),
|
||||
});
|
||||
}
|
||||
|
||||
let dbDepartmentId = null;
|
||||
if (departmentId) {
|
||||
const targetDept = await prisma.department.findUnique({
|
||||
where: { departmentId: departmentId },
|
||||
});
|
||||
if (targetDept) {
|
||||
dbDepartmentId = targetDept.id;
|
||||
}
|
||||
}
|
||||
|
||||
const seo = await prisma.seo.create({
|
||||
data: {
|
||||
seoTitle,
|
||||
metaDescription,
|
||||
focusKeyphrase,
|
||||
slug: slug ? slug : null,
|
||||
tags: tags || [],
|
||||
ogTitle,
|
||||
ogDescription,
|
||||
ogImage,
|
||||
},
|
||||
});
|
||||
|
||||
const facility = await prisma.facility.create({
|
||||
data: {
|
||||
facilityId,
|
||||
name,
|
||||
slug,
|
||||
shortDescription,
|
||||
description,
|
||||
videoUrl,
|
||||
isActive: isActive !== undefined ? isActive : true,
|
||||
isFeatured: isFeatured !== undefined ? isFeatured : false,
|
||||
sortOrder: sortOrder !== undefined ? Number(sortOrder) : 1000,
|
||||
departmentId: dbDepartmentId,
|
||||
seoId: seo.id,
|
||||
},
|
||||
});
|
||||
|
||||
if (images && images.length > 0) {
|
||||
await prisma.facilityImage.createMany({
|
||||
data: images.map((img) => ({
|
||||
url: img.url,
|
||||
altText: img.altText || null,
|
||||
description: img.description || null,
|
||||
facilityId: facility.id,
|
||||
})),
|
||||
});
|
||||
}
|
||||
|
||||
res.status(201).json({
|
||||
success: true,
|
||||
message: 'Facility created successfully',
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: 'Failed to create facility',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const updateFacility = async (req, res) => {
|
||||
try {
|
||||
const { facilityId, action } = req.params;
|
||||
const {
|
||||
name,
|
||||
slug,
|
||||
shortDescription,
|
||||
description,
|
||||
videoUrl,
|
||||
isActive,
|
||||
isFeatured,
|
||||
sortOrder,
|
||||
departmentId,
|
||||
images,
|
||||
seoTitle,
|
||||
metaDescription,
|
||||
focusKeyphrase,
|
||||
tags,
|
||||
ogTitle,
|
||||
ogDescription,
|
||||
ogImage,
|
||||
} = req.body;
|
||||
|
||||
if (!facilityId) {
|
||||
return res.status(400).json({ success: false, message: 'Facility ID is required' });
|
||||
}
|
||||
|
||||
const facility = await prisma.facility.findUnique({ where: { facilityId } });
|
||||
if (!facility) return res.status(404).json({ success: false, message: 'Facility not found' });
|
||||
|
||||
if (action === 'toggleStatus') {
|
||||
await prisma.facility.update({
|
||||
where: { id: facility.id },
|
||||
data: { isActive: !facility.isActive },
|
||||
});
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
message: `Facility has been ${facility.isActive ? 'deactivated' : 'activated'} successfully`,
|
||||
});
|
||||
}
|
||||
|
||||
if (action === 'toggleFeatured') {
|
||||
await prisma.facility.update({
|
||||
where: { id: facility.id },
|
||||
data: { isFeatured: !facility.isFeatured },
|
||||
});
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
message: `Facility has been ${facility.isFeatured ? 'removed from featured' : 'marked as featured'} successfully`,
|
||||
});
|
||||
}
|
||||
|
||||
const messages = [];
|
||||
if (!name?.trim()) messages.push('Facility name is required');
|
||||
if (!slug?.trim()) messages.push('Slug is required');
|
||||
|
||||
if (messages.length > 0) {
|
||||
return res.status(400).json({ success: false, message: messages.join(', ') });
|
||||
}
|
||||
|
||||
let dbDepartmentId = undefined;
|
||||
if (departmentId !== undefined) {
|
||||
if (departmentId) {
|
||||
const targetDept = await prisma.department.findUnique({
|
||||
where: { departmentId: departmentId },
|
||||
});
|
||||
dbDepartmentId = targetDept ? targetDept.id : null;
|
||||
} else {
|
||||
dbDepartmentId = null;
|
||||
}
|
||||
}
|
||||
|
||||
await prisma.facility.update({
|
||||
where: { id: facility.id },
|
||||
data: {
|
||||
name,
|
||||
slug,
|
||||
shortDescription,
|
||||
description,
|
||||
videoUrl,
|
||||
isActive: isActive !== undefined ? isActive : undefined,
|
||||
isFeatured: isFeatured !== undefined ? isFeatured : undefined,
|
||||
sortOrder: sortOrder !== undefined ? Number(sortOrder) : undefined,
|
||||
departmentId: dbDepartmentId,
|
||||
},
|
||||
});
|
||||
|
||||
if (facility.seoId) {
|
||||
await prisma.seo.update({
|
||||
where: { id: facility.seoId },
|
||||
data: {
|
||||
seoTitle,
|
||||
metaDescription,
|
||||
focusKeyphrase,
|
||||
slug: slug ? slug : null,
|
||||
tags: tags || [],
|
||||
ogTitle,
|
||||
ogDescription,
|
||||
ogImage,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
const seo = await prisma.seo.create({
|
||||
data: {
|
||||
seoTitle,
|
||||
metaDescription,
|
||||
focusKeyphrase,
|
||||
slug: slug ? slug : null,
|
||||
tags: tags || [],
|
||||
ogTitle,
|
||||
ogDescription,
|
||||
ogImage,
|
||||
},
|
||||
});
|
||||
await prisma.facility.update({ where: { id: facility.id }, data: { seoId: seo.id } });
|
||||
}
|
||||
|
||||
if (Array.isArray(images)) {
|
||||
await prisma.facilityImage.deleteMany({ where: { facilityId: facility.id } });
|
||||
if (images.length > 0) {
|
||||
await prisma.facilityImage.createMany({
|
||||
data: images.map((img) => ({
|
||||
url: img.url,
|
||||
altText: img.altText || null,
|
||||
description: img.description || null,
|
||||
facilityId: facility.id,
|
||||
})),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
res.status(200).json({ success: true, message: 'Facility updated successfully' });
|
||||
} catch (error) {
|
||||
console.error('Update Error:', error);
|
||||
res.status(500).json({ success: false, message: 'Failed to update facility' });
|
||||
}
|
||||
};
|
||||
|
||||
export const deleteFacility = async (req, res) => {
|
||||
try {
|
||||
const { facilityId } = req.params;
|
||||
|
||||
const facility = await prisma.facility.findUnique({ where: { facilityId } });
|
||||
if (!facility) {
|
||||
return res.status(404).json({ success: false, message: 'Facility not found' });
|
||||
}
|
||||
|
||||
await prisma.facilityImage.deleteMany({ where: { facilityId: facility.id } });
|
||||
await prisma.facility.delete({ where: { id: facility.id } });
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
message: 'Facility deleted successfully',
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).json({ success: false, message: 'Failed to delete facility' });
|
||||
}
|
||||
};
|
||||
|
||||
export const getFeaturedFacilities = async (req, res) => {
|
||||
try {
|
||||
const facilities = await prisma.facility.findMany({
|
||||
where: { isActive: true, isFeatured: true },
|
||||
include: {
|
||||
images: true,
|
||||
department: true,
|
||||
},
|
||||
orderBy: [{ sortOrder: 'asc' }, { name: 'asc' }],
|
||||
});
|
||||
|
||||
const data = facilities.map((fac) => ({
|
||||
facilityId: fac.facilityId,
|
||||
name: fac.name,
|
||||
slug: fac.slug,
|
||||
shortDescription: fac.shortDescription,
|
||||
image: fac.images[0]?.url ?? '',
|
||||
departmentName: fac.department?.name ?? '',
|
||||
}));
|
||||
|
||||
res.status(200).json({ success: true, data });
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).json({ success: false, message: 'Failed to fetch featured facilities' });
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user