Skip to content
Open

Side #175

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
174 changes: 163 additions & 11 deletions server/app.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,188 @@
const express = require("express");
const morgan = require("morgan");
const cookieParser = require("cookie-parser");
const cors = require("cors");
const mongoose = require("mongoose");
const PORT = 5005;

// STATIC DATA
// Devs Team - Import the provided files with JSON data of students and cohorts here:
// ...
// MODELS
const Cohort = require("./models/Cohort.model");
const Student = require("./models/Student.model");


// INITIALIZE EXPRESS APP - https://expressjs.com/en/4x/api.html#express
// INITIALIZE EXPRESS APP
const app = express();


// MIDDLEWARE
// Research Team - Set up CORS middleware here:
// ...
app.use(express.json());
app.use(morgan("dev"));
app.use(express.static("public"));
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(cors());

// MONGOOSE CONNECTION
mongoose
.connect("mongodb://127.0.0.1:27017/cohort-tools-api")
.then((x) => console.log(`Connected to Mongo! Database name: "${x.connections[0].name}"`))
.catch((err) => console.error("Error connecting to MongoDB", err));


// =========================================================
// ROUTES
// =========================================================

// ROUTES - https://expressjs.com/en/starter/basic-routing.html
// Devs Team - Start working on the routes here:
// ...
app.get("/docs", (req, res) => {
res.sendFile(__dirname + "/views/docs.html");
});

// --- COHORT ROUTES ---

// GET /api/cohorts - Retrieve all cohorts
app.get("/api/cohorts", async (req, res) => {
try {
const cohorts = await Cohort.find();
res.status(200).json(cohorts);
} catch (error) {
console.error("Error fetching cohorts:", error);
res.status(500).json({ message: "Failed to retrieve cohorts" });
}
});

// POST /api/cohorts - Create a new cohort
app.post("/api/cohorts", async (req, res) => {
try {
const newCohort = await Cohort.create(req.body);
res.status(201).json(newCohort);
} catch (error) {
console.error("Error creating cohort:", error);
res.status(500).json({ message: "Failed to create cohort" });
}
});

// GET /api/cohorts/:cohortId - Retrieve a specific cohort by id
app.get("/api/cohorts/:cohortId", async (req, res) => {
try {
const cohort = await Cohort.findById(req.params.cohortId);
if (!cohort) {
return res.status(404).json({ message: "Cohort not found" });
}
res.status(200).json(cohort);
} catch (error) {
console.error("Error fetching cohort:", error);
res.status(500).json({ message: "Failed to retrieve cohort" });
}
});

// PUT /api/cohorts/:cohortId - Update a specific cohort by id
app.put("/api/cohorts/:cohortId", async (req, res) => {
try {
const updatedCohort = await Cohort.findByIdAndUpdate(req.params.cohortId, req.body, { new: true });
if (!updatedCohort) {
return res.status(404).json({ message: "Cohort not found" });
}
res.status(200).json(updatedCohort);
} catch (error) {
console.error("Error updating cohort:", error);
res.status(500).json({ message: "Failed to update cohort" });
}
});

// DELETE /api/cohorts/:cohortId - Delete a specific cohort by id
app.delete("/api/cohorts/:cohortId", async (req, res) => {
try {
const deletedCohort = await Cohort.findByIdAndDelete(req.params.cohortId);
if (!deletedCohort) {
return res.status(404).json({ message: "Cohort not found" });
}
res.status(204).send();
} catch (error) {
console.error("Error deleting cohort:", error);
res.status(500).json({ message: "Failed to delete cohort" });
}
});


// --- STUDENT ROUTES ---

// GET /api/students - Retrieve all students
app.get("/api/students", async (req, res) => {
try {
const students = await Student.find().populate("cohort");
res.status(200).json(students);
} catch (error) {
console.error("Error fetching students:", error);
res.status(500).json({ message: "Failed to retrieve students" });
}
});

// POST /api/students - Create a new student
app.post("/api/students", async (req, res) => {
try {
const newStudent = await Student.create(req.body);
res.status(201).json(newStudent);
} catch (error) {
console.error("Error creating student:", error);
res.status(500).json({ message: "Failed to create student" });
}
});

// GET /api/students/cohort/:cohortId - Retrieve all students for a given cohort
app.get("/api/students/cohort/:cohortId", async (req, res) => {
try {
const students = await Student.find({ cohort: req.params.cohortId }).populate("cohort");
res.status(200).json(students);
} catch (error) {
console.error("Error fetching students by cohort:", error);
res.status(500).json({ message: "Failed to retrieve students for this cohort" });
}
});

// GET /api/students/:studentId - Retrieve a specific student by id
app.get("/api/students/:studentId", async (req, res) => {
try {
const student = await Student.findById(req.params.studentId).populate("cohort");
if (!student) {
return res.status(404).json({ message: "Student not found" });
}
res.status(200).json(student);
} catch (error) {
console.error("Error fetching student:", error);
res.status(500).json({ message: "Failed to retrieve student" });
}
});

// PUT /api/students/:studentId - Update a specific student by id
app.put("/api/students/:studentId", async (req, res) => {
try {
const updatedStudent = await Student.findByIdAndUpdate(req.params.studentId, req.body, { new: true });
if (!updatedStudent) {
return res.status(404).json({ message: "Student not found" });
}
res.status(200).json(updatedStudent);
} catch (error) {
console.error("Error updating student:", error);
res.status(500).json({ message: "Failed to update student" });
}
});

// DELETE /api/students/:studentId - Delete a specific student by id
app.delete("/api/students/:studentId", async (req, res) => {
try {
const deletedStudent = await Student.findByIdAndDelete(req.params.studentId);
if (!deletedStudent) {
return res.status(404).json({ message: "Student not found" });
}
res.status(204).send();
} catch (error) {
console.error("Error deleting student:", error);
res.status(500).json({ message: "Failed to delete student" });
}
});


// =========================================================
// START SERVER
// =========================================================
app.listen(PORT, () => {
console.log(`Server listening on port ${PORT}`);
});
18 changes: 18 additions & 0 deletions server/models/Cohort.model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const mongoose = require("mongoose");
const Schema = mongoose.Schema;

const cohortSchema = new Schema({
cohortSlug: { type: String, required: true, unique: true },
cohortName: { type: String, required: true },
program: { type: String, enum: ["Web Dev", "UX/UI", "Data Analytics", "Cybersecurity"] },
format: { type: String, enum: ["Full Time", "Part Time"] },
campus: { type: String },
startDate: { type: Date, default: Date.now },
endDate: { type: Date },
inProgress: { type: Boolean, default: false },
programManager: { type: String, required: true },
leadTeacher: { type: String, required: true },
totalHours: { type: Number, default: 360 }
});

module.exports = mongoose.model("Cohort", cohortSchema);
19 changes: 19 additions & 0 deletions server/models/Student.model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const mongoose = require("mongoose");
const Schema = mongoose.Schema;

const studentSchema = new Schema({
firstName: { type: String, required: true },
lastName: { type: String, required: true },
email: { type: String, required: true, unique: true },
phone: { type: String, required: true },
linkedinUrl: { type: String, default: "" },
languages: { type: [String], enum: ["English", "Spanish", "French", "German", "Portuguese", "Dutch", "Other"] },
program: { type: String, enum: ["Web Dev", "UX/UI", "Data Analytics", "Cybersecurity"] },
background: { type: String, default: "" },
image: { type: String, default: "https://i.imgur.com/r8bo8u7.png" },
// This establishes the relationship between a student and a cohort
cohort: { type: Schema.Types.ObjectId, ref: "Cohort" },
projects: { type: Array }
});

module.exports = mongoose.model("Student", studentSchema);
27 changes: 27 additions & 0 deletions server/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
"description": "ExpressJS API for the Cohort Tools app",
"main": "app.js",
"scripts": {
"dev": "nodemon app.js",
"test": "echo \"Error: no test specified\" && exit 1"
"start": "node app.js",
"dev": "nodemon app.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
Expand All @@ -19,6 +20,7 @@
"homepage": "https://github.com/ironhack-labs/cohort-tools-project#readme",
"dependencies": {
"cookie-parser": "^1.4.6",
"cors": "^2.8.6",
"express": "^4.18.2",
"morgan": "^1.10.0",
"nodemon": "^3.0.1"
Expand Down