diff --git a/backend/prisma/migrations/20260313085241_career/migration.sql b/backend/prisma/migrations/20260313085241_career/migration.sql new file mode 100644 index 0000000..21d3f71 --- /dev/null +++ b/backend/prisma/migrations/20260313085241_career/migration.sql @@ -0,0 +1,15 @@ +-- CreateTable +CREATE TABLE "Career" ( + "id" SERIAL NOT NULL, + "post" TEXT NOT NULL, + "designation" TEXT, + "qualification" TEXT, + "experienceNeed" TEXT, + "email" TEXT, + "number" TEXT, + "status" TEXT NOT NULL DEFAULT 'new', + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "Career_pkey" PRIMARY KEY ("id") +); diff --git a/backend/prisma/schema.prisma b/backend/prisma/schema.prisma index 506ec5e..9333495 100644 --- a/backend/prisma/schema.prisma +++ b/backend/prisma/schema.prisma @@ -97,4 +97,18 @@ model Blog { createdAt DateTime @default(now()) updatedAt DateTime @updatedAt +} + +model Career { + id Int @id @default(autoincrement()) + post String + designation String? + qualification String? + experienceNeed String? + email String? + number String? + status String @default("new") + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt } \ No newline at end of file diff --git a/backend/src/app.js b/backend/src/app.js index ba01c32..cdd12e1 100644 --- a/backend/src/app.js +++ b/backend/src/app.js @@ -6,6 +6,8 @@ import departmentRoutes from "./routes/department.routes.js"; import authRoutes from "./routes/auth.routes.js"; import blogRoutes from "./routes/blog.routes.js"; import uploadRoutes from "./routes/upload.routes.js"; +import doctorRoutes from "./routes/doctor.routes.js"; +import careerRoutes from "./routes/career.routes.js"; dotenv.config(); @@ -35,6 +37,8 @@ app.use("/api/auth", authRoutes); app.use("/api/blogs", blogRoutes); app.use("/uploads", express.static("uploads")); app.use("/api/upload", uploadRoutes); +app.use("/api/doctors", doctorRoutes); +app.use("/api/careers", careerRoutes); const PORT = process.env.PORT || 3000; app.listen(PORT, () => { diff --git a/backend/src/controllers/career.controller.js b/backend/src/controllers/career.controller.js new file mode 100644 index 0000000..2b365de --- /dev/null +++ b/backend/src/controllers/career.controller.js @@ -0,0 +1,128 @@ +import prisma from "../prisma/client.js"; + +// GET ALL CAREERS + +export const getAllCareers = async (req, res) => { + try { + const careers = await prisma.career.findMany({ + orderBy: {createdAt: "desc"}, + }); + + const response = careers.map((c) => ({ + id: c.id, + post: c.post, + designation: c.designation, + qualification: c.qualification, + experienceNeed: c.experienceNeed, + email: c.email, + number: c.number, + status: c.status, + })); + + return res.status(200).json({ + success: true, + data: response, + }); + } catch (error) { + console.error(error); + return res.status(500).json({ + success: false, + message: "Failed to fetch careers", + }); + } +}; + +// CREATE CAREER + +export const createCareer = async (req, res) => { + try { + const { + post, + designation, + qualification, + experienceNeed, + email, + number, + status, + } = req.body; + + if (!post || !designation) { + return res.status(400).json({ + success: false, + message: "Post and designation are required", + }); + } + + const career = await prisma.career.create({ + data: { + post, + designation, + qualification, + experienceNeed, + email, + number, + status, + }, + }); + + return res.status(201).json({ + success: true, + message: "Career created successfully", + data: career, + }); + } catch (error) { + console.error(error); + return res.status(500).json({ + success: false, + message: "Failed to create career", + }); + } +}; + +// UPDATE CAREER (PATCH) + +export const updateCareer = async (req, res) => { + try { + const {id} = req.params; + + const career = await prisma.career.update({ + where: {id: Number(id)}, + data: req.body, + }); + + return res.status(200).json({ + success: true, + message: "Career updated successfully", + data: career, + }); + } catch (error) { + console.error(error); + return res.status(500).json({ + success: false, + message: "Failed to update career", + }); + } +}; + +// DELETE CAREER + +export const deleteCareer = async (req, res) => { + try { + const {id} = req.params; + + await prisma.career.delete({ + where: {id: Number(id)}, + }); + + return res.status(200).json({ + success: true, + message: "Career deleted successfully", + }); + } catch (error) { + console.error(error); + return res.status(500).json({ + success: false, + message: "Failed to delete career", + }); + } +}; diff --git a/backend/src/controllers/department.controller.js b/backend/src/controllers/department.controller.js index f06f916..4007ddd 100644 --- a/backend/src/controllers/department.controller.js +++ b/backend/src/controllers/department.controller.js @@ -64,3 +64,54 @@ export async function createDepartment(req, res) { res.status(500).json({error: "Failed to create department"}); } } + +export const updateDepartment = async (req, res) => { + try { + const {id} = req.params; + + const {name, para1, para2, para3, facilities, services} = req.body; + + const department = await prisma.department.update({ + where: {id: Number(id)}, + data: { + name, + para1, + para2, + para3, + facilities, + services, + }, + }); + + return res.status(200).json({ + success: true, + message: "Department updated successfully", + data: department, + }); + } catch (error) { + console.error(error); + return res + .status(500) + .json({success: false, message: "Failed to update department"}); + } +}; + +export const deleteDepartment = async (req, res) => { + try { + const {id} = req.params; + + await prisma.department.delete({ + where: {id: Number(id)}, + }); + + return res.status(200).json({ + success: true, + message: "Department deleted successfully", + }); + } catch (error) { + console.error(error); + return res + .status(500) + .json({success: false, message: "Failed to delete department"}); + } +}; diff --git a/backend/src/controllers/doctor.controller.js b/backend/src/controllers/doctor.controller.js new file mode 100644 index 0000000..fbf8484 --- /dev/null +++ b/backend/src/controllers/doctor.controller.js @@ -0,0 +1,449 @@ +import prisma from "../prisma/client.js"; + +// get doctors + +export const getAllDoctors = async (req, res) => { + try { + const doctors = await prisma.doctor.findMany({ + include: { + departments: { + include: { + department: true, + timing: true, + }, + }, + }, + orderBy: {name: "asc"}, + }); + + const formatted = doctors.map((doc, index) => { + const departmentIds = doc.departments.map( + (d) => d.department.departmentId, + ); + + let timings = []; + + doc.departments.forEach((d) => { + const t = d.timing; + + if (!t) return; + + if (t.monday) timings.push(`Monday ${t.monday}`); + if (t.tuesday) timings.push(`Tuesday ${t.tuesday}`); + if (t.wednesday) timings.push(`Wednesday ${t.wednesday}`); + if (t.thursday) timings.push(`Thursday ${t.thursday}`); + if (t.friday) timings.push(`Friday ${t.friday}`); + if (t.saturday) timings.push(`Saturday ${t.saturday}`); + if (t.sunday) timings.push(`Sunday ${t.sunday}`); + + if (t.additional) timings.push(t.additional); + }); + + return { + SL_NO: String(index + 1), + Doctor_ID: doc.doctorId, + Department_ID: departmentIds, + Name: doc.name, + Designation: doc.designation, + "Working Status": doc.workingStatus, + Qualification: doc.qualification, + Timing: timings.join(" & "), + }; + }); + + res.status(200).json({ + success: true, + data: formatted, + }); + } catch (error) { + console.error(error); + res.status(500).json({ + success: false, + message: "Failed to fetch doctors", + }); + } +}; + +// get doctor by id + +export const getDoctorByDoctorId = async (req, res) => { + try { + const {doctorId} = req.params; + + const doctor = await prisma.doctor.findUnique({ + where: {doctorId}, + include: { + departments: { + include: { + department: true, + timing: true, + }, + }, + }, + }); + + if (!doctor) { + return res.status(404).json({ + success: false, + message: "Doctor not found", + }); + } + + const departments = doctor.departments.map( + (d) => d.department.departmentId, + ); + + const timing = doctor.departments[0]?.timing ?? {}; + + const response = { + doctorId: doctor.doctorId, + name: doctor.name, + designation: doctor.designation, + workingStatus: doctor.workingStatus, + qualification: doctor.qualification, + departments, + timing: { + monday: timing?.monday ?? "", + tuesday: timing?.tuesday ?? "", + wednesday: timing?.wednesday ?? "", + thursday: timing?.thursday ?? "", + friday: timing?.friday ?? "", + saturday: timing?.saturday ?? "", + sunday: timing?.sunday ?? "", + additional: timing?.additional ?? "", + }, + }; + + res.status(200).json({ + success: true, + data: response, + }); + } catch (error) { + console.error(error); + res.status(500).json({ + success: false, + message: "Failed to fetch doctor", + }); + } +}; + +// add doctors +export const createDoctor = async (req, res) => { + try { + const { + doctorId, + name, + designation, + workingStatus, + qualification, + departments, + timing, + } = req.body; + + const doctor = await prisma.doctor.create({ + data: { + doctorId, + name, + designation, + workingStatus, + qualification, + }, + }); + + for (const depId of departments) { + const department = await prisma.department.findUnique({ + where: {departmentId: depId}, + }); + + const doctorDepartment = await prisma.doctorDepartment.create({ + data: { + doctorId: doctor.id, + departmentId: department.id, + }, + }); + + if (timing) { + await prisma.doctorTiming.create({ + data: { + doctorDepartmentId: doctorDepartment.id, + ...timing, + }, + }); + } + } + + res.status(201).json({ + success: true, + message: "Doctor created successfully", + }); + } catch (error) { + console.error(error); + res.status(500).json({ + success: false, + message: "Failed to create doctor", + }); + } +}; + +//update doctors +export const updateDoctor = async (req, res) => { + try { + const {doctorId} = req.params; + const { + name, + designation, + workingStatus, + qualification, + departments, + timing, + } = req.body; + + if (!doctorId) { + return res.status(400).json({ + success: false, + message: "Doctor ID is required", + }); + } + + const doctor = await prisma.doctor.findUnique({ + where: {doctorId}, + }); + + if (!doctor) { + return res.status(404).json({ + success: false, + message: `Doctor with ID ${doctorId} not found`, + }); + } + + const updatedDoctor = await prisma.doctor.update({ + where: {id: doctor.id}, + data: { + ...(name && {name}), + ...(designation && {designation}), + ...(workingStatus && {workingStatus}), + ...(qualification && {qualification}), + }, + }); + + if (departments) { + const doctorDepartments = await prisma.doctorDepartment.findMany({ + where: {doctorId: doctor.id}, + }); + + for (const dd of doctorDepartments) { + await prisma.doctorTiming.deleteMany({ + where: {doctorDepartmentId: dd.id}, + }); + } + + await prisma.doctorDepartment.deleteMany({ + where: {doctorId: doctor.id}, + }); + + for (const depId of departments) { + const department = await prisma.department.findUnique({ + where: {departmentId: depId}, + }); + if (!department) continue; + + const doctorDepartment = await prisma.doctorDepartment.create({ + data: { + doctorId: doctor.id, + departmentId: department.id, + }, + }); + + if (timing) { + await prisma.doctorTiming.create({ + data: { + doctorDepartmentId: doctorDepartment.id, + ...timing, + }, + }); + } + } + } else if (timing) { + const doctorDepartments = await prisma.doctorDepartment.findMany({ + where: {doctorId: doctor.id}, + }); + + for (const dd of doctorDepartments) { + await prisma.doctorTiming.upsert({ + where: {doctorDepartmentId: dd.id}, + update: {...timing}, + create: {doctorDepartmentId: dd.id, ...timing}, + }); + } + } + + res.status(200).json({ + success: true, + message: `Doctor ${doctorId} updated successfully`, + data: updatedDoctor, + }); + } catch (error) { + console.error(error); + res.status(500).json({ + success: false, + message: "Failed to update doctor", + }); + } +}; +//delete doctor + +export const deleteDoctor = async (req, res) => { + try { + const {doctorId} = req.params; + + if (!doctorId) { + return res.status(400).json({ + success: false, + message: "Doctor ID is required", + }); + } + + const doctor = await prisma.doctor.findUnique({ + where: {doctorId}, + }); + + if (!doctor) { + return res.status(404).json({ + success: false, + message: `Doctor with ID ${doctorId} not found`, + }); + } + + const doctorDepartments = await prisma.doctorDepartment.findMany({ + where: {doctorId: doctor.id}, + }); + + for (const dd of doctorDepartments) { + await prisma.doctorTiming.deleteMany({ + where: {doctorDepartmentId: dd.id}, + }); + } + + await prisma.doctorDepartment.deleteMany({ + where: {doctorId: doctor.id}, + }); + + await prisma.doctor.delete({ + where: {id: doctor.id}, + }); + + res.status(200).json({ + success: true, + message: `Doctor ${doctorId} deleted successfully`, + }); + } catch (error) { + console.error(error); + res.status(500).json({ + success: false, + message: "Failed to delete doctor", + }); + } +}; + +// get doctor timings + +export const getDoctorTimings = async (req, res) => { + try { + const doctors = await prisma.doctor.findMany({ + include: { + departments: { + include: { + timing: true, + }, + }, + }, + }); + + const result = doctors.map((doc) => { + let timing = {}; + + if (doc.departments.length > 0) { + timing = doc.departments[0].timing ?? {}; + } + + return { + Doctor_ID: doc.doctorId, + Doctor: doc.name, + Monday: timing?.monday ?? "", + Tuesday: timing?.tuesday ?? "", + Wednesday: timing?.wednesday ?? "", + Thursday: timing?.thursday ?? "", + Friday: timing?.friday ?? "", + Saturday: timing?.saturday ?? "", + Sunday: timing?.sunday ?? "", + Additional: timing?.additional ?? "", + }; + }); + + res.status(200).json({ + success: true, + data: result, + }); + } catch (error) { + console.error(error); + res.status(500).json({ + success: false, + message: "Failed to fetch doctor timings", + }); + } +}; +// get doctor timings by id + +export const getDoctorTimingById = async (req, res) => { + try { + const {doctorId} = req.params; + + const doctor = await prisma.doctor.findUnique({ + where: {doctorId}, + include: { + departments: { + include: { + timing: true, + }, + }, + }, + }); + + if (!doctor) { + return res.status(404).json({ + success: false, + message: "Doctor not found", + }); + } + + let timing = {}; + + if (doctor.departments.length > 0) { + timing = doctor.departments[0].timing ?? {}; + } + + const result = { + Doctor_ID: doctor.doctorId, + Doctor: doctor.name, + Monday: timing?.monday ?? "", + Tuesday: timing?.tuesday ?? "", + Wednesday: timing?.wednesday ?? "", + Thursday: timing?.thursday ?? "", + Friday: timing?.friday ?? "", + Saturday: timing?.saturday ?? "", + Sunday: timing?.sunday ?? "", + Additional: timing?.additional ?? "", + }; + + res.status(200).json({ + success: true, + data: result, + }); + } catch (error) { + console.error(error); + res.status(500).json({ + success: false, + message: "Failed to fetch doctor timing", + }); + } +}; diff --git a/backend/src/routes/career.routes.js b/backend/src/routes/career.routes.js new file mode 100644 index 0000000..b85346b --- /dev/null +++ b/backend/src/routes/career.routes.js @@ -0,0 +1,17 @@ +import express from "express"; +import { + getAllCareers, + createCareer, + updateCareer, + deleteCareer, +} from "../controllers/career.controller.js"; + +const router = express.Router(); + +router.get("/getAll", getAllCareers); + +router.post("/", createCareer); +router.patch("/:id", updateCareer); +router.delete("/:id", deleteCareer); + +export default router; diff --git a/backend/src/routes/department.routes.js b/backend/src/routes/department.routes.js index ae84d2d..6c0d5bc 100644 --- a/backend/src/routes/department.routes.js +++ b/backend/src/routes/department.routes.js @@ -2,6 +2,8 @@ import express from "express"; import { getAllDepartments, createDepartment, + updateDepartment, + deleteDepartment, } from "../controllers/department.controller.js"; import jwtAuthMiddleware from "../middleware/auth.js"; @@ -12,5 +14,7 @@ router.get("/getAll", getAllDepartments); // Protected router.post("/", jwtAuthMiddleware, createDepartment); +router.put("/:id", jwtAuthMiddleware, updateDepartment); +router.delete("/:id", jwtAuthMiddleware, deleteDepartment); export default router; diff --git a/backend/src/routes/doctor.routes.js b/backend/src/routes/doctor.routes.js new file mode 100644 index 0000000..c91db2c --- /dev/null +++ b/backend/src/routes/doctor.routes.js @@ -0,0 +1,25 @@ +import express from "express"; +import { + getAllDoctors, + createDoctor, + updateDoctor, + deleteDoctor, + getDoctorTimings, + getDoctorTimingById, + getDoctorByDoctorId, +} from "../controllers/doctor.controller.js"; + +import jwtAuthMiddleware from "../middleware/auth.js"; + +const router = express.Router(); + +router.get("/getAll", getAllDoctors); +router.get("/:doctorId", getDoctorByDoctorId); +router.get("/getTimings", getDoctorTimings); +router.get("/getTimings/:doctorId", getDoctorTimingById); + +router.post("/", jwtAuthMiddleware, createDoctor); +router.patch("/:doctorId", jwtAuthMiddleware, updateDoctor); +router.delete("/:doctorId", jwtAuthMiddleware, deleteDoctor); + +export default router;