feat:add candidate apis
This commit is contained in:
@@ -0,0 +1,17 @@
|
|||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "Candidate" (
|
||||||
|
"id" SERIAL NOT NULL,
|
||||||
|
"fullName" TEXT NOT NULL,
|
||||||
|
"mobile" TEXT NOT NULL,
|
||||||
|
"email" TEXT NOT NULL,
|
||||||
|
"subject" TEXT NOT NULL,
|
||||||
|
"coverLetter" TEXT NOT NULL,
|
||||||
|
"careerId" INTEGER NOT NULL,
|
||||||
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||||
|
|
||||||
|
CONSTRAINT "Candidate_pkey" PRIMARY KEY ("id")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "Candidate" ADD CONSTRAINT "Candidate_careerId_fkey" FOREIGN KEY ("careerId") REFERENCES "Career"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
@@ -27,6 +27,7 @@ model Doctor {
|
|||||||
qualification String?
|
qualification String?
|
||||||
|
|
||||||
departments DoctorDepartment[]
|
departments DoctorDepartment[]
|
||||||
|
appointments Appointment[]
|
||||||
|
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
@@ -45,6 +46,7 @@ model Department {
|
|||||||
services String?
|
services String?
|
||||||
|
|
||||||
doctors DoctorDepartment[]
|
doctors DoctorDepartment[]
|
||||||
|
appointments Appointment[]
|
||||||
|
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
@@ -109,6 +111,42 @@ model Career {
|
|||||||
number String?
|
number String?
|
||||||
status String @default("new")
|
status String @default("new")
|
||||||
|
|
||||||
|
candidates Candidate[]
|
||||||
|
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
}
|
||||||
|
|
||||||
|
model Candidate {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
fullName String
|
||||||
|
mobile String
|
||||||
|
email String
|
||||||
|
subject String
|
||||||
|
coverLetter String
|
||||||
|
careerId Int
|
||||||
|
|
||||||
|
career Career @relation(fields: [careerId], references: [id])
|
||||||
|
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
}
|
||||||
|
|
||||||
|
model Appointment {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
|
||||||
|
name String
|
||||||
|
mobileNumber String
|
||||||
|
email String?
|
||||||
|
message String?
|
||||||
|
date DateTime
|
||||||
|
|
||||||
|
doctorId Int
|
||||||
|
departmentId Int
|
||||||
|
|
||||||
|
doctor Doctor @relation(fields: [doctorId], references: [id])
|
||||||
|
department Department @relation(fields: [departmentId], references: [id])
|
||||||
|
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
}
|
}
|
||||||
@@ -8,6 +8,8 @@ import blogRoutes from "./routes/blog.routes.js";
|
|||||||
import uploadRoutes from "./routes/upload.routes.js";
|
import uploadRoutes from "./routes/upload.routes.js";
|
||||||
import doctorRoutes from "./routes/doctor.routes.js";
|
import doctorRoutes from "./routes/doctor.routes.js";
|
||||||
import careerRoutes from "./routes/career.routes.js";
|
import careerRoutes from "./routes/career.routes.js";
|
||||||
|
import candidateRoutes from "./routes/candidate.routes.js";
|
||||||
|
import appointmentRoutes from "./routes/appointment.routes.js";
|
||||||
|
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
|
|
||||||
@@ -39,6 +41,8 @@ app.use("/uploads", express.static("uploads"));
|
|||||||
app.use("/api/upload", uploadRoutes);
|
app.use("/api/upload", uploadRoutes);
|
||||||
app.use("/api/doctors", doctorRoutes);
|
app.use("/api/doctors", doctorRoutes);
|
||||||
app.use("/api/careers", careerRoutes);
|
app.use("/api/careers", careerRoutes);
|
||||||
|
app.use("/api/candidates", candidateRoutes);
|
||||||
|
app.use("/api/appointments", appointmentRoutes);
|
||||||
|
|
||||||
const PORT = process.env.PORT || 3000;
|
const PORT = process.env.PORT || 3000;
|
||||||
app.listen(PORT, () => {
|
app.listen(PORT, () => {
|
||||||
|
|||||||
183
backend/src/controllers/candidate.controller.js
Normal file
183
backend/src/controllers/candidate.controller.js
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
import prisma from "../prisma/client.js";
|
||||||
|
|
||||||
|
// CREATE CANDIDATE
|
||||||
|
|
||||||
|
export const createCandidate = async (req, res) => {
|
||||||
|
try {
|
||||||
|
const {fullName, mobile, email, subject, coverLetter, careerId} = req.body;
|
||||||
|
|
||||||
|
if (!fullName || !mobile || !email || !careerId) {
|
||||||
|
return res.status(400).json({
|
||||||
|
success: false,
|
||||||
|
message: "Required fields missing",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const candidate = await prisma.candidate.create({
|
||||||
|
data: {
|
||||||
|
fullName,
|
||||||
|
mobile,
|
||||||
|
email,
|
||||||
|
subject,
|
||||||
|
coverLetter,
|
||||||
|
careerId: Number(careerId),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
res.status(201).json({
|
||||||
|
success: true,
|
||||||
|
message: "Application submitted successfully",
|
||||||
|
data: candidate,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
res.status(500).json({
|
||||||
|
success: false,
|
||||||
|
message: "Failed to create candidate",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// GET ALL CANDIDATES
|
||||||
|
|
||||||
|
export const getCandidates = async (req, res) => {
|
||||||
|
try {
|
||||||
|
const candidates = await prisma.candidate.findMany({
|
||||||
|
include: {
|
||||||
|
career: true,
|
||||||
|
},
|
||||||
|
orderBy: {
|
||||||
|
createdAt: "desc",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
res.status(200).json({
|
||||||
|
success: true,
|
||||||
|
data: candidates,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
res.status(500).json({
|
||||||
|
success: false,
|
||||||
|
message: "Failed to fetch candidates",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// GET SINGLE CANDIDATE
|
||||||
|
|
||||||
|
export const getCandidate = async (req, res) => {
|
||||||
|
try {
|
||||||
|
const {id} = req.params;
|
||||||
|
|
||||||
|
const candidate = await prisma.candidate.findUnique({
|
||||||
|
where: {
|
||||||
|
id: Number(id),
|
||||||
|
},
|
||||||
|
include: {
|
||||||
|
career: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!candidate) {
|
||||||
|
return res.status(404).json({
|
||||||
|
success: false,
|
||||||
|
message: "Candidate not found",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
res.status(200).json({
|
||||||
|
success: true,
|
||||||
|
data: candidate,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
res.status(500).json({
|
||||||
|
success: false,
|
||||||
|
message: "Failed to fetch candidate",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// GET CANDIDATES BY CAREER
|
||||||
|
|
||||||
|
export const getCandidatesByCareer = async (req, res) => {
|
||||||
|
try {
|
||||||
|
const {careerId} = req.params;
|
||||||
|
|
||||||
|
const candidates = await prisma.candidate.findMany({
|
||||||
|
where: {
|
||||||
|
careerId: Number(careerId),
|
||||||
|
},
|
||||||
|
include: {
|
||||||
|
career: true,
|
||||||
|
},
|
||||||
|
orderBy: {
|
||||||
|
createdAt: "desc",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
res.status(200).json({
|
||||||
|
success: true,
|
||||||
|
data: candidates,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
res.status(500).json({
|
||||||
|
success: false,
|
||||||
|
message: "Failed to fetch candidates",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// UPDATE CANDIDATE
|
||||||
|
|
||||||
|
export const updateCandidate = async (req, res) => {
|
||||||
|
try {
|
||||||
|
const {id} = req.params;
|
||||||
|
|
||||||
|
const candidate = await prisma.candidate.update({
|
||||||
|
where: {
|
||||||
|
id: Number(id),
|
||||||
|
},
|
||||||
|
data: req.body,
|
||||||
|
});
|
||||||
|
|
||||||
|
res.status(200).json({
|
||||||
|
success: true,
|
||||||
|
message: "Candidate updated successfully",
|
||||||
|
data: candidate,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
res.status(500).json({
|
||||||
|
success: false,
|
||||||
|
message: "Failed to update candidate",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// DELETE CANDIDATE
|
||||||
|
|
||||||
|
export const deleteCandidate = async (req, res) => {
|
||||||
|
try {
|
||||||
|
const {id} = req.params;
|
||||||
|
|
||||||
|
await prisma.candidate.delete({
|
||||||
|
where: {
|
||||||
|
id: Number(id),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
res.status(200).json({
|
||||||
|
success: true,
|
||||||
|
message: "Candidate deleted successfully",
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
res.status(500).json({
|
||||||
|
success: false,
|
||||||
|
message: "Failed to delete candidate",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
25
backend/src/routes/candidate.routes.js
Normal file
25
backend/src/routes/candidate.routes.js
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import express from "express";
|
||||||
|
import {
|
||||||
|
createCandidate,
|
||||||
|
getCandidates,
|
||||||
|
getCandidate,
|
||||||
|
getCandidatesByCareer,
|
||||||
|
updateCandidate,
|
||||||
|
deleteCandidate,
|
||||||
|
} from "../controllers/candidate.controller.js";
|
||||||
|
|
||||||
|
import jwtAuthMiddleware from "../middleware/auth.js";
|
||||||
|
|
||||||
|
const router = express.Router();
|
||||||
|
|
||||||
|
/* PUBLIC */
|
||||||
|
|
||||||
|
router.get("/getAll", getCandidates);
|
||||||
|
router.get("/:id", getCandidate);
|
||||||
|
router.get("/career/:careerId", getCandidatesByCareer);
|
||||||
|
|
||||||
|
router.post("/", createCandidate);
|
||||||
|
router.patch("/:id", updateCandidate);
|
||||||
|
router.delete("/:id", jwtAuthMiddleware, deleteCandidate);
|
||||||
|
|
||||||
|
export default router;
|
||||||
Reference in New Issue
Block a user