Project Introduction

The Training Management System is a web application designed to facilitate the management of training programs, courses, and assessments. Built using Node.js, this platform allows trainers to create and manage courses, while trainees can enroll in sessions, complete assessments, and receive certifications. The system supports multiple user roles, including admin, trainer, and trainee, ensuring a tailored experience for each user type. The underlying MySQL database schema is structured to manage users, courses, training sessions, enrollments, assessments, assessment results, feedback, certifications, and resources, providing a robust foundation for effective training management.

Project Objectives

  • To develop a user-friendly interface for trainers to create and manage courses and training sessions.
  • To allow trainees to enroll in training sessions and track their progress.
  • To implement a secure user authentication system for managing user roles and permissions.
  • To facilitate the creation and management of assessments for each course.
  • To record and analyze assessment results for trainees.
  • To collect feedback from trainees regarding courses and training sessions.
  • To issue certifications to trainees upon successful completion of courses.
  • To provide resources related to courses, such as documents, videos, and presentations.
  • To ensure the application is scalable and maintainable for future enhancements.

Project Modules

  1. User Management Module:

    This module handles user registration, authentication, and role management, allowing users to manage their accounts securely.

  2. Course Management Module:

    This module allows trainers to create, update, and manage courses, including details such as title, description, and prerequisites.

  3. Training Session Management Module:

    This module facilitates the scheduling and management of training sessions, including locations and trainer assignments.

  4. Enrollment Management Module:

    This module manages trainee enrollments in training sessions, including tracking their status (enrolled, waitlisted, completed).

  5. Assessment Management Module:

    This module allows trainers to create and manage assessments for courses, including total marks and assessment details.

  6. Assessment Results Module:

    This module records and analyzes assessment results for trainees, including marks obtained.

  7. Feedback Management Module:

    This module collects feedback from trainees regarding courses and training sessions, including comments and ratings.

  8. Certification Management Module:

    This module issues certifications to trainees upon successful completion of courses, including issue and expiration dates.

  9. Resource Management Module:

    This module manages resources related to courses, such as documents, videos, and presentations, ensuring easy access for trainees.

Steps Overview

Set Up the Project: Initialize a new Node.js project and install the required packages.

Configure Sequelize: Set up Sequelize to connect to your database and define models based on your SQL schema.

Create Repositories: Implement repository patterns for data access.

Create Controllers: Implement controllers to handle business logic.

Set Up Routes: Define routes for the application.

Create Views: Use EJS to create views for the application.

Implement CRUD Operations: Implement the CRUD operations for each model.

Step 1: Set Up the Project


mkdir training-app
cd training-app
npm init -y
npm install express sequelize mysql2 ejs body-parser

Step 2: Configure Sequelize

Create a config folder and a database.js file to configure Sequelize.

config/database.js:


const { Sequelize } = require('sequelize');
const sequelize = new Sequelize('your_database_name', 'your_username', 'your_password', {
host: 'localhost',
dialect: 'mysql',
});
module.exports = sequelize;

Step 3: Define Models

Create a models folder and define your models based on the SQL schema.

models/User.js:


const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config/database');
class User extends Model {}
User .init({
UserId: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
Username: {
type: DataTypes.STRING(50),
allowNull: false,
unique: true,
},
PasswordHash: {
type: DataTypes.STRING(256),
allowNull: false,
},
Email: {
type: DataTypes.STRING(100),
allowNull: false,
unique: true,
},
FirstName: {
type: DataTypes.STRING(50),
allowNull: false,
},
LastName: {
type: DataTypes.STRING(50),
allowNull: false,
},
RoleId: {
type: DataTypes.INTEGER,
allowNull: false,
},
}, {
sequelize,
modelName: 'User ',
timestamps: true,
});
module.exports = User;

Repeat this process for the other models (Roles, Courses, Content, etc.) by creating corresponding files in the models folder.

Step 4: Create Repositories

Create a repositories folder and implement repository classes for data access.

repositories/UserRepository.js:


const User = require('../models/User');
class UserRepository {
async create(userData) {
return await User.create(userData);
}
async findAll() {
return await User.findAll();
}
async findById(id) {
return await User.findByPk(id);
}
async update(id, userData) {
const user = await this.findById(id);
if (user) {
return await user.update(userData);
}
return null;
}
async delete(id) {
const user = await this.findById(id);
if (user) {
return await user.destroy();
}
return null;
}
}
module.exports = new UserRepository();

Repeat this process for the other entities.

Step 5: Create Controllers

Create a controllers folder and implement controllers for handling requests.

controllers/UserController.js:


const UserRepository = require('../repositories/UserRepository');
class UserController {
async create(req, res) {
const user = await UserRepository.create(req.body);
res.redirect('/users');
}
async findAll(req, res) {
const users = await UserRepository.findAll();
res.render('users/index', { users });
}
async findById(req, res) {
const user = await UserRepository.findById(req.params.id);
res.render('users/edit', { user });
}
async update(req, res) {
await UserRepository.update(req.params.id, req.body);
res.redirect('/users');
}
async delete(req, res) {
await UserRepository.delete(req.params.id);
res.redirect('/users');
}
}
module.exports = new UserController();

Step 6: Set Up Routes

Create a routes folder and define your routes.

routes/userRoutes.js:


const express = require('express');
const router = express.Router();
const UserController = require('../controllers/UserController');
router.get('/', UserController.findAll);
router.get('/create', (req, res) => res.render('users/create'));
router.post('/', UserController.create);
router.get('/:id/edit', UserController.findById);
router.post('/:id', UserController.update);
router.post('/:id/delete', UserController.delete);
module.exports = router;

Step 7: Create Views

Create a views folder and set up EJS views for your application.

views/users/index.ejs:


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<title>Users</title>
</head>
<body>
<div class="container">
<h1>Users</h1>
<a href="/users/create" class="btn btn-primary">Create User</a>
<table class="table">
<thead>
<tr>
<th>Username</th>
<th>Email</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<% users.forEach(user => { %>
<tr>
<td><%= user.Username %></td>
<td><%= user.Email %></td>
<td>
<a href="/users/<%= user.UserId %>/edit" class="btn btn-warning">Edit</a>
<form action="/users/<%= user.UserId %>/delete" method="POST" style="display:inline;">
<button type="submit" class="btn btn-danger">Delete</button>
</form>
</td>
</tr>
<% }) %>
</tbody>
</table>
</div>
</body>
</html>

views/users/create.ejs:


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset=" UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<title>Create User</title>
</head>
<body>
<div class="container">
<h1>Create User</h1>
<form action="/users" method="POST">
<div class="mb-3">
<label for="Username" class="form-label">Username</label>
<input type="text" class="form-control" id="Username" name="Username" required>
</div>
<div class="mb-3">
<label for="Email" class="form-label">Email</label>
<input type="email" class="form-control" id="Email" name="Email" required>
</div>
<div class="mb-3">
<label for="PasswordHash" class="form-label">Password</label>
<input type="password" class="form-control" id="PasswordHash" name="PasswordHash" required>
</div>
<div class="mb-3">
<label for="FirstName" class="form-label">First Name</label>
<input type="text" class="form-control" id="FirstName" name="FirstName" required>
</div>
<div class="mb-3">
<label for="LastName" class="form-label">Last Name</label>
<input type="text" class="form-control" id="LastName" name="LastName" required>
</div>
<div class="mb-3">
<label for="RoleId" class="form-label">Role ID</label>
<input type="number" class="form-control" id="RoleId" name="RoleId" required>
</div>
<button type="submit" class="btn btn-primary">Create User</button>
</form>
</div>
</body>
</html>

Step 8: Initialize the Application

Create the main application file to set up Express and use the defined routes.

app.js:


const express = require('express');
const bodyParser = require('body-parser');
const userRoutes = require('./routes/userRoutes');
const sequelize = require('./config/database');
const app = express();
const PORT = process.env.PORT || 3000;
app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({ extended: true }));
app.use('/users', userRoutes);
sequelize.sync().then(() => {
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});
}).catch(err => {
console.error('Unable to connect to the database:', err);
});

Step 9: Run the Application

Start the application by running the following command in your terminal:

node app.js

Now you can access the application at http://localhost:3000/users to manage users with complete CRUD operations. You can repeat similar steps for other models like Roles, Courses, etc., by creating their respective routes, controllers, views, and repositories.

Following are the complete implementation for the remaining models

(Roles, Courses, Content, Schedules, Enrollments, Attendance, Assessments, Feedback, Notifications, Resources, Reports) along with their repositories, controllers, routes, and EJS views using Bootstrap 5 templates.

Step 1: Define Remaining Models

Create the following model files in the models directory.

models/Role.js:


const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config/database');
class Role extends Model {}
Role.init({
RoleId: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
RoleName: {
type: DataTypes.STRING(50),
allowNull: false,
unique: true,
},
}, {
sequelize,
modelName: 'Role',
timestamps: true,
});
module.exports = Role;

models/Course.js:


const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config/database');
class Course extends Model {}
Course.init({
CourseId: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
CourseName: {
type: DataTypes.STRING(100),
allowNull: false,
},
Description: {
type: DataTypes.TEXT,
},
CreatedBy: {
type: DataTypes.INTEGER,
allowNull: false,
},
}, {
sequelize,
modelName: 'Course',
timestamps: true,
});
module.exports = Course;

models/Content.js:


const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config/database');
class Content extends Model {}
Content.init({
ContentId: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
CourseId: {
type: DataTypes.INTEGER,
allowNull: false,
},
ContentType: {
type: DataTypes.STRING(50),
allowNull: false,
},
ContentLink: {
type: DataTypes.STRING(255),
},
}, {
sequelize,
modelName: 'Content',
timestamps: true,
});
module.exports = Content;

models/Schedule.js:


const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config/database');
class Schedule extends Model {}
Schedule.init({
ScheduleId: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
CourseId: {
type: DataTypes.INTEGER,
allowNull: false,
},
StartDate: {
type: DataTypes.DATE,
allowNull: false,
},
EndDate: {
type: DataTypes.DATE,
allowNull: false,
},
}, {
sequelize,
modelName: 'Schedule',
timestamps: true,
});
module.exports = Schedule;

models/Enrollment.js:


const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config/database');
class Enrollment extends Model {}
Enrollment.init({
EnrollmentId: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
UserId: {
type: DataTypes.INTEGER,
allowNull: false,
},
CourseId: {
type: DataTypes.INTEGER,
allowNull: false,
},
EnrollmentDate: {
type: DataTypes.DATE,
defaultValue: DataTypes.NOW,
},
Status: {
type: DataTypes.STRING(50),
allowNull: false,
},
}, {
sequelize,
modelName: 'Enrollment',
timestamps: true,
});
module.exports = Enrollment;

models/Attendance.js:


const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config/database');
class Attendance extends Model {}
Attendance.init({
AttendanceId: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
EnrollmentId: {
type: DataTypes.INTEGER,
allowNull: false,
},
AttendanceDate: {
type: DataTypes.DATE,
allowNull: false,
},
Status: {
type: DataTypes.STRING(20),
allowNull: false,
},
}, {
sequelize,
modelName: 'Attendance',
timestamps: true,
});
module.exports = Attendance;

models/Assessment.js:


const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config/database');
class Assessment extends Model {}
Assessment.init({
AssessmentId: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
CourseId: {
type: DataTypes.INTEGER,
allowNull: false,
},
AssessmentType: {
type: DataTypes.STRING(50),
allowNull: false,
},
TotalMarks: {
type: DataTypes.INTEGER,
allowNull: false,
},
}, {
sequelize,
modelName: 'Assessment',
timestamps: true,
});
module.exports = Assessment;

models/Feedback.js:


const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config/database');
class Feedback extends Model {}
Feedback.init({
FeedbackId: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
UserId: {
type: DataTypes.INTEGER,
allowNull: false,
},
CourseId: {
type: DataTypes.INTEGER,
allowNull: false,
},
FeedbackContent: {
type: DataTypes.TEXT,
allowNull: false,
},
}, {
sequelize,
modelName: 'Feedback',
timestamps: true,
});
module.exports = Feedback;

models/Notification.js:


const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config/database');
class Notification extends Model {}
Notification.init({
NotificationId: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
UserId: {
type: DataTypes.INTEGER,
allowNull: false,
},
Message: {
type: DataTypes.STRING(255),
allowNull: false,
},
IsRead: {
type: DataTypes.BOOLEAN,
defaultValue: false,
},
}, {
sequelize,
modelName: 'Notification',
timestamps: true,
});
module.exports = Notification;

models/Resource.js:


const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config/database');
class Resource extends Model {}
Resource .init({
ResourceId: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
CourseId: {
type: DataTypes.INTEGER,
allowNull: false,
},
ResourceName: {
type: DataTypes.STRING(100),
allowNull: false,
},
ResourceLink: {
type: DataTypes.STRING(255),
},
}, {
sequelize,
modelName: 'Resource',
timestamps: true,
});
module.exports = Resource;

models/Report.js:


const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config/database');
class Report extends Model {}
Report.init({
ReportId: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
UserId: {
type: DataTypes.INTEGER,
allowNull: false,
},
ReportDate: {
type: DataTypes.DATE,
allowNull: false,
},
ReportContent: {
type: DataTypes.TEXT,
allowNull: false,
},
}, {
sequelize,
modelName: 'Report',
timestamps: true,
});
module.exports = Report;

Step 2: Create Repositories

Create repository files for each model in the repositories directory.

repositories/RoleRepository.js:


const Role = require('../models/Role');
class RoleRepository {
async create(roleData) {
return await Role.create(roleData);
}
async findAll() {
return await Role.findAll();
}
async findById(id) {
return await Role.findByPk(id);
}
async update(id, roleData) {
const role = await this.findById(id);
if (role) {
return await role.update(roleData);
}
return null;
}
async delete(id) {
const role = await this.findById(id);
if (role) {
return await role.destroy();
}
return null;
}
}
module.exports = new RoleRepository();

Repeat this process for the other repositories (Course, Content, Schedule, Enrollment, Attendance, Assessment, Feedback, Notification, Resource, Report).

Step 3: Create Controllers

Create controller files for each model in the controllers directory.

controllers/RoleController.js:


const RoleRepository = require('../repositories/RoleRepository');
class RoleController {
async create(req, res) {
await RoleRepository.create(req.body);
res.redirect('/roles');
}
async findAll(req, res) {
const roles = await RoleRepository.findAll();
res.render('roles/index', { roles });
}
async findById(req, res) {
const role = await RoleRepository.findById(req.params.id);
res.render('roles/edit', { role });
}
async update(req, res) {
await RoleRepository.update(req.params.id, req.body);
res.redirect('/roles');
}
async delete(req, res) {
await RoleRepository.delete(req.params.id);
res.redirect('/roles');
}
}
module.exports = new RoleController();

Repeat this process for the other controllers (Course, Content, Schedule, Enrollment, Attendance, Assessment, Feedback, Notification, Resource, Report).

Step 4: Set Up Routes

Create route files for each model in the routes directory.

routes/roleRoutes.js:


const express = require('express');
const router = express.Router();
const RoleController = require('../controllers/RoleController');
router.get('/', RoleController.findAll);
router.get('/create', (req, res) => res.render('roles/create'));
router.post('/', RoleController.create);
router.get('/:id/edit', RoleController.findById);
router.post('/:id', RoleController.update);
router.post('/:id/delete', RoleController.delete);
module.exports = router;

Repeat this process for the other routes (Course, Content, Schedule, Enrollment, Attendance, Assessment, Feedback, Notification, Resource, Report).

Step 5: Create Views

Create EJS view files for each model in the views directory.

views/roles/index.ejs:


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<title>Roles</title>
</head>
<body>
<div class="container">
<h1>Roles</h1>
<a href="/roles/create" class="btn btn-primary">Create Role</a>
<table class="table">
<thead>
<tr <th>Role Name</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<% roles.forEach(role => { %>
<tr>
<td><%= role.RoleName %></td>
<td>
<a href="/roles/<%= role.RoleId %>/edit" class="btn btn-warning">Edit</a>
<form action="/roles/<%= role.RoleId %>/delete" method="POST" style="display:inline;">
<button type="submit" class="btn btn-danger">Delete</button>
</form>
</td>
</tr>
<% }) %>
</tbody>
</table>
</div>
</body>
</html>

views/roles/create.ejs:


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<title>Create Role</title>
</head>
<body>
<div class="container">
<h1>Create Role</h1>
<form action="/roles" method="POST">
<div class="mb-3">
<label for="RoleName" class="form-label">Role Name</label>
<input type="text" class="form-control" id="RoleName" name="RoleName" required>
</div>
<button type="submit" class="btn btn-primary">Create Role</button>
</form>
</div>
</body>
</html>

Step 6: Initialize the Application

Update the main application file to include the new routes.

app.js:


const express = require('express');
const bodyParser = require('body-parser');
const userRoutes = require('./routes/userRoutes');
const roleRoutes = require('./routes/roleRoutes');
const sequelize = require('./config/database');
const app = express();
const PORT = process.env.PORT || 3000;
app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({ extended: true }));
app.use('/users', userRoutes);
app.use('/roles', roleRoutes);
sequelize.sync().then(() => {
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});
}).catch(err => {
console.error('Unable to connect to the database:', err);
});

Step 7: Repeat for Other Models

Follow the same pattern for the remaining models (Courses, Content, Schedules, Enrollments, Attendance, Assessments, Feedback, Notifications, Resources, Reports) by creating their respective models, repositories, controllers, routes, and views.

For example, for Courses, you would create:

models/Course.js, repositories/CourseRepository.js, controllers/CourseController.js, routes/courseRoutes.js, and corresponding EJS views like views/courses/index.ejs and views/courses/create.ejs.

Example for Courses

models/Course.js:


// Similar to the previous Course model definition
repositories/CourseRepository.js:
// Similar to the previous RoleRepository definition
controllers/CourseController.js:
// Similar to the previous RoleController definition
routes/courseRoutes.js:
// Similar to the previous roleRoutes definition
views/courses/index.ejs:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<title>Courses</title>
</head>
<body>
<div class="container">
<h1>Courses</h1>
<a href="/courses/create" class="btn btn-primary">Create Course</a>
<table class="table">
<thead>
<tr>
<th>Course Name</th>
<th>Description</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<% courses.forEach(course => { %>
<tr>
<td><%= course.CourseName %></td>
<td><%= course.Description %></td>
<td>
<a href="/courses/<%= course.CourseId %>/edit" class="btn btn-warning">Edit</a>
<form action="/courses/<%= course.CourseId %>/delete" method="POST"style="display:inline;">
<button type="submit" class="btn btn-danger">Delete</button>
</form>
</td>
</tr>
<% }) %>
</tbody>
</table>
</div>
</body>
</html>

views/courses/create.ejs:


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<title>Create Course</title>
</head>
<body>
<div class="container">
<h1>Create Course</h1>
<form action="/courses" method="POST">
<div class="mb-3">
<label for="CourseName" class="form-label">Course Name</label>
<input type="text" class="form-control" id="CourseName" name="CourseName" required>
</div>
<div class="mb-3">
<label for="Description" class="form-label">Description</label>
<textarea class="form-control" id="Description" name="Description"></textarea>
</div>
<div class="mb-3">
<label for="CreatedBy" class="form-label">Created By (User ID)</label>
<input type="number" class="form-control" id="CreatedBy" name="CreatedBy" required>
</div>
<button type="submit" class="btn btn-primary">Create Course</button>
</form>
</div>
</body>
</html>

Final Steps

Continue this process for the remaining models (Content, Schedules, Enrollments, Attendance, Assessments, Feedback, Notifications, Resources, Reports) by creating their respective models, repositories, controllers, routes, and views.

Example for Enrollments

models/Enrollment.js:


// Similar to the previous Enrollment model definition
repositories/EnrollmentRepository.js:
// Similar to the previous RoleRepository definition
controllers/EnrollmentController.js:
// Similar to the previous RoleController definition
routes/enrollmentRoutes.js:
// Similar to the previous roleRoutes definition
views/enrollments/index.ejs:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<title>Enrollments</title>
</head>
<body>
<div class="container">
<h1>Enrollments</h1>
<a href="/enrollments/create" class="btn btn-primary">Create Enrollment</a>
<table class="table">
<thead>
<tr>
<th>User ID</th>
<th>Course ID</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<% enrollments.forEach(enrollment => { %>
<tr>
<td><%= enrollment.UserId %></td>
<td><%= enrollment.CourseId %></td>
<td><%= enrollment.Status %></td>
<td>
<a href="/enrollments/<%= enrollment.EnrollmentId %>/edit" class="btn btn-warning">Edit</a>
<form action="/enrollments/<%= enrollment.EnrollmentId %>/delete" method="POST" style="display:inline;">
<button type="submit" class="btn btn-danger">Delete</button>
</form>
</td>
</tr>
<% }) %>
</tbody>
</table>
</div>
</body>
</html>

By following the outlined steps, you will have a complete CRUD application

for all the models defined in your SQL schema using Node.js, Sequelize, Express, and EJS with Bootstrap 5 templates. Each model will have its own repository, controller, routes, and views, allowing for full management of the data.

Certainly! Below, I will provide the complete implementation for the remaining models

repositories, controllers, routes, and EJS views for the remaining entities (Content, Schedules, Enrollments, Attendance, Assessments, Feedback, Notifications, Resources, Reports) in your Node.js application using Sequelize, Express, and EJS with Bootstrap 5 templates.

Models

models/Content.js:


const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config/database');
class Content extends Model {}
Content.init({
ContentId: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
CourseId: {
type: DataTypes.INTEGER,
allowNull: false,
},
ContentType: {
type: DataTypes.STRING(50),
allowNull: false,
},
ContentLink: {
type: DataTypes.STRING(255),
},
}, {
sequelize,
modelName: 'Content',
timestamps: true,
});
module.exports = Content;

models/Schedule.js:


const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config/database');
class Schedule extends Model {}
Schedule.init({
ScheduleId: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
CourseId: {
type: DataTypes.INTEGER,
allowNull: false,
},
StartDate: {
type: DataTypes.DATE,
allowNull: false,
},
EndDate: {
type: DataTypes.DATE,
allowNull: false,
},
}, {
sequelize,
modelName: 'Schedule',
timestamps: true,
});
module.exports = Schedule;

models/Enrollment.js:


const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config/database');
class Enrollment extends Model {}
Enrollment.init({
EnrollmentId: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
UserId: {
type: DataTypes.INTEGER,
allowNull: false,
},
CourseId: {
type: DataTypes.INTEGER,
allowNull: false,
},
EnrollmentDate: {
type: DataTypes.DATE,
defaultValue: DataTypes.NOW,
},
Status: {
type: DataTypes.STRING(50),
allowNull: false,
},
}, {
sequelize,
modelName: 'Enrollment',
timestamps: true,
});
module.exports = Enrollment;

models/Attendance.js:


const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config/database');
class Attendance extends Model {}
Attendance.init({
AttendanceId: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
EnrollmentId: {
type: DataTypes.INTEGER,
allowNull: false,
},
AttendanceDate: {
type: DataTypes.DATE,
allowNull: false,
},
Status: {
type: DataTypes.STRING(20),
allowNull: false,
},
}, {
sequelize,
modelName: 'Attendance',
timestamps: true,
});
module.exports = Attendance;

models/Assessment.js:


const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config/database');
class Assessment extends Model {}
Assessment.init({
AssessmentId: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
CourseId: {
type: DataTypes.INTEGER,
allowNull: false,
},
AssessmentType: {
type: DataTypes.STRING(50),
allowNull: false,
},
TotalMarks: {
type: DataTypes.INTEGER,
allowNull: false,
},
}, {
sequelize,
modelName: 'Assessment',
timestamps: true,
});
module.exports = Assessment;

models/Feedback.js:


const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config/database');
class Feedback extends Model {}
Feedback.init({
FeedbackId: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
UserId: {
type: DataTypes.INTEGER,
allowNull: false,
},
CourseId: {
type: DataTypes.INTEGER,
allowNull: false,
},
FeedbackContent: {
type: DataTypes.TEXT,
allowNull: false,
},
}, {
sequelize,
modelName: 'Feedback',
timestamps: true,
});
module.exports = Feedback;

models/Notification.js:


const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config/database');
class Notification extends Model {}
Notification.init({
NotificationId: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
UserId: {
type: DataTypes.INTEGER,
allowNull: false,
},
Message: {
type: DataTypes.STRING(255),
allowNull: false,
},
IsRead: {
type: DataTypes.BOOLEAN,
defaultValue: false,
},
}, {
sequelize,
modelName: 'Notification',
timestamps: true,
});
module.exports = Notification;

models/Resource.js:


const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config/database');
class Resource extends Model {}
Resource.init({
ResourceId: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
CourseId: {
type: DataTypes.INTEGER,
allowNull: false,
},
ResourceName: {
type: DataTypes.STRING(100),
allowNull: false,
},
ResourceLink: {
type: DataTypes.STRING(255),
},
}, {
sequelize,
modelName: 'Resource',
timestamps: true,
});
module.exports = Resource;

models/Report.js:


const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config/database');
class Report extends Model {}
Report.init({
ReportId: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
UserId: {
type: DataTypes.INTEGER,
allowNull: false,
},
ReportDate: {
type: DataTypes.DATE,
allowNull: false,
},
ReportContent: {
type: DataTypes.TEXT,
allowNull: false,
},
}, {
sequelize,
modelName: 'Report',
timestamps: true,
});
module.exports = Report;

Repositories

Create repository files for each model in the repositories directory.

repositories/ContentRepository.js:


const Content = require('../models/Content');
class ContentRepository {
async create(contentData) {
return await Content.create(contentData);
}
async findAll() {
return await Content.findAll();
}
async findById(id) {
return await Content.findByPk(id);
}
async update(id, contentData) {
const content = await this.findById(id);
if (content) {
return await content.update(contentData);
}
return null;
}
async delete(id) {
const content = await this.findById(id);
if (content) {
return await content.destroy();
}
return null;
}
}
module.exports = new ContentRepository();

repositories/ScheduleRepository.js:


const Schedule = require('../models/Schedule');
class ScheduleRepository {
async create(scheduleData) {
return await Schedule.create(scheduleData);
}
async findAll() {
return await Schedule.findAll();
}
async findById(id) {
return await Schedule.findByPk(id);
}
async update(id, scheduleData) {
const schedule = await this.findById(id);
if (schedule) {
return await schedule.update(scheduleData);
}
return null;
}
async delete(id) {
const schedule = await this.findById(id);
if (schedule) {
return await schedule.destroy();
}
return null;
}
}
module.exports = new ScheduleRepository();

repositories/EnrollmentRepository.js:


const Enrollment = require('../models/Enrollment');
class EnrollmentRepository {
async create(enrollmentData) {
return await Enrollment.create(enrollmentData);
}
async findAll() {
return await Enrollment.findAll();
}
async findById(id) {
return await Enrollment.findByPk(id);
}
async update(id, enrollmentData) {
const enrollment = await this.findById(id);
if (enrollment) {
return await enrollment.update(enrollmentData);
}
return null;
}
async delete(id) {
const enrollment = await this.findById(id);
if (enrollment) {
return await enrollment.destroy();
}
return null;
}
}
module.exports = new EnrollmentRepository();

repositories/AttendanceRepository.js:


const Attendance = require('../models/Attendance');
class AttendanceRepository {
async create(attendanceData) {
return await Attendance.create(attendanceData);
}
async findAll() {
return await Attendance.findAll();
}
async findById(id) {
return await Attendance.findByPk(id);
}
async update(id, attendanceData) {
const attendance = await this.findById(id);
if (attendance) {
return await attendance.update(attendanceData);
}
return null;
}
async delete(id) {
const attendance = await this.findById(id);
if (attendance) {
return await attendance.destroy();
}
return null;
}
}
module.exports = new AttendanceRepository();

repositories/AssessmentRepository.js:


const Assessment = require('../models/Assessment');
class AssessmentRepository {
async create(assessmentData) {
return await Assessment.create(assessmentData);
}
async findAll() {
return await Assessment.findAll();
}
async findById(id) {
return await Assessment.findByPk(id);
}
async update(id, assessmentData) {
const assessment = await this.findById(id);
if (assessment) {
return await assessment.update(assessmentData);
}
return null;
}
async delete(id) {
const assessment = await this.findById(id);
if (assessment) {
return await assessment.destroy();
}
return null;
}
}
module.exports = new AssessmentRepository();

repositories/FeedbackRepository.js:


const Feedback = require('../models/Feedback');
class FeedbackRepository {
async create(feedbackData) {
return await Feedback.create(feedbackData);
}
async findAll() {
return await Feedback.findAll();
}
async findById(id) {
return await Feedback.findByPk(id);
}
async update(id, feedbackData) {
const feedback = await this.findById(id);
if (feedback) {
return await feedback.update(feedbackData);
}
return null;
}
async delete(id) {
const feedback = await this.findById(id);
if (feedback) {
return await feedback.destroy();
}
return null;
}
}
module.exports = new FeedbackRepository();

repositories/NotificationRepository.js:


const Notification = require('../models /Notification');
class NotificationRepository {
async create(notificationData) {
return await Notification.create(notificationData);
}
async findAll() {
return await Notification.findAll();
}
async findById(id) {
return await Notification.findByPk(id);
}
async update(id, notificationData) {
const notification = await this.findById(id);
if (notification) {
return await notification.update(notificationData);
}
return null;
}
async delete(id) {
const notification = await this.findById(id);
if (notification) {
return await notification.destroy();
}
return null;
}
}
module.exports = new NotificationRepository();

repositories/ResourceRepository.js:


const Resource = require('../models/Resource');
class ResourceRepository {
async create(resourceData) {
return await Resource.create(resourceData);
}
async findAll() {
return await Resource.findAll();
}
async findById(id) {
return await Resource.findByPk(id);
}
async update(id, resourceData) {
const resource = await this.findById(id);
if (resource) {
return await resource.update(resourceData);
}
return null;
}
async delete(id) {
const resource = await this.findById(id);
if (resource) {
return await resource.destroy();
}
return null;
}
}
module.exports = new ResourceRepository();

repositories/ReportRepository.js:


const Report = require('../models/Report');
class ReportRepository {
async create(reportData) {
return await Report.create(reportData);
}
async findAll() {
return await Report.findAll();
}
async findById(id) {
return await Report.findByPk(id);
}
async update(id, reportData) {
const report = await this.findById(id);
if (report) {
return await report.update(reportData);
}
return null;
}
async delete(id) {
const report = await this.findById(id);
if (report) {
return await report.destroy();
}
return null;
}
}
module.exports = new ReportRepository();

Controllers

Create controller files for each model in the controllers directory.

controllers/ContentController.js:


const ContentRepository = require('../repositories/ContentRepository');
class ContentController {
async create(req, res) {
await ContentRepository.create(req.body);
res.redirect('/contents');
}
async findAll(req, res) {
const contents = await ContentRepository.findAll();
res.render('contents/index', { contents });
}
async findById(req, res) {
const content = await ContentRepository.findById(req.params.id);
res.render('contents/edit', { content });
}
async update(req, res) {
await ContentRepository.update(req.params.id, req.body);
res.redirect('/contents');
}
async delete(req, res) {
await ContentRepository.delete(req.params.id);
res.redirect('/contents');
}
}
module.exports = new ContentController();

controllers/ScheduleController.js:


const ScheduleRepository = require('../repositories/ScheduleRepository');
class ScheduleController {
async create(req, res) {
await ScheduleRepository.create(req.body);
res.redirect('/schedules');
}
async findAll(req, res) {
const schedules = await ScheduleRepository.findAll();
res.render('schedules/index', { schedules });
}
async findById(req, res) {
const schedule = await ScheduleRepository.findById(req.params.id);
res.render('schedules/edit', { schedule });
}
async update(req, res) {
await ScheduleRepository.update(req.params.id, req.body);
res.redirect('/schedules');
}
async delete(req, res) {
await ScheduleRepository.delete(req.params.id);
res.redirect('/schedules');
}
}
module.exports = new ScheduleController();

controllers/EnrollmentController.js:


const EnrollmentRepository = require('../repositories/EnrollmentRepository');
class EnrollmentController {
async create(req, res) {
await EnrollmentRepository.create(req.body);
res.redirect('/enrollments');
}
async findAll(req, res) {
const enrollments = await EnrollmentRepository.findAll();
res.render('enrollments/index', { enrollments });
}
async findById(req, res) {
const enrollment = await EnrollmentRepository.findById(req.params.id);
res.render('enrollments/edit', { enrollment });
}
async update(req, res) {
await EnrollmentRepository.update(req.params.id, req.body);
res.redirect('/enrollments');
}
async delete(req, res) {
await EnrollmentRepository.delete (req.params.id);
res.redirect('/enrollments');
}
}
module.exports = new EnrollmentController();

controllers/AttendanceController.js:


const AttendanceRepository = require('../repositories/AttendanceRepository');
class AttendanceController {
async create(req, res) {
await AttendanceRepository.create(req.body);
res.redirect('/attendances');
}
async findAll(req, res) {
const attendances = await AttendanceRepository.findAll();
res.render('attendances/index', { attendances });
}
async findById(req, res) {
const attendance = await AttendanceRepository.findById(req.params.id);
res.render('attendances/edit', { attendance });
}
async update(req, res) {
await AttendanceRepository.update(req.params.id, req.body);
res.redirect('/attendances');
}
async delete(req, res) {
await AttendanceRepository.delete(req.params.id);
res.redirect('/attendances');
}
}
module.exports = new AttendanceController();

controllers/AssessmentController.js:


const AssessmentRepository = require('../repositories/AssessmentRepository');
class AssessmentController {
async create(req, res) {
await AssessmentRepository.create(req.body);
res.redirect('/assessments');
}
async findAll(req, res) {
const assessments = await AssessmentRepository.findAll();
res.render('assessments/index', { assessments });
}
async findById(req, res) {
const assessment = await AssessmentRepository.findById(req.params.id);
res.render('assessments/edit', { assessment });
}
async update(req, res) {
await AssessmentRepository.update(req.params.id, req.body);
res.redirect('/assessments');
}
async delete(req, res) {
await AssessmentRepository.delete(req.params.id);
res.redirect('/assessments');
}
}
module.exports = new AssessmentController();

controllers/FeedbackController.js:


const FeedbackRepository = require('../repositories/FeedbackRepository');
class FeedbackController {
async create(req, res) {
await FeedbackRepository.create(req.body);
res.redirect('/feedbacks');
}
async findAll(req, res) {
const feedbacks = await FeedbackRepository.findAll();
res.render('feedbacks/index', { feedbacks });
}
async findById(req, res) {
const feedback = await FeedbackRepository.findById(req.params.id);
res.render('feedbacks/edit', { feedback });
}
async update(req, res) {
await FeedbackRepository.update(req.params.id, req.body);
res.redirect('/feedbacks');
}
async delete(req, res) {
await FeedbackRepository.delete(req.params.id);
res.redirect('/feedbacks');
}
}
module.exports = new FeedbackController();

controllers/NotificationController.js:


const NotificationRepository = require('../repositories/NotificationRepository');
class NotificationController {
async create(req, res) {
await NotificationRepository.create(req.body);
res.redirect('/notifications');
}
async findAll(req, res) {
const notifications = await NotificationRepository.findAll();
res.render('notifications/index', { notifications });
}
async findById(req, res) {
const notification = await NotificationRepository.findById(req.params.id);
res.render('notifications/edit', { notification });
}
async update(req, res) {
await NotificationRepository.update(req.params.id, req.body);
res.redirect('/notifications');
}
async delete(req, res) {
await NotificationRepository.delete(req.params.id);
res.redirect('/notifications');
}
}
module.exports = new NotificationController();

controllers/ResourceController.js:


const ResourceRepository = require('../repositories/ResourceRepository');
class ResourceController {
async create(req, res) {
await ResourceRepository.create(req.body);
res.redirect('/resources');
}
async findAll(req, res) {
const resources = await ResourceRepository.findAll();
res.render('resources/index', { resources });
}
async findById(req, res) {
const resource = await ResourceRepository.findById(req.params.id);
res.render('resources/edit', { resource });
}
async update(req, res) {
await ResourceRepository.update(req.params.id, req.body);
res.redirect('/resources');
}
async delete(req, res) {
await ResourceRepository.delete(req.params.id);
res.redirect('/resources');
}
}
module.exports = new ResourceController();

controllers/ReportController.js:


const ReportRepository = require('../repositories/ReportRepository');
class ReportController {
async create(req, res) {
await ReportRepository.create(req.body);
res.redirect('/reports');
}
async findAll(req, res) {
const reports = await ReportRepository.findAll();
res .render('reports/index', { reports });
}
async findById(req, res) {
const report = await ReportRepository.findById(req.params.id);
res.render('reports/edit', { report });
}
async update(req, res) {
await ReportRepository.update(req.params.id, req.body);
res.redirect('/reports');
}
async delete(req, res) {
await ReportRepository.delete(req.params.id);
res.redirect('/reports');
}
}
module.exports = new ReportController();

Routes

Create route files for each model in the routes directory.

routes/contentRoutes.js:


const express = require('express');
const router = express.Router();
const ContentController = require('../controllers/ContentController');
router.get('/', ContentController.findAll);
router.get('/create', (req, res) => res.render('contents/create'));
router.post('/', ContentController.create);
router.get('/:id/edit', ContentController.findById);
router.post('/:id', ContentController.update);
router.post('/:id/delete', ContentController.delete);
module.exports = router;

routes/scheduleRoutes.js:


const express = require('express');
const router = express.Router();
const ScheduleController = require('../controllers/ScheduleController');
router.get('/', ScheduleController.findAll);
router.get('/create', (req, res) => res.render('schedules/create'));
router.post('/', ScheduleController.create);
router.get('/:id/edit', ScheduleController.findById);
router.post('/:id', ScheduleController.update);
router.post('/:id/delete', ScheduleController.delete);
module.exports = router;

routes/enrollmentRoutes.js:


const express = require('express');
const router = express.Router();
const EnrollmentController = require('../controllers/EnrollmentController');
router.get('/', EnrollmentController.findAll);
router.get('/create', (req, res) => res.render('enrollments/create'));
router.post('/', EnrollmentController.create);
router.get('/:id/edit', EnrollmentController.findById);
router.post('/:id', EnrollmentController.update);
router.post('/:id/delete', EnrollmentController.delete);
module.exports = router;

routes/attendanceRoutes.js:


const express = require('express');
const router = express.Router();
const AttendanceController = require('../controllers/AttendanceController');
router.get('/', AttendanceController.findAll);
router.get('/create', (req, res) => res.render('attendances/create'));
router.post('/', AttendanceController.create);
router.get('/:id/edit', AttendanceController.findById);
router.post('/:id', AttendanceController.update);
router.post('/:id/delete', AttendanceController.delete);
module.exports = router;

routes/assessmentRoutes.js:


const express = require('express');
const router = express.Router();
const AssessmentController = require('../controllers/AssessmentController');
router.get('/', AssessmentController.findAll);
router.get('/create', (req, res) => res.render('assessments/create'));
router.post('/', AssessmentController.create);
router.get('/:id/edit', AssessmentController.findById);
router.post('/:id', AssessmentController.update);
router.post('/:id/delete', AssessmentController.delete);
module.exports = router;

routes/feedbackRoutes.js:


const express = require('express');
const router = express.Router();
const FeedbackController = require('../controllers/FeedbackController');
router.get('/', FeedbackController.findAll);
router.get('/create', (req, res) => res.render('feedbacks/create'));
router.post('/', FeedbackController.create);
router.get('/:id/edit', FeedbackController.findById);
router.post('/:id', FeedbackController.update);
router.post('/:id/delete', FeedbackController.delete);
module.exports = router;

routes/notificationRoutes.js:


const express = require('express');
const router = express.Router();
const NotificationController = require('../controllers/NotificationController');
router.get('/', NotificationController.findAll);
router.get('/create', (req, res) => res.render('notifications/create'));
router.post('/', NotificationController.create);
router.get('/:id/edit', NotificationController.findById);
router.post('/:id', NotificationController.update);
router.post('/:id/delete', NotificationController.delete);
module.exports = router;

routes/resourceRoutes.js:


const express = require('express');
const router = express.Router();
const ResourceController = require('../controllers/ResourceController');
router.get('/', ResourceController.findAll);
router.get('/create', (req, res) => res.render('resources/create'));
router.post('/', ResourceController.create);
router.get('/:id/edit', ResourceController.findById);
router.post('/:id', ResourceController.update);
router.post('/:id/delete', ResourceController.delete);
module.exports = router;

routes/reportRoutes.js:


const express = require('express');
const router = express.Router();
const ReportController = require('../controllers/ReportController');
router.get('/', ReportController.findAll);
router.get('/create', (req, res) =>res.render('reports/create'));
router.post('/', ReportController.create);
router.get('/:id/edit', ReportController.findById);
router.post('/:id', ReportController.update);
router.post('/:id/delete', ReportController.delete);
module.exports = router;

Views

Create EJS view files for each model in the views directory.

views/contents/index.ejs:


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<title>Contents</title>
</head>
<body>
<div class="container">
<h1>Contents</h1>
<a href="/contents/create" class="btn btn-primary">Create Content</a>
<table class="table">
<thead>
<tr>
<th>Content Type</th>
<th>Content Link</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<% contents.forEach(content => { %>
<tr>
<td><%= content.ContentType %></td>
<td><%= content.ContentLink %></td>
<td>
<a href="/contents/<%= content.ContentId %>/edit" class="btn btn-warning">Edit</a>
<form action="/contents/<%= content.ContentId %>/delete" method="POST" style="display:inline;">
<button type="submit" class="btn btn-danger">Delete</button>
</form>
</td>
</tr>
<% }) %>
</tbody>
</table>
</div>
</body>
</html>

views/contents/create.ejs:


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<title>Create Content</title>
</head>
<body>
<div class="container">
<h1>Create Content</h1>
<form action="/contents" method="POST">
<div class="mb-3">
<label for="CourseId" class="form-label">Course ID</label>
<input type="number" class="form-control" id="CourseId" name="CourseId" required>
</div>
<div class="mb-3">
<label for="ContentType" class="form-label">Content Type</label>
<input type="text" class="form-control" id="ContentType" name="ContentType" required>
</div>
<div class="mb-3">
<label for="ContentLink" class="form-label">Content Link</label>
<input type="text" class="form-control" id="ContentLink" name="ContentLink">
</div>
<button type="submit" class="btn btn-primary">Create Content</button>
</form>
</div>
</body>
</html>

views/schedules/index.ejs:


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<title>Schedules</title>
</head>
<body>
<div class="container">
<h1>Schedules</h1>
<a href="/schedules/create" class="btn btn-primary">Create Schedule</a>
<table class="table">
<thead>
<tr>
<th>Course ID</th>
<th>Start Date</th>
<th>End Date</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<% schedules.forEach(schedule => { %>
<tr>
<td><%= schedule.CourseId %></td>
<td><%= schedule.StartDate.toLocaleDateString() %></td>
<td><%= schedule.EndDate.toLocaleDateString() %></td>
<td>
<a href="/schedules/<%= schedule.ScheduleId %>/edit" class="btn btn-warning">Edit</a>
<form action="/schedules/<%= schedule.ScheduleId %>/delete" method="POST" style="display:inline;">
<button type="submit" class="btn btn-danger">Delete</button>
</form>
</td>
</tr>
<% }) %>
</tbody>
</table>
</div>
</body>
</html>

views/schedules/create.ejs:


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<title>Create Schedule</title>
</head>
<body>
<div class="container">
<h1>Create Schedule</h1>
<form action="/schedules" method="POST">
<div class="mb-3">
<label for="CourseId" class="form-label">Course ID</label>
<input type="number" class="form-control" id="CourseId" name="CourseId" required>
</div>
<div class="mb-3">
<label for="StartDate" class="form-label">Start Date</label>
<input type="date" class="form-control" id="StartDate" name="StartDate" required>
</div>
<div class="mb-3">
<label for="EndDate" class="form-label">End Date</label>
<input type="date" class="form-control" id="EndDate" name="EndDate" required>
</div>
<button type="submit" class="btn btn-primary">Create Schedule</button>
</form>
</div>
</body>
</html>

views/enrollments/index.ejs:


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<title>Enrollments</title>
</head>
<body>
<div class="container">
<h1>Enrollments</h1>
<a href="/enrollments/create" class="btn btn-primary">Create Enrollment</a>
<table class="table">
<thead>
<tr>
<th>User ID</th>
<th>Course ID</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<% enrollments.forEach(enrollment => { %>
<tr>
<td><%= enrollment.UserId %></td>
<td><%= enrollment.CourseId %></td>
<td><%= enrollment.Status %></td>
<td>
<a href="/enrollments/<%= enrollment.EnrollmentId %>/edit" class="btn btn-warning">Edit</a>
<form action="/enrollments/<%= enrollment.EnrollmentId %>/delete" method="POST" style="display:inline;">
<button type="submit" class="btn btn-danger">Delete</button>
</form>
</td>
</tr>
<% }) %>
</tbody>
</table>
</div>
</body>
</html>

views/enrollments/create.ejs:


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<title>Create Enrollment</title>
</head>
<body>
<div class="container">
<h1>Create Enrollment</h1>
<form action="/enrollments" method="POST">
<div class="mb-3">
<label for="User Id" class="form-label">User ID</label>
<input type="number" class="form-control" id="User Id" name="User Id" required>
</div>
<div class="mb-3">
<label for="CourseId" class="form-label">Course ID</label>
<input type="number" class="form-control" id="CourseId" name="CourseId" required>
</div>
<div class="mb-3">
<label for="Status" class="form-label">Status</label>
<input type="text" class="form-control" id="Status" name="Status" required>
</div>
<button type="submit" class="btn btn-primary">Create Enrollment</button>
</form>
</div>
</body>
</html>

views/attendances/index.ejs:


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<title>Attendances</title>
</head>
<body>
<div class="container">
<h1>Attendances</h1>
<a href="/attendances/create" class="btn btn-primary">Create Attendance</a>
<table class="table">
<thead>
<tr>
<th>Enrollment ID</th>
<th>Attendance Date</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<% attendances.forEach(attendance => { %>
<tr>
<td><%= attendance.EnrollmentId %></td>
<td><%= attendance.AttendanceDate.toLocaleDateString() %></td>
<td><%= attendance.Status %></td>
<td>
<a href="/attendances/<%= attendance.AttendanceId %>/edit" class="btn btn-warning">Edit</a>
<form action="/attendances/<%= attendance.AttendanceId %>/delete" method="POST" style="display:inline;">
<button type="submit" class="btn btn-danger">Delete</button>
</form>
</td>
</tr>
<% }) %>
</tbody>
</table>
</div>
</body>
</html>

views/attendances/create.ejs:


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<title>Create Attendance</title>
</head>
<body>
<div class="container">
<h1>Create Attendance</h1>
<form action="/attendances" method="POST">
<div class="mb-3">
<label for="EnrollmentId" class="form-label">Enrollment ID</label>
<input type="number" class="form-control" id="EnrollmentId" name="EnrollmentId" required>
</div>
<div class="mb-3">
<label for="AttendanceDate" class="form-label">Attendance Date</label>
<input type="date" class="form-control" id="AttendanceDate" name="AttendanceDate" required>
</div>
<div class="mb-3">
<label for="Status" class="form-label">Status</label>
<input type="text" class="form-control" id="Status" name="Status" required>
</div>
<button type="submit" class="btn btn-primary">Create Attendance</button>
</form>
</div>
</body>
</html>

views/assessments/index.ejs:


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<title>Assessments</title>
</head>
<body>
<div class="container">
<h1>Assessments</h1>
<a href="/assessments/create" class="btn btn-primary">Create Assessment</a>
<table class="table">
<thead>
<tr>
<th>Course ID</th>
<th>Assessment Type</th>
<th>Total Marks</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<% assessments.forEach(assessment => { %>
<tr>
<td><%= assessment.CourseId %></td>
<td><%= assessment.AssessmentType %></td>
<td><%= assessment.TotalMarks %></td>
<td>
<a href="/assessments/<%= assessment.AssessmentId %>/edit" class="btn btn-warning">Edit</a>
<form action="/assessments/<%= assessment.AssessmentId %>/delete" method="POST" style="display:inline;">
<button type="submit" class="btn btn-danger">Delete</button>
</form>
</td>
</tr>
<% }) %>
</tbody>
</table>
</div>
</body>
</html>

views/assessments/create.ejs:


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<title>Create Assessment</title>
</head>
<body>
<div class="container">
<h1>Create Assessment</h1>
<form action="/assessments" method="POST">
<div class="mb-3">
<label for="CourseId" class="form-label">Course ID</label>
<input type="number" class="form-control" id="CourseId" name="CourseId" required>
</div>
<div class="mb-3">
<label for="AssessmentType" class="form-label">Assessment Type</label>
<input type="text" class="form-control" id="AssessmentType" name="AssessmentType" required>
</div>
<div class="mb-3">
<label for="TotalMarks" class="form-label">Total Marks</label>
<input type="number" class="form-control" id="TotalMarks" name="TotalMarks" required>
</div>
<button type="submit" class="btn btn-primary">Create Assessment</button>
</form>
</div>
</body>
</html>

views/feedbacks/index.ejs:


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<title>Feedbacks</title>
</head>
<body>
<div class="container">
<h1>Feedbacks</h1>
<a href="/feedbacks/create" class="btn btn-primary">Create Feedback</a>
<table class="table">
<thead>
<tr>
<th>User ID</th>
<th>Course ID</th>
<th>Feedback Content</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<% feedbacks.forEach(feedback => { %>
<tr>
<td><%= feedback.UserId %></td>
<td><%= feedback.CourseId %></td>
<td><%= feedback.FeedbackContent %></td>
<td>
<a href="/feedbacks/<%= feedback.FeedbackId %>/edit" class="btn btn-warning">Edit</a>
<form action="/feedbacks/<%= feedback.FeedbackId %>/delete" method="POST" style="display:inline;">
<button type="submit" class="btn btn-danger">Delete</button>
</form>
</td>
</tr>
<% }) %>
</tbody>
</table>
</div>
</body>
</html>

views/feedbacks/create.ejs:


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<title>Create Feedback</title>
</head>
<body>
<div class="container">
<h1>Create Feedback</h1>
<form action="/feedbacks" method="POST">
<div class="mb-3">
<label for="User Id" class="form-label">User ID</label>
<input type="number" class="form-control" id="User Id" name="User Id" required>
</div>
<div class="mb-3">
<label for="CourseId" class="form-label">Course ID</label>
<input type="number" class="form-control" id="CourseId" name="CourseId" required>
</div>
<div class="mb-3">
<label for="FeedbackContent" class="form-label">Feedback Content</label>
<textarea class="form-control" id="FeedbackContent" name="FeedbackContent" required></textarea>
</div>
< button type="submit" class="btn btn-primary">Create Feedback</button>
</form>
</div>
</body>
</html>

views/notifications/index.ejs:


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<title>Notifications</title>
</head>
<body>
<div class="container">
<h1>Notifications</h1>
<a href="/notifications/create" class="btn btn-primary">Create Notification</a>
<table class="table">
<thead>
<tr>
<th>User ID</th>
<th>Message</th>
<th>Is Read</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<% notifications.forEach(notification => { %>
<tr>
<td><%= notification.UserId %></td>
<td><%= notification.Message %></td>
<td><%= notification.IsRead ? 'Yes' : 'No' %></td>
<td>
<a href="/notifications/<%= notification.NotificationId %>/edit" class="btn btn-warning">Edit</a>
<form action="/notifications/<%= notification.NotificationId %>/delete" method="POST" style="display:inline;">
<button type="submit" class="btn btn-danger">Delete</button>
</form>
</td>
</tr>
<% }) %>
</tbody>
</table>
</div>
</body>
</html>

views/notifications/create.ejs:


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<title>Create Notification</title>
</head>
<body>
<div class="container">
<h1>Create Notification</h1>
<form action="/notifications" method="POST">
<div class="mb-3">
<label for="User Id" class="form-label">User ID</label>
<input type="number" class="form-control" id="User Id" name="User Id" required>
</div>
<div class="mb-3">
<label for="Message" class="form-label">Message</label>
<input type="text" class="form-control" id="Message" name="Message" required>
</div>
<button type="submit" class="btn btn-primary">Create Notification</button>
</form>
</div>
</body>
</html>

views/resources/index.ejs:


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<title>Resources</title>
</head>
<body>
<div class="container">
<h1>Resources</h1>
<a href="/resources/create" class="btn btn-primary">Create Resource</a>
<table class="table">
<thead>
<tr>
<th>Course ID</th>
<th>Resource Name</th>
<th>Resource Link</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<% resources.forEach(resource => { %>
<tr>
<td><%= resource.CourseId %></td>
<td><%= resource.ResourceName %></td>
<td><%= resource.ResourceLink %></td>
<td>
<a href="/resources/<%= resource.ResourceId %>/edit" class="btn btn-warning">Edit</a>
<form action="/resources/<%= resource.ResourceId %>/delete" method="POST" style="display:inline;">
<button type="submit" class="btn btn-danger">Delete</button>
</form>
</td>
</tr>
<% }) %>
</tbody>
</table>
</div>
</body>
</html>

views/resources/create.ejs:


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<title>Create Resource</title>
</head>
<body>
<div class="container">
<h1>Create Resource</h1>
<form action="/resources" method="POST">
<div class="mb-3">
<label for="CourseId" class="form-label">Course ID</label>
<input type="number" class="form-control" id="CourseId" name="CourseId" required>
</div>
<div class="mb-3">
<label for="ResourceName" class="form-label">Resource Name</label>
<input type="text" class="form-control" id="ResourceName" name="ResourceName" required>
</div>
<div class="mb-3">
<label for="ResourceLink" class="form-label">Resource Link</label>
<input type="text" class="form-control" id="ResourceLink" name="ResourceLink">
</div>
<button type="submit" class="btn btn-primary">Create Resource</button>
</form>
</div>
</body>
</html>

views/reports/index.ejs:


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<title>Reports</title>
</head>
<body>
<div class="container">
<h1>Reports</h1>
<a href="/reports/create" class="btn btn-primary">Create Report</a>
<table class="table">
<thead>
<tr>
<th>User ID</th>
<th>Report Date</th>
<th>Report Content</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<% reports.forEach(report => { %>
<tr>
<td><%= report.UserId %></td>
<td><%= report.ReportDate.toLocaleDateString() %></td>
<td><%= report.ReportContent %></td>
<td>
<a href="/reports/<%= report.ReportId %>/edit" class="btn btn-warning">Edit</a>
<form action="/reports/<%= report.ReportId %>/delete" method="POST" style="display:inline;">
<button type="submit" class="btn btn-danger">Delete</button>
</form>
</td>
</tr>
<% }) %>
</tbody>
</table>
</div>
</body>
</html>

views/reports/create.ejs:


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<title>Create Report</title>
</head>
<body>
<div class="container">
<h1>Create Report</h1>
<form action="/reports" method="POST">
<div class="mb-3">
<label for="User Id" class="form-label">User ID</label>
<input type="number" class="form-control" id="User Id" name="User Id" required>
</div>
<div class="mb-3">
<label for="ReportDate" class="form-label">Report Date</label>
<input type="date" class="form-control" id="ReportDate" name="ReportDate" required>
</div>
<div class="mb-3">
<label for="ReportContent" class="form-label">Report Content</label>
<textarea class="form-control" id="ReportContent" name="ReportContent" required></textarea>
</div>
<button type="submit" class="btn btn-primary">Create Report</button>
</form>
</div>
</body>
</html>

Final Integration

Ensure that all routes are integrated into your main application file (app.js), and that the server is set up to listen for incoming requests.

app.js:


const express = require('express');
const bodyParser = require('body-parser');
const contentRoutes = require('./routes/contentRoutes');
const scheduleRoutes = require('./routes/scheduleRoutes');
const enrollmentRoutes = require('./routes/enrollmentRoutes');
const attendanceRoutes = require('./routes/attendanceRoutes');
const assessmentRoutes = require('./routes/assessmentRoutes');
const feedbackRoutes = require('./routes/feedbackRoutes');
const notificationRoutes = require('./routes/notificationRoutes');
const resourceRoutes = require('./routes/resourceRoutes');
const reportRoutes = require('./routes/reportRoutes');
const sequelize = require('./config/database');
const app = express();
const PORT = process.env.PORT || 3000;
app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({ extended: true }));
app.use('/contents', contentRoutes);
app.use('/schedules', scheduleRoutes);
app.use('/enrollments', enrollmentRoutes);
app.use('/attendances', attendanceRoutes);
app.use('/assessments', assessmentRoutes);
app.use('/feedbacks', feedbackRoutes);
app.use('/notifications', notificationRoutes);
app.use('/resources', resourceRoutes);
app.use('/reports', reportRoutes);
sequelize.sync().then(() => {
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});
}).catch(err => {
console.error('Unable to connect to the database:', err);
});

With this setup, you will have a fully functional Node.js application

with complete CRUD operations for all specified models using Sequelize, Express, and EJS with Bootstrap 5 templates. Each model has its own repository, controller, routes, and views, allowing for efficient management of the data.

Folder Structure for NodeJS & ExpressJS project

Creating a Dashboard Page

To create a dashboard page in Node.js that displays consolidated project data using EJS and Bootstrap 5, you will need to set up a controller, routes, and the EJS view.

Controller: Create a DashboardController that fetches the necessary data from your models and prepares it for rendering.

Routes: Set up a route for the dashboard that points to the controller method.

EJS View: Create an EJS file that uses Bootstrap 5 to display the data in a visually appealing way.

This structure will allow you to effectively manage and display your project's consolidated data on the dashboard.

Dashboard Controller

controllers/DashboardController.js:


const ContentRepository = require('../repositories/ContentRepository');
const ScheduleRepository = require('../repositories/ScheduleRepository');
const EnrollmentRepository = require('../repositories/EnrollmentRepository');
const AttendanceRepository = require('../repositories/AttendanceRepository');
const AssessmentRepository = require('../repositories/AssessmentRepository');
const FeedbackRepository = require('../repositories/FeedbackRepository');
const NotificationRepository = require('../repositories/NotificationRepository');
const ResourceRepository = require('../repositories/ResourceRepository');
const ReportRepository = require('../repositories/ReportRepository');
class DashboardController {
async showDashboard(req, res) {
const contents = await ContentRepository.findAll();
const schedules = await ScheduleRepository.findAll();
const enrollments = await EnrollmentRepository.findAll();
const attendances = await AttendanceRepository.findAll();
const assessments = await AssessmentRepository.findAll();
const feedbacks = await FeedbackRepository.findAll();
const notifications = await NotificationRepository.findAll();
const resources = await ResourceRepository.findAll();
const reports = await ReportRepository.findAll();
res.render('dashboard', {
contents,
schedules,
enrollments,
attendances,
assessments,
feedbacks,
notifications,
resources,
reports
});
}
}
module.exports = new DashboardController();

Dashboard Routes

routes/dashboardRoutes.js:


const express = require('express');
const router = express.Router();
const DashboardController = require('../controllers/DashboardController');
router.get('/', DashboardController.showDashboard);
module.exports = router;

EJS View for Dashboard

views/dashboard.ejs:


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<title>Dashboard</title>
</head>
<body>
<div class="container">
<h1 class="mt-4">Dashboard</h1>
<h2>Contents</h2>
<table class="table">
<thead>
<tr>
<th>Content Type</th>
<th>Content Link</th>
</tr>
</thead>
<tbody>
<% contents.forEach(content => { %>
<tr>
<td><%= content.ContentType %></td>
<td><%= content.ContentLink %></td>
</tr>
<% }) %>
</tbody>
</table>
<h2>Schedules</h2>
<table class="table">
<thead>
<tr>
<th>Course ID</th>
<th>Start Date</th>
<th>End Date</th>
</tr>
</thead>
<tbody>
<% schedules.forEach(schedule => { %>
<tr>
<td><%= schedule.CourseId %></td>
<td><%= schedule.StartDate.toLocaleDateString() %></td>
<td><%= schedule.EndDate.toLocaleDateString() %></td>
</tr>
<% }) %>
</tbody>
</table>
<h2>Enrollments</h2>
<table class="table">
<thead>
<tr>
<th>User ID</th>
<th>Course ID</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<% enrollments.forEach(enrollment => { %>
<tr>
<td><%= enrollment.UserId %></td>
<td><%= enrollment.CourseId %></td>
<td><%= enrollment.Status %></td>
</tr>
<% }) %>
</tbody>
</table>
<h2>Attendances</h2>
<table class="table">
<thead>
<tr>
<th>Enrollment ID</th>
<th>Attendance Date</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<% attendances.forEach(attendance => { %>
<tr>
<td><%= attendance.EnrollmentId %></td>
<td><%= attendance.AttendanceDate.toLocaleDateString() %></td>
<td><%= attendance.Status %></td>
</tr>
<% }) %>
</tbody>
</table>
<h2>Assessments</h2>
<table class="table">
<thead>
<tr>
<th>Course ID</th>
<th>Assessment Type</th>
<th>Total Marks</th>
</tr>
</thead>
<tbody>
<% assessments.forEach(assessment => { %>
<tr>
<td><%= assessment.CourseId %></td>
<td><%= assessment.AssessmentType %></td>
<td><%= assessment.TotalMarks %></td>
</tr>
<% }) %>
</tbody>
</table>
<h2>Feedbacks</h2>
<table class="table">
<thead>
<tr>
<th>User ID</th>
<th>Course ID</th>
<th>Feedback Content</th>
</tr>
</thead>
<tbody>
<% feedbacks.forEach(feedback => { %>
<tr>
<td><%= feedback.UserId %></td>
<td><%= feedback.CourseId %></td>
<td><%= feedback.FeedbackContent %></td>
</tr>
<% }) %>
</tbody>
</table>
<h2>Notifications</h2>
<table class="table">
<thead>
<tr>
<th>User ID</th>
<th>Message</th>
<th>Is Read</th>
</tr>
</thead>
<tbody>
<% notifications.forEach(notification => { %>
<tr>
<td><%= notification.UserId %></td>
<td><%= notification.Message %></td>
<td><%= notification.IsRead ? 'Yes' : 'No' %></td>
</tr>
<% }) %>
</tbody>
</table>
<h2>Resources</h2>
<table class="table">
<thead>
<tr>
<th>Course ID</th>
<th>Resource Name</th>
<th>Resource Link</th>
</tr>
</thead>
<tbody>
<% resources.forEach(resource => { %>
<tr>
<td><%= resource.CourseId %></td>
<td><%= resource.ResourceName %></td>
<td><%= resource.ResourceLink %></td>
</tr>
<% }) %>
</tbody>
</table>
<h2>Reports</h2>
<table class="table">
<thead>
<tr>
<th>User ID</th>
<th>Report Date</th>
<th>Report Content</th>
</tr>
</thead>
<tbody>
<% reports.forEach(report => { %>
<tr>
<td><%= report.UserId %></td>
<td><%= report.ReportDate.toLocaleDateString() %></td>
<td><%= report.ReportContent %></td>
</tr>
<% }) %>
</tbody>
</table>
</div>
</body>
</html>

Final Integration

Make sure to integrate the dashboard routes into your main application file (app.js):

app.js:


const express = require('express');
const bodyParser = require('body-parser');
const contentRoutes = require('./routes/contentRoutes');
const scheduleRoutes = require('./routes/scheduleRoutes');
const enrollmentRoutes = require('./routes/enrollmentRoutes');
const attendanceRoutes = require('./routes/attendanceRoutes');
const assessmentRoutes = require('./routes/assessmentRoutes');
const feedbackRoutes = require('./routes/feedbackRoutes');
const notificationRoutes = require('./routes/notificationRoutes');
const resourceRoutes = require('./routes/resourceRoutes');
const reportRoutes = require('./routes/reportRoutes');
const dashboardRoutes = require('./routes/dashboardRoutes'); // Add this line
const sequelize = require('./config/database');
const app = express();
const PORT = process.env.PORT || 3000;
app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({ extended: true }));
app.use('/contents', contentRoutes);
app.use('/schedules', scheduleRoutes);
app.use('/enrollments', enrollmentRoutes);
app.use('/attendances', attendanceRoutes);
app.use('/assessments', assessmentRoutes);
app.use('/feedbacks', feedbackRoutes);
app.use('/notifications', notificationRoutes);
app.use('/resources', resourceRoutes);
app.use('/reports', reportRoutes);
app.use('/dashboard', dashboardRoutes); // Add this line
sequelize.sync().then(() => {
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});
}).catch(err => {
console.error('Unable to connect to the database:', err);
});

With this setup, you will have a functional dashboard page

that consolidates and displays data from various models in your Node.js application. The dashboard will provide an overview of the project's key components, making it easier to manage and monitor the application's data.