Skip to content
Open
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
224 changes: 213 additions & 11 deletions server/app.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,238 @@
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 - https://expressjs.com/en/starter/basic-routing.html
// Devs Team - Start working on the routes here:
// ...
// =========================================================
// ROUTES
// =========================================================

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, next) => {
try {
const cohorts = await Cohort.find();
res.status(200).json(cohorts);
} catch (error) {
error.status = 500;
error.message = "Failed to retrieve cohorts";
next(error);
}
});

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

// GET /api/cohorts/:cohortId - Retrieve a specific cohort by id
app.get("/api/cohorts/:cohortId", async (req, res, next) => {
try {
const cohort = await Cohort.findById(req.params.cohortId);
if (!cohort) {
const error = new Error("Cohort not found");
error.status = 404;
return next(error);

}
res.status(200).json(updatedCohort);
} catch (error) {
error.status = 500;
error.message = "Failed to retrieve cohort";
next(error);
}
});

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

}
res.status(200).json(updatedCohort);
} catch (error) {
error.status = 500;
error.message = "Failed to update cohort";
next(error);
}
});

// DELETE /api/cohorts/:cohortId - Delete a specific cohort by id
app.delete("/api/cohorts/:cohortId", async (req, res, next) => {
try {
const deletedCohort = await Cohort.findByIdAndDelete(req.params.cohortId);
if (!deletedCohort) {
const error = new Error("Cohort not found");
error.status = 404;
return next(error);

}
res.status(204).send();
} catch (error) {
error.status = 500;
error.messgae ="Failed to delete cohort";
next(error);

}
});


// --- STUDENT ROUTES ---

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

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

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

// GET /api/students/:studentId - Retrieve a specific student by id
app.get("/api/students/:studentId", async (req, res, next) => {
try {
const student = await Student.findById(req.params.studentId).populate("cohort");
if (!student) {const error = new Error ("Student not found");
error.status = 404;
return next(error);
}

res.status(200).json(student);

} catch (error) {
error.status = 500;
error.message = "Failed to updatestudent";
next(error);
}
});

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

res.status(200).json(updatedStudent);

} catch (error) {
error.status = 500;
error.message = "Failed to delete student";
next(error);
}
});

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

} catch (error) {
error.status = 500;
error.message = "Failed to delete student";
next(error);
}
});

// =========================================================
// ERROR HANDLING
// =========================================================
//404

app.use((req, res) => {
res.status(404).json ({
message: "Route not found"
});

app.use((error, req, res, next) => {
console.error(error);
res.status(500).json({ message: "Internal server error" });
});

});




// =========================================================
// 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