feat: facility and google review crud
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE "Facility" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"facilityId" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"slug" TEXT NOT NULL,
|
||||
"shortDescription" TEXT,
|
||||
"description" TEXT,
|
||||
"videoUrl" TEXT,
|
||||
"isActive" BOOLEAN NOT NULL DEFAULT true,
|
||||
"isFeatured" BOOLEAN NOT NULL DEFAULT false,
|
||||
"sortOrder" INTEGER NOT NULL DEFAULT 1000,
|
||||
"departmentId" INTEGER,
|
||||
"seoId" INTEGER,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "Facility_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "FacilityImage" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"url" TEXT NOT NULL,
|
||||
"altText" TEXT,
|
||||
"description" TEXT,
|
||||
"facilityId" INTEGER NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "FacilityImage_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Facility_facilityId_key" ON "Facility"("facilityId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Facility_slug_key" ON "Facility"("slug");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Facility_seoId_key" ON "Facility"("seoId");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Facility" ADD CONSTRAINT "Facility_departmentId_fkey" FOREIGN KEY ("departmentId") REFERENCES "Department"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Facility" ADD CONSTRAINT "Facility_seoId_fkey" FOREIGN KEY ("seoId") REFERENCES "Seo"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "FacilityImage" ADD CONSTRAINT "FacilityImage_facilityId_fkey" FOREIGN KEY ("facilityId") REFERENCES "Facility"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,17 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE "GoogleReview" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"reviewerName" TEXT NOT NULL,
|
||||
"reviewerImage" TEXT,
|
||||
"rating" INTEGER NOT NULL,
|
||||
"review" TEXT NOT NULL,
|
||||
"reviewDate" TIMESTAMP(3),
|
||||
"googleReviewUrl" TEXT,
|
||||
"isFeatured" BOOLEAN NOT NULL DEFAULT false,
|
||||
"isActive" BOOLEAN NOT NULL DEFAULT true,
|
||||
"sortOrder" INTEGER NOT NULL DEFAULT 1000,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "GoogleReview_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
@@ -46,12 +46,12 @@ model Department {
|
||||
name String
|
||||
image String?
|
||||
|
||||
|
||||
para1 String?
|
||||
para2 String?
|
||||
para3 String?
|
||||
facilities String?
|
||||
services String?
|
||||
facilitiesList Facility[]
|
||||
|
||||
isActive Boolean @default(true)
|
||||
sortOrder Int @default(1000)
|
||||
@@ -300,6 +300,7 @@ model Seo {
|
||||
id Int @id @default(autoincrement())
|
||||
doctor Doctor?
|
||||
healthPackage HealthPackage?
|
||||
facility Facility?
|
||||
|
||||
|
||||
seoTitle String?
|
||||
@@ -378,4 +379,61 @@ model Accreditation {
|
||||
enum AccreditationType {
|
||||
ACCREDITATION
|
||||
CERTIFICATION
|
||||
}
|
||||
|
||||
model Facility {
|
||||
id Int @id @default(autoincrement())
|
||||
facilityId String @unique
|
||||
name String
|
||||
slug String @unique
|
||||
|
||||
shortDescription String? @db.Text
|
||||
description String? @db.Text
|
||||
videoUrl String?
|
||||
|
||||
isActive Boolean @default(true)
|
||||
isFeatured Boolean @default(false)
|
||||
sortOrder Int @default(1000)
|
||||
|
||||
images FacilityImage[]
|
||||
|
||||
departmentId Int?
|
||||
department Department? @relation(fields: [departmentId], references: [id], onDelete: SetNull)
|
||||
|
||||
seoId Int? @unique
|
||||
seo Seo? @relation(fields: [seoId], references: [id], onDelete: SetNull)
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
model FacilityImage {
|
||||
id Int @id @default(autoincrement())
|
||||
url String
|
||||
altText String?
|
||||
description String?
|
||||
|
||||
facilityId Int
|
||||
facility Facility @relation(fields: [facilityId], references: [id], onDelete: Cascade)
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
}
|
||||
|
||||
model GoogleReview {
|
||||
id Int @id @default(autoincrement())
|
||||
|
||||
reviewerName String
|
||||
reviewerImage String?
|
||||
rating Int
|
||||
review String @db.Text
|
||||
reviewDate DateTime?
|
||||
googleReviewUrl String?
|
||||
|
||||
isFeatured Boolean @default(false)
|
||||
isActive Boolean @default(true)
|
||||
|
||||
sortOrder Int @default(1000)
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
@@ -19,6 +19,8 @@ import healthCheckRoutes from './routes/healthCheck.route.js';
|
||||
import homepageBannerRoutes from './routes/homepageBanner.routes.js';
|
||||
import insurancePartnerRoutes from './routes/insurancePartner.routes.js';
|
||||
import accreditationRoutes from './routes/accreditation.routes.js';
|
||||
import facilityRoutes from './routes/facility.routes.js';
|
||||
import gReviewRoutes from './routes/googleReview.routes.js';
|
||||
|
||||
dotenv.config();
|
||||
|
||||
@@ -63,6 +65,8 @@ app.use('/api/health-check', healthCheckRoutes);
|
||||
app.use('/api/homepage-banners', homepageBannerRoutes);
|
||||
app.use('/api/insurance-partners', insurancePartnerRoutes);
|
||||
app.use('/api/accreditation', accreditationRoutes);
|
||||
app.use('/api/facilities', facilityRoutes);
|
||||
app.use('/api/google-reviews', gReviewRoutes);
|
||||
|
||||
const PORT = process.env.PORT || 5008;
|
||||
app.listen(PORT, () => {
|
||||
|
||||
@@ -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' });
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,224 @@
|
||||
import prisma from '../prisma/client.js';
|
||||
|
||||
export const getFeaturedGoogleReviews = async (req, res) => {
|
||||
try {
|
||||
const reviews = await prisma.googleReview.findMany({
|
||||
where: {
|
||||
isActive: true,
|
||||
isFeatured: true,
|
||||
},
|
||||
orderBy: {
|
||||
sortOrder: 'asc',
|
||||
},
|
||||
});
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: reviews,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: 'Failed to fetch featured Google reviews',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const createGoogleReview = async (req, res) => {
|
||||
try {
|
||||
const {
|
||||
reviewerName,
|
||||
reviewerImage,
|
||||
rating,
|
||||
review,
|
||||
reviewDate,
|
||||
googleReviewUrl,
|
||||
isFeatured,
|
||||
isActive,
|
||||
sortOrder,
|
||||
} = req.body;
|
||||
|
||||
if (!reviewerName || !rating || !review) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: 'Reviewer name, rating and review are required.',
|
||||
});
|
||||
}
|
||||
|
||||
const googleReview = await prisma.googleReview.create({
|
||||
data: {
|
||||
reviewerName,
|
||||
reviewerImage,
|
||||
rating: Number(rating),
|
||||
review,
|
||||
reviewDate: reviewDate ? new Date(reviewDate) : null,
|
||||
googleReviewUrl,
|
||||
isFeatured,
|
||||
isActive,
|
||||
sortOrder,
|
||||
},
|
||||
});
|
||||
|
||||
res.status(201).json({
|
||||
success: true,
|
||||
data: googleReview,
|
||||
message: 'Google review created successfully',
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: 'Failed to create Google review',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const getGoogleReviews = async (req, res) => {
|
||||
try {
|
||||
const reviews = await prisma.googleReview.findMany({
|
||||
orderBy: {
|
||||
sortOrder: 'asc',
|
||||
},
|
||||
});
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: reviews,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: 'Failed to fetch Google reviews',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const getActiveGoogleReviews = async (req, res) => {
|
||||
try {
|
||||
const reviews = await prisma.googleReview.findMany({
|
||||
where: {
|
||||
isActive: true,
|
||||
},
|
||||
orderBy: {
|
||||
sortOrder: 'asc',
|
||||
},
|
||||
});
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: reviews,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: 'Failed to fetch active Google reviews',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const getGoogleReview = async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
const review = await prisma.googleReview.findUnique({
|
||||
where: {
|
||||
id: Number(id),
|
||||
},
|
||||
});
|
||||
|
||||
if (!review) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: 'Google review not found',
|
||||
});
|
||||
}
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: review,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: 'Failed to fetch Google review',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const updateGoogleReview = async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
const {
|
||||
reviewerName,
|
||||
reviewerImage,
|
||||
rating,
|
||||
review,
|
||||
reviewDate,
|
||||
googleReviewUrl,
|
||||
isFeatured,
|
||||
isActive,
|
||||
sortOrder,
|
||||
} = req.body;
|
||||
|
||||
const dataToUpdate = {};
|
||||
|
||||
if (reviewerName !== undefined) dataToUpdate.reviewerName = reviewerName;
|
||||
if (reviewerImage !== undefined) dataToUpdate.reviewerImage = reviewerImage;
|
||||
if (rating !== undefined) dataToUpdate.rating = Number(rating);
|
||||
if (review !== undefined) dataToUpdate.review = review;
|
||||
if (reviewDate !== undefined) {
|
||||
dataToUpdate.reviewDate = reviewDate ? new Date(reviewDate) : null;
|
||||
}
|
||||
if (googleReviewUrl !== undefined) dataToUpdate.googleReviewUrl = googleReviewUrl;
|
||||
if (isFeatured !== undefined) dataToUpdate.isFeatured = isFeatured;
|
||||
if (isActive !== undefined) dataToUpdate.isActive = isActive;
|
||||
if (sortOrder !== undefined) dataToUpdate.sortOrder = sortOrder;
|
||||
|
||||
const googleReview = await prisma.googleReview.update({
|
||||
where: {
|
||||
id: Number(id),
|
||||
},
|
||||
data: dataToUpdate,
|
||||
});
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: googleReview,
|
||||
message: 'Google review updated successfully',
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: 'Failed to update Google review',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const deleteGoogleReview = async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
await prisma.googleReview.delete({
|
||||
where: {
|
||||
id: Number(id),
|
||||
},
|
||||
});
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: 'Google review deleted successfully',
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: 'Failed to delete Google review',
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,23 @@
|
||||
import express from 'express';
|
||||
import {
|
||||
getAllFacilities,
|
||||
getFacilityByFacilityId,
|
||||
createFacility,
|
||||
updateFacility,
|
||||
deleteFacility,
|
||||
getFeaturedFacilities,
|
||||
} from '../controllers/facility.controller.js';
|
||||
|
||||
import jwtAuthMiddleware from '../middleware/auth.js';
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
router.get('/getAll', getAllFacilities);
|
||||
router.get('/featured', getFeaturedFacilities);
|
||||
router.get('/:facilityId', getFacilityByFacilityId);
|
||||
|
||||
router.post('/', jwtAuthMiddleware, createFacility);
|
||||
router.patch('/:facilityId/:action', jwtAuthMiddleware, updateFacility);
|
||||
router.delete('/:facilityId', jwtAuthMiddleware, deleteFacility);
|
||||
|
||||
export default router;
|
||||
@@ -0,0 +1,25 @@
|
||||
import express from 'express';
|
||||
import jwtAuthMiddleware from '../middleware/auth.js';
|
||||
|
||||
import {
|
||||
createGoogleReview,
|
||||
getGoogleReviews,
|
||||
getActiveGoogleReviews,
|
||||
getFeaturedGoogleReviews,
|
||||
getGoogleReview,
|
||||
updateGoogleReview,
|
||||
deleteGoogleReview,
|
||||
} from '../controllers/googleReview.controller.js';
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
router.get('/active', getActiveGoogleReviews);
|
||||
router.get('/featured', getFeaturedGoogleReviews);
|
||||
|
||||
router.post('/', jwtAuthMiddleware, createGoogleReview);
|
||||
router.get('/getAll', jwtAuthMiddleware, getGoogleReviews);
|
||||
router.get('/:id', jwtAuthMiddleware, getGoogleReview);
|
||||
router.put('/:id', jwtAuthMiddleware, updateGoogleReview);
|
||||
router.delete('/:id', jwtAuthMiddleware, deleteGoogleReview);
|
||||
|
||||
export default router;
|
||||
Reference in New Issue
Block a user