From e22727eefdece68cd45568021d61c18bfcf62028 Mon Sep 17 00:00:00 2001
From: Harshitha Shetty <141444342+HarshithaShetty27@users.noreply.github.com>
Date: Mon, 9 Dec 2024 05:06:08 +0530
Subject: [PATCH] Added backend and integration for FilterPage and CourseTable
done
---
client/src/App.js | 2 +
client/src/Pages/CourseForm.css | 136 +++++++++++++----------
client/src/Pages/CourseForm.jsx | 173 +++++++++++++++++++++++++++--
client/src/Pages/CourseTable.css | 111 ++++++++++++++++++
client/src/Pages/CourseTable.jsx | 89 +++++++++++++++
client/src/Pages/FilterPage.jsx | 104 +++++++++++------
client/src/api.js | 28 +++++
server/models/Appointment.js | 11 ++
server/models/Course.js | 13 +++
server/models/Faculty.js | 11 ++
server/package-lock.json | 36 +++++-
server/package.json | 5 +-
server/routes/appointmentRoutes.js | 51 +++++++++
server/routes/courseRoutes.js | 38 +++++++
server/routes/facultyRoutes.js | 29 +++++
server/server.js | 37 ++++--
16 files changed, 756 insertions(+), 118 deletions(-)
create mode 100644 client/src/Pages/CourseTable.css
create mode 100644 client/src/Pages/CourseTable.jsx
create mode 100644 client/src/api.js
create mode 100644 server/models/Appointment.js
create mode 100644 server/models/Course.js
create mode 100644 server/models/Faculty.js
create mode 100644 server/routes/appointmentRoutes.js
create mode 100644 server/routes/courseRoutes.js
create mode 100644 server/routes/facultyRoutes.js
diff --git a/client/src/App.js b/client/src/App.js
index 8dbbb71..e215dbe 100644
--- a/client/src/App.js
+++ b/client/src/App.js
@@ -11,6 +11,7 @@ import ResetPwPage from "./Pages/ResetPw";
import FilterPage from "./Pages/FilterPage";
import WelcomeWithFilter from "./Pages/WelcomeWithFilter";
import "react-toastify/dist/ReactToastify.css";
+import CourseTable from "./Pages/CourseTable";
function App() {
return (
@@ -26,6 +27,7 @@ function App() {
}>
}>
} />
+ } />
);
diff --git a/client/src/Pages/CourseForm.css b/client/src/Pages/CourseForm.css
index ee4dd20..1d45e17 100644
--- a/client/src/Pages/CourseForm.css
+++ b/client/src/Pages/CourseForm.css
@@ -1,63 +1,85 @@
+/* CourseForm.css */
.form-container {
- max-width: 600px;
- margin: 30px auto;
- padding: 20px;
- background-color: #f4f4f9;
- border-radius: 10px;
- box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
+ max-width: 600px;
+ margin: 50px auto;
+ padding: 20px;
+ border: 1px solid #ccc;
+ border-radius: 10px;
+ background-color: #f9f9f9;
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
+}
+
+h2 {
+ text-align: center;
+ color: #333;
+ margin-bottom: 20px;
+ font-size: 1.8rem;
+}
+
+form {
+ display: flex;
+ flex-direction: column;
+ gap: 15px;
+}
+
+label {
+ font-size: 1rem;
+ font-weight: bold;
+ color: #555;
+ display: flex;
+ flex-direction: column;
+}
+
+input[type="text"] {
+ padding: 10px;
+ font-size: 1rem;
+ border: 1px solid #ccc;
+ border-radius: 5px;
+ background-color: #fff;
+ transition: border-color 0.3s ease;
+}
+
+input[type="text"]:focus {
+ border-color: #007bff;
+ outline: none;
+}
+
+button {
+ padding: 10px 15px;
+ font-size: 1rem;
+ font-weight: bold;
+ color: #fff;
+ background-color: #007bff;
+ border: none;
+ border-radius: 5px;
+ cursor: pointer;
+ transition: background-color 0.3s ease;
+}
+
+button:hover {
+ background-color: #0056b3;
+}
+
+button:active {
+ background-color: #003d7a;
+}
+
+button[type="submit"] {
+ align-self: center;
+ width: 50%;
+}
+
+@media (max-width: 768px) {
+ .form-container {
+ margin: 20px;
+ padding: 15px;
}
-
+
h2 {
- text-align: center;
- font-size: 24px;
- color: #333;
- margin-bottom: 20px;
+ font-size: 1.5rem;
}
-
- form {
- display: flex;
- flex-direction: column;
- gap: 20px;
- }
-
- label {
- font-size: 16px;
- color: #333;
- margin-bottom: 5px;
- }
-
- input {
- padding: 12px;
- font-size: 16px;
- border: 1px solid #ddd;
- border-radius: 5px;
+
+ button[type="submit"] {
width: 100%;
- box-sizing: border-box;
}
-
- input:focus {
- outline: none;
- border-color: #4caf50;
- box-shadow: 0 0 5px rgba(0, 192, 0, 0.2);
- }
-
- button {
- padding: 12px;
- font-size: 16px;
- background-color: #4caf50;
- color: white;
- border: none;
- border-radius: 5px;
- cursor: pointer;
- width: 100%;
- box-sizing: border-box;
- }
-
- button:hover {
- background-color: #45a049;
- }
-
- button:focus {
- outline: none;
- }
-
\ No newline at end of file
+}
diff --git a/client/src/Pages/CourseForm.jsx b/client/src/Pages/CourseForm.jsx
index 24e080c..8ace412 100644
--- a/client/src/Pages/CourseForm.jsx
+++ b/client/src/Pages/CourseForm.jsx
@@ -1,27 +1,182 @@
-import React from "react";
-import { useParams } from "react-router-dom";
+import React, { useState, useEffect } from "react";
+import { useLocation, useParams, useNavigate } from "react-router-dom";
import "./CourseForm.css";
const CourseForm = () => {
const { id } = useParams(); // Get the course ID from the URL params
+ const location = useLocation();
+ const navigate = useNavigate(); // Updated for navigation
+ const { course } = location.state || {};
+
+ const [options, setOptions] = useState({
+ assessment: [],
+ reassessment: [],
+ paperSetting: [],
+ moderation: [],
+ pwdPaperSetter: [],
+ oralsPracticals: [], // New field for Orals/Practicals
+ });
+
+ const [formData, setFormData] = useState({
+ assessment: "",
+ reassessment: "",
+ paperSetting: "",
+ moderation: "",
+ pwdPaperSetter: "",
+ oralsPracticals: "", // New field for Orals/Practicals
+ });
+
+ const [errors, setErrors] = useState({}); // To track validation errors
+
+ // Fetch data for search bars
+ useEffect(() => {
+ const fetchOptions = async () => {
+ try {
+ const response = await fetch("/api/options"); // Replace with your API endpoint
+ const data = await response.json();
+ setOptions(data);
+ } catch (error) {
+ console.error("Failed to fetch options:", error);
+ }
+ };
+
+ fetchOptions();
+ }, []);
+
+ const handleInputChange = (e) => {
+ const { name, value } = e.target;
+ setFormData({ ...formData, [name]: value });
+ };
+
+ const validateForm = () => {
+ const newErrors = {};
+ Object.keys(formData).forEach((field) => {
+ if (!formData[field]) {
+ newErrors[field] = "This field is required";
+ }
+ });
+ setErrors(newErrors);
+ return Object.keys(newErrors).length === 0;
+ };
+
+ const handleSubmit = (e) => {
+ e.preventDefault();
+ if (validateForm()) {
+ console.log("Form submitted:", formData);
+
+ navigate("/courses", { state: { updatedCourse: { ...course, status: "Submitted" } } });
+ }
+ };
return (
Course Info
-
);
diff --git a/client/src/Pages/CourseTable.css b/client/src/Pages/CourseTable.css
new file mode 100644
index 0000000..863b9d5
--- /dev/null
+++ b/client/src/Pages/CourseTable.css
@@ -0,0 +1,111 @@
+/* CourseTable.css */
+
+.course-table {
+ width: 80%;
+ margin: 0 auto;
+ padding: 20px;
+ background-color: #f9f9f9;
+ border-radius: 8px;
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
+ }
+
+ .course-table h2 {
+ text-align: center;
+ margin-bottom: 20px;
+ color: #333;
+ }
+
+ .course-table ul {
+ list-style-type: none;
+ padding: 0;
+ margin: 0;
+ }
+
+ .course-table li {
+ padding: 10px;
+ margin-bottom: 10px;
+ background-color: #fff;
+ border: 1px solid #ddd;
+ border-radius: 4px;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ }
+
+ .course-table li:last-child {
+ margin-bottom: 0;
+ }
+
+ .course-table li .status {
+ font-size: 0.9rem;
+ padding: 5px 10px;
+ border-radius: 3px;
+ color: #fff;
+ }
+
+ .course-table li .status.Pending {
+ background-color: #f39c12;
+ }
+
+ .course-table li .status.Submitted {
+ background-color: #2ecc71;
+ }
+
+ .course-table .form-container {
+ padding: 20px;
+ background-color: #fff;
+ border-radius: 8px;
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
+ }
+
+ .course-table .form-container h2 {
+ margin-bottom: 20px;
+ text-align: center;
+ }
+
+ .course-table .form-container form {
+ display: flex;
+ flex-direction: column;
+ }
+
+ .course-table .form-container label {
+ margin-bottom: 10px;
+ }
+
+ .course-table .form-container input[type="text"] {
+ padding: 8px;
+ border: 1px solid #ddd;
+ border-radius: 4px;
+ width: 100%;
+ }
+
+ .course-table .form-container input[type="text"]:focus {
+ border-color: #007bff;
+ }
+
+ .course-table .form-container .error {
+ border-color: red;
+ }
+
+ .course-table .form-container .error-message {
+ color: red;
+ font-size: 0.9rem;
+ margin-top: 5px;
+ }
+
+ .course-table .form-container button {
+ padding: 10px;
+ background-color: #007bff;
+ color: #fff;
+ border: none;
+ border-radius: 4px;
+ cursor: pointer;
+ font-size: 1rem;
+ margin-top: 15px;
+ }
+
+ .course-table .form-container button:disabled {
+ background-color: #ccc;
+ cursor: not-allowed;
+ }
+
\ No newline at end of file
diff --git a/client/src/Pages/CourseTable.jsx b/client/src/Pages/CourseTable.jsx
new file mode 100644
index 0000000..8bf9a44
--- /dev/null
+++ b/client/src/Pages/CourseTable.jsx
@@ -0,0 +1,89 @@
+// import React from "react";
+// import { useNavigate } from "react-router-dom";
+// import "./CourseTable.css";
+
+// const CourseTable = ({courses}) => {
+// const navigate = useNavigate();
+
+// const handleRowClick = (course) => {
+// navigate(`/course-form/${course.id}`, { state: { course } });
+// };
+
+// return (
+//
+//
Courses
+//
+//
+//
+// | Course ID |
+// Course Name |
+// Status |
+//
+//
+//
+// {courses.map((course) => (
+// handleRowClick(course)}
+// style={{ cursor: "pointer" }}
+// >
+// | {course.id} |
+// {course.name} |
+//
+//
+// {course.status}
+//
+// |
+//
+// ))}
+//
+//
+//
+// );
+// };
+
+// export default CourseTable;
+
+import React, { useState, useEffect } from 'react';
+import { useLocation, useNavigate } from "react-router-dom";
+import "./CourseTable.css";
+import { fetchCourses } from '../api';
+
+const CourseTable = () => {
+ const { state } = useLocation();
+ const courses = state?.courses;
+ console.log(courses);
+
+ useEffect(() => {
+ if (!courses || courses.length === 0) {
+ alert("No courses available");
+ }
+ }, [courses]);
+
+ if (!courses) {
+ return Loading...
;
+ }
+
+ return (
+
+
+
+ | CourseID |
+ Course Name |
+ Status |
+
+
+
+ {courses.map(course => (
+
+ | {course.courseId} |
+ {course.name} |
+ {course.status} |
+
+ ))}
+
+
+ );
+}
+
+export default CourseTable;
diff --git a/client/src/Pages/FilterPage.jsx b/client/src/Pages/FilterPage.jsx
index c156a3b..88c56e5 100644
--- a/client/src/Pages/FilterPage.jsx
+++ b/client/src/Pages/FilterPage.jsx
@@ -1,67 +1,101 @@
import React, { useState } from "react";
+import { useNavigate } from "react-router-dom";
import "./FilterPage.css";
+import { fetchCourses } from "../api";
-const FilterPage = ({ onApplyFilter }) => {
- const [selectedOption, setSelectedOption] = useState(null);
+const FilterPage = () => {
const [formData, setFormData] = useState({
scheme: "",
- year: "",
+ semester: "",
+ department: "",
+ program: "",
});
+ const navigate = useNavigate();
+
const handleInputChange = (e) => {
const { name, value } = e.target;
setFormData({ ...formData, [name]: value });
+
+ // Reset semester if program changes
+ if (name === "program") {
+ setFormData((prevData) => ({ ...prevData, semester: "" }));
+ }
};
- const handleApplyFilter = () => {
- if (!formData.scheme || !formData.year) {
- alert("Please select both Scheme and Year before applying the filter.");
+ const handleApplyFilter = async () => {
+ if (!formData.scheme || !formData.semester || !formData.department || !formData.program) {
+ alert("Please fill all the fields before applying the filter.");
return;
}
- if (!selectedOption) {
- alert("Please select either 'Course' or 'Faculty' before applying the filter.");
- return;
+
+ try {
+ const filteredCourses = await fetchCourses(formData);
+ console.log(formData);
+ if (filteredCourses.length > 0) {
+ navigate("/courses", { state: { courses: filteredCourses } });
+ } else {
+ alert("No courses found for the selected filters.");
+ }
+ } catch (error) {
+ console.error("Error fetching courses:", error);
+ alert("Failed to fetch courses. Please try again later.");
}
- onApplyFilter(selectedOption); // Pass the selected option to the parent
};
- const handleSelectOption = (option) => {
- setSelectedOption(option);
+ const getSemesters = () => {
+ if (!formData.program) return [];
+ if (formData.program === "B.Tech") {
+ return Array.from({ length: 8 }, (_, i) => i + 1); // 1 to 8
+ }
+ if (formData.program === "M.Tech") {
+ return Array.from({ length: 4 }, (_, i) => i + 1); // 1 to 4
+ }
+ return [];
};
return (
+
+
+
-
-
-
diff --git a/client/src/api.js b/client/src/api.js
new file mode 100644
index 0000000..2725849
--- /dev/null
+++ b/client/src/api.js
@@ -0,0 +1,28 @@
+const BASE_URL = "http://localhost:8080/api";
+
+export const fetchCourses = async (filterData) => {
+ try {
+
+ // Serialize filterData into query parameters
+ const queryString = new URLSearchParams(filterData).toString();
+ // console.log(queryString);
+ const response = await fetch(`${BASE_URL}/courses?${queryString}`, {
+ method: "GET",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ });
+
+ if (!response.ok) {
+ throw new Error("Failed to fetch courses");
+ }
+
+ const filteredCourses = await response.json();
+ console.log(filteredCourses);
+ return filteredCourses;
+ } catch (error) {
+ console.error("Error fetching courses:", error);
+ throw error; // Re-throw error to be handled by the caller
+ }
+};
+
diff --git a/server/models/Appointment.js b/server/models/Appointment.js
new file mode 100644
index 0000000..49c45fd
--- /dev/null
+++ b/server/models/Appointment.js
@@ -0,0 +1,11 @@
+const mongoose = require("mongoose");
+const { v4: uuidv4 } = require("uuid"); // For UUID generation
+
+const AppointmentSchema = new mongoose.Schema({
+ appointmentId: { type: String, default: uuidv4 }, // Auto-generate using UUID
+ courseId: { type: String, required: true, ref: "Course" },
+ facultyId: { type: String, required: true, ref: "Faculty" },
+ appointmentType: { type: [String], required: true }, // Array of appointment types
+});
+
+module.exports = mongoose.model("Appointment", AppointmentSchema);
diff --git a/server/models/Course.js b/server/models/Course.js
new file mode 100644
index 0000000..84f0b6e
--- /dev/null
+++ b/server/models/Course.js
@@ -0,0 +1,13 @@
+const mongoose = require("mongoose");
+
+const CourseSchema = new mongoose.Schema({
+ courseId: { type: String, required: true, unique: true },
+ name: { type: String, required: true },
+ department: { type: String, required: true },
+ program: { type: String, required: true },
+ scheme: { type: String, required: true },
+ semester: { type: Number, required: true },
+ status: { type: String, enum: ["submitted", "not submitted"], default: "not submitted" },
+});
+
+module.exports = mongoose.model("Course", CourseSchema);
diff --git a/server/models/Faculty.js b/server/models/Faculty.js
new file mode 100644
index 0000000..9e77a43
--- /dev/null
+++ b/server/models/Faculty.js
@@ -0,0 +1,11 @@
+const mongoose = require("mongoose");
+
+const FacultySchema = new mongoose.Schema({
+ facultyId: { type: String, required: true, unique: true },
+ name: { type: String, required: true },
+ email: { type: String, required: true },
+ department: { type: String, required: true },
+ program: { type: String, required: true },
+});
+
+module.exports = mongoose.model("Faculty", FacultySchema);
diff --git a/server/package-lock.json b/server/package-lock.json
index 235d398..5ab6d3c 100644
--- a/server/package-lock.json
+++ b/server/package-lock.json
@@ -25,7 +25,8 @@
"passport": "^0.7.0",
"passport-google-oauth20": "^2.0.0",
"passport-local": "^1.0.0",
- "passport-local-mongoose": "^8.0.0"
+ "passport-local-mongoose": "^8.0.0",
+ "uuid": "^11.0.3"
},
"devDependencies": {
"nodemon": "^3.1.0"
@@ -712,6 +713,18 @@
"node": ">=14"
}
},
+ "node_modules/gaxios/node_modules/uuid": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
+ "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
+ "funding": [
+ "https://github.com/sponsors/broofa",
+ "https://github.com/sponsors/ctavan"
+ ],
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
"node_modules/gcp-metadata": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-5.3.0.tgz",
@@ -898,6 +911,18 @@
"node": ">=14.0.0"
}
},
+ "node_modules/googleapis-common/node_modules/uuid": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
+ "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
+ "funding": [
+ "https://github.com/sponsors/broofa",
+ "https://github.com/sponsors/ctavan"
+ ],
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
"node_modules/gopd": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.1.0.tgz",
@@ -2219,16 +2244,15 @@
}
},
"node_modules/uuid": {
- "version": "9.0.1",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
- "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
+ "version": "11.0.3",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.0.3.tgz",
+ "integrity": "sha512-d0z310fCWv5dJwnX1Y/MncBAqGMKEzlBb1AOf7z9K8ALnd0utBX/msg/fA0+sbyN1ihbMsLhrBlnl1ak7Wa0rg==",
"funding": [
"https://github.com/sponsors/broofa",
"https://github.com/sponsors/ctavan"
],
- "license": "MIT",
"bin": {
- "uuid": "dist/bin/uuid"
+ "uuid": "dist/esm/bin/uuid"
}
},
"node_modules/vary": {
diff --git a/server/package.json b/server/package.json
index 19285e6..53728c5 100644
--- a/server/package.json
+++ b/server/package.json
@@ -5,7 +5,7 @@
"main": "sever.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
- "build" : "npm install --prefix ../client && npm run build --prefix ../client && npm install",
+ "build": "npm install --prefix ../client && npm run build --prefix ../client && npm install",
"start": "nodemon server.js"
},
"repository": {
@@ -34,7 +34,8 @@
"passport": "^0.7.0",
"passport-google-oauth20": "^2.0.0",
"passport-local": "^1.0.0",
- "passport-local-mongoose": "^8.0.0"
+ "passport-local-mongoose": "^8.0.0",
+ "uuid": "^11.0.3"
},
"devDependencies": {
"nodemon": "^3.1.0"
diff --git a/server/routes/appointmentRoutes.js b/server/routes/appointmentRoutes.js
new file mode 100644
index 0000000..ffce999
--- /dev/null
+++ b/server/routes/appointmentRoutes.js
@@ -0,0 +1,51 @@
+const express = require("express");
+const Appointment = require("../models/Appointment");
+
+const router = express.Router();
+
+// Get all appointments
+router.get("/", async (req, res) => {
+ try {
+ const appointments = await Appointment.find()
+ .populate("courseId", "name department")
+ .populate("facultyId", "name email");
+ res.json(appointments);
+ } catch (error) {
+ res.status(500).json({ error: "Failed to fetch appointments" });
+ }
+});
+
+// Create a new appointment
+router.post("/", async (req, res) => {
+ try {
+ const { courseId, facultyId, appointmentType } = req.body;
+
+ const newAppointment = new Appointment({
+ courseId,
+ facultyId,
+ appointmentType,
+ });
+
+ await newAppointment.save();
+ res.status(201).json(newAppointment);
+ } catch (error) {
+ res.status(400).json({ error: "Failed to create appointment" });
+ }
+ });
+
+// Get appointment by ID
+router.get("/:id", async (req, res) => {
+ try {
+ const appointment = await Appointment.findOne({ appointmentId: req.params.id })
+ .populate("courseId", "name department")
+ .populate("facultyId", "name email");
+ if (!appointment) {
+ return res.status(404).json({ error: "Appointment not found" });
+ }
+ res.json(appointment);
+ } catch (error) {
+ res.status(500).json({ error: "Failed to fetch appointment" });
+ }
+});
+
+module.exports = router;
diff --git a/server/routes/courseRoutes.js b/server/routes/courseRoutes.js
new file mode 100644
index 0000000..a932537
--- /dev/null
+++ b/server/routes/courseRoutes.js
@@ -0,0 +1,38 @@
+const express = require("express");
+const Course = require("../models/Course");
+
+const router = express.Router();
+
+router.get("/", async (req, res) => {
+ try {
+ const filter = {};
+
+ if (req.query.department) filter.department = req.query.department;
+ if (req.query.program) filter.program = req.query.program;
+ if (req.query.semester) filter.semester = Number(req.query.semester); // Convert to number if needed
+ if (req.query.scheme) filter.scheme = req.query.scheme;
+
+ const courses = await Course.find(filter);
+ res.json(courses);
+ } catch (error) {
+ console.error("Error fetching courses:", error);
+ res.status(500).json({ error: "Failed to fetch courses" });
+ }
+ });
+
+
+// Get course by ID
+router.get("/:id", async (req, res) => {
+ try {
+ const course = await Course.findOne({ courseId: req.params.id });
+ if (!course) {
+ return res.status(404).json({ error: "Course not found" });
+ }
+ res.json(course);
+ } catch (error) {
+ console.error("Error fetching course:", error);
+ res.status(500).json({ error: "Failed to fetch course" });
+ }
+});
+
+module.exports = router;
diff --git a/server/routes/facultyRoutes.js b/server/routes/facultyRoutes.js
new file mode 100644
index 0000000..a7809b7
--- /dev/null
+++ b/server/routes/facultyRoutes.js
@@ -0,0 +1,29 @@
+const express = require("express");
+const Faculty = require("../models/Faculty");
+
+const router = express.Router();
+
+// Get all faculty members
+router.get("/", async (req, res) => {
+ try {
+ const faculty = await Faculty.find();
+ res.json(faculty);
+ } catch (error) {
+ res.status(500).json({ error: "Failed to fetch faculty members" });
+ }
+});
+
+// Get faculty by ID
+router.get("/:id", async (req, res) => {
+ try {
+ const faculty = await Faculty.findOne({ facultyId: req.params.id });
+ if (!faculty) {
+ return res.status(404).json({ error: "Faculty member not found" });
+ }
+ res.json(faculty);
+ } catch (error) {
+ res.status(500).json({ error: "Failed to fetch faculty member" });
+ }
+});
+
+module.exports = router;
diff --git a/server/server.js b/server/server.js
index 7b1b9b4..834670e 100644
--- a/server/server.js
+++ b/server/server.js
@@ -1,25 +1,38 @@
const express = require("express");
-const User = require("./models/User");
+const mongoose = require("mongoose");
+const bodyParser = require("body-parser");
const cors = require("cors");
+require("dotenv").config();
const passport = require("passport");
const session = require("express-session");
-const bodyParser = require("body-parser");
const bcrypt = require("bcryptjs");
const LocalStrategy = require("passport-local").Strategy;
-const PasswordRouter = require("./routes/authRoutes");
const crypto = require("crypto");
const jwt = require("jsonwebtoken");
const path = require("path");
+const User = require("./models/User");
+const PasswordRouter = require("./routes/authRoutes");
+const courseRoutes = require("./routes/courseRoutes");
+const facultyRoutes = require("./routes/facultyRoutes");
+const appointmentRoutes = require("./routes/appointmentRoutes");
+
+// Existing Database Connection
const { connectdb } = require("./ConnectionDb");
connectdb();
+// MongoDB Connection
+mongoose
+ .connect(process.env.mongoURI)
+ .then(() => console.log("MongoDB connected"))
+ .catch((err) => console.error("MongoDB connection error:", err));
+
const app = express();
// Middleware
+app.use(cors());
app.use(express.json());
app.use(bodyParser.urlencoded({ extended: true }));
-
app.use(
session({
secret: "secret",
@@ -39,7 +52,7 @@ app.use(
})
);
-// Passport configuration
+// Passport Configuration
require("./config/passport");
passport.use(
@@ -76,7 +89,11 @@ passport.deserializeUser((id, done) => {
// Routes
app.use("/password", PasswordRouter);
+app.use("/api/courses", courseRoutes);
+app.use("/api/faculty", facultyRoutes);
+app.use("/api/appointments", appointmentRoutes);
+// OAuth Routes
app.get(
"/auth/google",
passport.authenticate("google", { scope: ["profile", "email"] })
@@ -86,7 +103,7 @@ app.get(
"/auth/google/callback",
passport.authenticate("google", { failureRedirect: "/" }),
function (req, res) {
- res.redirect("http://localhost:3000/Welcom");
+ res.redirect("http://localhost:3000/Welcom");
}
);
@@ -174,15 +191,17 @@ app.get("/api/user/profile", async (req, res) => {
}
});
-// Serve static files
+// Serve Static Files
app.use(express.static(path.join(__dirname, "../client/build")));
-// Catch-all route to serve React app
+// Catch-All Route
app.get("*", (req, res) =>
res.sendFile(path.join(__dirname, "../client/build/index.html"))
);
-const Port = 8080;
+
+// Start Server
+const Port = process.env.PORT || 8080;
app.listen(Port, () => {
console.log(`Server is Running at port ${Port}`);
});