Project Introduction

The Office Management System is a comprehensive web application designed to streamline the management of office operations, including document management, task assignments, project tracking, and attendance monitoring. Built using Node.js, this platform allows users to efficiently manage their daily activities and collaborate with colleagues. The system supports multiple user roles, including admin, manager, and employee, ensuring a tailored experience for each user type. The underlying MySQL database schema is structured to manage users, documents, tasks, projects, meetings, resources, attendance, expenses, and notifications, providing a robust foundation for effective office management.

Project Objectives

  • To develop a user-friendly interface for managing documents, tasks, and projects.
  • To implement a secure user authentication system for managing user roles and permissions.
  • To allow users to create, assign, and track tasks associated with various projects.
  • To facilitate scheduling and management of meetings, including details such as time and location.
  • To manage office resources, including equipment, rooms, and supplies.
  • To track employee attendance and manage leave statuses.
  • To handle expense reporting and approval processes.
  • To provide notifications for important updates and reminders.
  • 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. Document Management Module:

    This module allows users to upload, manage, and track documents, including version control.

  3. Task Management Module:

    This module facilitates the creation and assignment of tasks, allowing users to track progress and due dates.

  4. Project Management Module:

    This module enables users to create and manage projects, including project details and timelines.

  5. Meeting Management Module:

    This module allows users to schedule and manage meetings, including participants and locations.

  6. Resource Management Module:

    This module manages office resources, including equipment, rooms, and supplies, tracking their availability.

  7. Attendance Management Module:

    This module tracks employee attendance, including statuses for present, absent, and leave.

  8. Expense Management Module:

    This module handles expense reporting and approval processes for users.

  9. Notification Module:

    This module sends notifications to users regarding important updates, reminders, and alerts.

Steps Overview

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

Configure Sequelize: Set up Sequelize to connect to your MySQL database.

Define Models: Create Sequelize models based on the provided SQL tables.

Create Repositories: Implement repository functions for CRUD operations.

Set Up Controllers: Create controllers to handle requests and responses.

Define Routes: Set up routes to connect the controllers.

Create Views: Use EJS to create views for displaying data.

Implement Bootstrap 5: Style the views using Bootstrap 5.

Create a Dashboard: Create a dashboard to display consolidated data.

Step 1: Set Up the Project


mkdir asset-management-system
cd asset-management-system
npm init -y
npm install express sequelize mysql2 ejs body-parser

Step 2: Configure Sequelize

Create a file named config.js for database configuration.


// config.js
const { Sequelize } = require('sequelize');
const sequelize = new Sequelize('database_name', 'username', 'password', {
host: 'localhost',
dialect: 'mysql',
});

module.exports = sequelize;

Step 3: Define Models

Create a folder named models and create model files for each table.

models/User.js


const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config');
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;

models/Role.js


const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config');
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/Asset.js


const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config');
class Asset extends Model {}
Asset.init({
AssetId: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
AssetName: {
type: DataTypes.STRING(100),
allowNull: false,
},
AssetType: {
type: DataTypes.STRING(50),
allowNull: false,
},
PurchaseDate: {
type: DataTypes.DATE,
allowNull: false,
},
Status: {
type: DataTypes.STRING(20),
allowNull: false,
},
}, {
sequelize,
modelName: 'Asset',
timestamps: true,
});
module.exports = Asset;

models/InventoryItem.js


const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config');
class InventoryItem extends Model {}
InventoryItem.init({
InventoryItemId: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
ItemName: {
type: DataTypes.STRING(100),
allowNull: false,
},
Quantity: {
type: DataTypes.INTEGER,
allowNull: false,
},
Location: {
type: DataTypes.STRING(100),
},
}, {
sequelize,
modelName: 'InventoryItem',
timestamps: true,
});
module.exports = InventoryItem;

models/Document.js


const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config');
class Document extends Model {}
Document.init({
DocumentId: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
DocumentName: {
type: DataTypes.STRING(100),
allowNull: false,
},
DocumentType: {
type: DataTypes.STRING(50),
allowNull: false,
},
UploadedBy: {
type: DataTypes.INTEGER,
allowNull: false,
},
}, {
sequelize,
modelName: 'Document',
timestamps: true,
});
module.exports = Document;

models/Meeting.js


const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config');
class Meeting extends Model {}
Meeting.init({
MeetingId: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
MeetingTitle: {
type: DataTypes.STRING(100),
allowNull: false,
},
MeetingDate: {
type: DataTypes.DATE ,
allowNull: false,
},
CreatedBy: {
type: DataTypes.INTEGER,
allowNull: false,
},
}, {
sequelize,
modelName: 'Meeting',
timestamps: true,
});
module.exports = Meeting;

models/Task.js


const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config');
class Task extends Model {}
Task.init({
TaskId: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
TaskTitle: {
type: DataTypes.STRING(100),
allowNull: false,
},
AssignedTo: {
type: DataTypes.INTEGER,
allowNull: false,
},
DueDate: {
type: DataTypes.DATE,
allowNull: false,
},
Status: {
type: DataTypes.STRING(20),
allowNull: false,
},
}, {
sequelize,
modelName: 'Task',
timestamps: true,
});
module.exports = Task;

models/Attendance.js


const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config');
class Attendance extends Model {}
Attendance.init({
AttendanceId: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
UserId: {
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/Report.js


const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config');
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,
},
}, {
sequelize,
modelName: 'Report',
timestamps: true,
});
module.exports = Report;

models/Feedback.js


const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config');
class Feedback extends Model {}
Feedback.init({
FeedbackId: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
UserId: {
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');
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;

Step 4: Create Repositories

Create a folder named repositories and implement repository functions for CRUD operations.

repositories/userRepository.js


const User = require('../models/User');
class UserRepository {
async createUser (data) {
return await User.create(data);
}
async getAllUsers() {
return await User.findAll();
}
async getUser ById(id) {
return await User.findByPk(id);
}
async updateUser (id, data) {
const user = await this.getUser ById(id);
if (user) {
return await user.update(data);
}
return null;
}
async deleteUser (id) {
const user = await this.getUser ById(id);
if (user) {
await user.destroy();
return true;
}
return false;
}
}
module.exports = new UserRepository();

Step 5: Set Up Controllers

Create a folder named controllers and create controller files for handling requests.

controllers/userController.js


const userRepository = require('../repositories/userRepository');
class UserController {
async createUser (req, res) {
try {
const user = await userRepository.createUser (req.body);
res.status(201).json(user);
} catch (error) {
res.status(500).json({ error: 'Error creating user' });
}
}
async getAllUsers(req, res) {
try {
const users = await userRepository.getAllUsers();
res.status(200).json(users);
} catch (error) {
res.status(500).json({ error: 'Error fetching users' });
}
}
async getUser ById(req, res) {
try {
const user = await userRepository.getUser ById(req.params.id);
if (user) {
res.status(200).json(user);
} else {
res.status(404).json({ error: 'User not found' });
}
} catch (error) {
res.status(500).json({ error: 'Error fetching user' });
}
}
async updateUser (req, res) {
try {
const updatedUser = await userRepository.updateUser (req.params.id, req.body);
if (updatedUser ) {
res.status(200).json(updatedUser );
} else {
res.status(404).json({ error: 'User not found' });
}
} catch (error) {
res.status(500).json({ error: 'Error updating user' });
}
}
async deleteUser (req, res) {
try {
const success = await userRepository.deleteUser (req.params.id);
if (success) {
res.status(204).send();
} else {
res.status(404).json({ error: 'User not found' });
}
} catch (error) {
res.status(500).json({ error: 'Error deleting user' });
}
}
}
module.exports = new UserController();

Step 6: Define Routes

Create a folder named routes and set up routes for the user controller.

routes/userRoutes.js


const express = require('express');
const router = express.Router();
const userController = require('../controllers/userController');
router.post('/', userController.createUser );
router.get('/', userController.getAllUsers);
router.get('/:id', userController.getUser ById);
router.put('/:id', userController.updateUser );
router.delete('/:id', userController.deleteUser );
module.exports = router;

Step 7: Create Views

Create a folder named views and create EJS files for displaying user data.

views/users.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>User Management</title>
</head>
<body>
<div class="container">
<h1 class="mt-4">User Management</h1>
<table class="table mt-4">
<thead>
<tr>
<th>User ID</th>
<th>Username</th>
<th>Email</th>
<th>First Name</th>
<th>Last Name</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<% users.forEach(user => { %>
<tr>
<td><%= user.UserId %></td>
<td><%= user.Username %></td>
<td><%= user.Email %></td>
<td><%= user.FirstName %></td>
<td><%= user.LastName %></td>
<td>
<a href="/users/<%= user.UserId %>/edit" class="btn btn-warning">Edit</a>
<form action="/users/<%= user.UserId %>" method="POST" style="display:inline;">
<input type="hidden" name="_method" value="DELETE">
<button type="submit" class="btn btn-danger">Delete</button>
</form>
</td>
</tr>
<% }) %>
</tbody>
</table>
<a href="/users/new" class="btn btn-primary">Add User</a>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

Step 8: Implement Bootstrap 5

Ensure that all views utilize Bootstrap 5 for styling, as shown in the user management view above.

Step 9: Create a Dashboard

Create a dashboard view to display consolidated data related to users, roles, assets, and other entities.

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>
<div class="row mt-4">
<div class="col-md-3">
<div class="card text-white bg-primary mb-3">
<div class="card-header">Total Users</div>
<div class="card-body">
<h5 class="card-title"><%= userCount %></h5>
<p class="card-text">Total number of registered users.</p>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card text-white bg-success mb-3">
<div class="card-header">Total Roles</div>
<div class="card-body">
<h5 class="card-title"><%= roleCount %></h5>
<p class="card-text">Total roles defined in the system.</p>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card text-white bg-info mb-3">
<div class="card-header">Total Assets</div>
<div class="card-body">
<h5 class="card-title"><%= assetCount %></h5>
<p class="card-text">Total assets managed.</p>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card text-white bg-warning mb-3">
<div class="card-header">Total Inventory Items</div>
<div class="card-body">
<h5 class="card-title"><%= inventoryItemCount %></h5>
<p class="card-text">Total inventory items available.</p>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

Step 10: Update the Main Application

In your main application file (e.g., index.js), integrate the user routes and dashboard route.


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

Run the Application

Start your application by running node index.js in your terminal.

Access the User Management: Open your browser and navigate to http://localhost:3000/users to manage users.

Access the Dashboard: Navigate to http://localhost:3000/dashboard to view the consolidated data.

This completes the implementation of a complete CRUD application for an asset management system using Node.js, Sequelize, Express, EJS, and Bootstrap 5.

Define Remaining Models

Create model files for each remaining table in the models directory.

models/Role.js


const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config');
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/Asset.js


const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config');
class Asset extends Model {}
Asset.init({
AssetId: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
AssetName: {
type: DataTypes.STRING(100),
allowNull: false,
},
AssetType: {
type: DataTypes.STRING(50),
allowNull: false,
},
PurchaseDate: {
type: DataTypes.DATE,
allowNull: false,
},
Status: {
type: DataTypes.STRING(20),
allowNull: false,
},
}, {
sequelize,
modelName: 'Asset',
timestamps: true,
});
module.exports = Asset;

models/InventoryItem.js


const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config');
class InventoryItem extends Model {}
InventoryItem.init({
InventoryItemId: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
ItemName: {
type: DataTypes.STRING(100),
allowNull: false,
},
Quantity: {
type: DataTypes.INTEGER,
allowNull: false,
},
Location: {
type: DataTypes.STRING(100),
},
}, {
sequelize,
modelName: 'InventoryItem',
timestamps: true,
});
module.exports = InventoryItem;

models/Document.js


const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config');
class Document extends Model {}
Document.init({
DocumentId: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
DocumentName: {
type: DataTypes.STRING(100),
allowNull: false,
},
DocumentType: {
type: DataTypes.STRING(50),
allowNull: false,
},
UploadedBy: {
type: DataTypes.INTEGER,
allowNull: false,
},
}, {
sequelize,
modelName: 'Document',
timestamps: true,
});
module.exports = Document;

models/Meeting.js


const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config');
class Meeting extends Model {}
Meeting.init({
MeetingId: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
MeetingTitle: {
type: DataTypes.STRING(100),
allowNull: false,
},
MeetingDate: {
type: DataTypes.DATE,
allowNull: false,
},
CreatedBy: {
type: DataTypes.INTEGER,
allowNull: false,
},
}, {
sequelize,
modelName: 'Meeting',
timestamps: true,
});
module.exports = Meeting;

models/Task.js


const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config');
class Task extends Model {}
Task.init({
TaskId: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
TaskTitle: {
type: DataTypes.STRING(100),
allowNull: false,
},
AssignedTo: {
type: DataTypes.INTEGER,
allowNull: false,
},
DueDate: {
type: DataTypes.DATE,
allowNull: false,
},
Status: {
type: DataTypes.STRING(20),
allowNull: false,
},
}, {
sequelize,
modelName: 'Task',
timestamps: true,
});
module.exports = Task;

models/Attendance.js


const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config');
class Attendance extends Model {}
Attendance.init({
AttendanceId: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
UserId: {
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/Report.js


const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config');
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,
},
}, {
sequelize,
modelName: 'Report',
timestamps: true,
});
module.exports = Report;

models/Feedback.js


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

Create Repositories

Create repository files for each model in the repositories directory.

repositories/roleRepository.js


const Role = require('../models/Role');
class RoleRepository {
async createRole(data) {
return await Role.create(data);
}
async getAllRoles() {
return await Role.findAll();
}
async getRoleById(id) {
return await Role.findByPk(id);
}
async updateRole(id, data) {
const role = await this.getRoleById(id);
if (role) {
return await role.update(data);
}
return null;
}
async deleteRole(id) {
const role = await this.getRoleById(id);
if (role) {
await role.destroy();
return true;
}
return false;
}
}
module.exports = new RoleRepository();

repositories/assetRepository.js


const Asset = require('../models/Asset');
class AssetRepository {
async createAsset(data) {
return await Asset.create(data);
}
async getAllAssets() {
return await Asset.findAll();
}
async getAssetById(id) {
return await Asset.findByPk(id);
}
async updateAsset(id, data) {
const asset = await this.getAssetById(id);
if (asset) {
return await asset.update(data);
}
return null;
}
async deleteAsset(id) {
const asset = await this.getAssetById(id);
if (asset) {
await asset.destroy();
return true;
}
return false;
}
}
module.exports = new AssetRepository();

repositories/inventoryItemRepository.js


const InventoryItem = require('../models/InventoryItem');
class InventoryItemRepository {
async createInventoryItem(data) {
return await InventoryItem.create(data);
}
async getAllInventoryItems() {
return await InventoryItem.findAll();
}
async getInventoryItemById(id) {
return await InventoryItem.findByPk(id);
}
async updateInventoryItem(id, data) {
const item = await this.getInventoryItemById(id);
if (item) {
return await item.update(data);
}
return null;
}
async deleteInventoryItem(id) {
const item = await this.getInventoryItemById(id);
if (item) {
await item.destroy();
return true;
}
return false;
}
}
module.exports = new InventoryItemRepository();

repositories/documentRepository.js


const Document = require('../models/Document');
class DocumentRepository {
async createDocument(data) {
return await Document.create(data);
}
async getAllDocuments() {
return await Document.findAll();
}
async getDocumentById(id) {
return await Document.findByPk(id);
}
async updateDocument(id, data) {
const document = await this.getDocumentById(id);
if (document) {
return await document.update(data);
}
return null;
}
async deleteDocument(id) {
const document = await this.getDocumentById(id);
if (document) {
await document.destroy();
return true;
}
return false;
}
}
module.exports = new DocumentRepository();

repositories/meetingRepository.js


const Meeting = require('../models/Meeting');
class MeetingRepository {
async createMeeting(data) {
return await Meeting.create(data);
}
async getAllMeetings() {
return await Meeting.findAll();
}
async getMeetingById(id) {
return await Meeting.findByPk(id);
}
async updateMeeting(id, data) {
const meeting = await this.getMeetingById(id);
if (meeting) {
return await meeting.update(data);
}
return null;
}
async deleteMeeting(id) {
const meeting = await this.getMeetingById(id);
if (meeting) {
await meeting.destroy();
return true;
}
return false;
}
}
module.exports = new MeetingRepository();

repositories/taskRepository.js


const Task = require('../models/Task');
class TaskRepository {
async createTask(data) {
return await Task.create(data);
}
async getAllTasks() {
return await Task.findAll();
}
async getTaskById(id) {
return await Task.findByPk(id);
}
async updateTask(id, data) {
const task = await this.getTaskById(id);
if (task) {
return await task.update(data);
}
return null;
}
async deleteTask(id) {
const task = await this.getTaskById(id);
if (task) {
await task.destroy();
return true;
}
return false;
}
}
module.exports = new TaskRepository();

repositories/attendanceRepository.js


const Attendance = require('../models/Attendance');
class AttendanceRepository {
async createAttendance(data) {
return await Attendance.create(data);
}
async getAllAttendanceRecords() {
return await Attendance.findAll();
}
async getAttendanceById(id) {
return await Attendance.findByPk(id);
}
async updateAttendance(id, data) {
const attendance = await this.getAttendanceById(id);
if (attendance) {
return await attendance.update(data);
}
return null;
}
async deleteAttendance(id) {
const attendance = await this.getAttendanceById(id);
if (attendance) {
await attendance.destroy();
return true;
}
return false;
}
}
module.exports = new AttendanceRepository();

repositories/reportRepository.js


const Report = require('../models/Report');
class ReportRepository {
async createReport(data) {
return await Report.create(data);
}
async getAllReports() {
return await Report.findAll();
}
async getReportById(id) {
return await Report.findByPk(id);
}
async updateReport(id, data) {
const report = await this.getReportById(id);
if (report) {
return await report.update(data);
}
return null;
}
async deleteReport(id) {
const report = await this.getReportById(id);
if (report) {
await report.destroy();
return true;
}
return false;
}
}
module.exports = new ReportRepository();

repositories/feedbackRepository.js


const Feedback = require('../models/Feedback');
class FeedbackRepository {
async createFeedback(data) {
return await Feedback.create(data);
}
async getAllFeedbacks() {
return await Feedback.findAll();
}
async getFeedbackById(id) {
return await Feedback.findByPk(id);
}
async updateFeedback(id, data) {
const feedback = await this.getFeedbackById(id);
if (feedback) {
return await feedback.update(data);
}
return null;
}
async deleteFeedback(id) {
const feedback = await this.getFeedbackById(id);
if (feedback) {
await feedback.destroy();
return true;
}
return false;
}
}
module.exports = new FeedbackRepository();

Set Up Controllers

Create controller files for each model in the controllers directory.

controllers/roleController.js


const roleRepository = require('../repositories/roleRepository');
class RoleController {
async createRole(req, res) {
try {
const role = await roleRepository.createRole(req.body);
res.status(201).json(role);
} catch (error) {
res.status(500).json({ error: 'Error creating role' });
}
}
async getAllRoles(req, res) {
try {
const roles = await roleRepository.getAllRoles();
res.status(200).json(roles);
} catch (error) {
res.status(500).json({ error: 'Error fetching roles' });
}
}
async getRoleById(req, res) {
try {
const role = await roleRepository.getRoleById(req.params.id);
if (role) {
res.status(200).json(role);
} else {
res.status(404).json({ error: 'Role not found' });
}
} catch (error) {
res.status(500).json({ error: 'Error fetching role' });
}
}
async updateRole(req, res) {
try {
const updatedRole = await roleRepository.updateRole(req.params.id, req.body);
if (updatedRole) {
res.status(200).json(updatedRole);
} else {
res.status(404 ).json({ error: 'Role not found' });
}
} catch (error) {
res.status(500).json({ error: 'Error updating role' });
}
}
async deleteRole(req, res) {
try {
const success = await roleRepository.deleteRole(req.params.id);
if (success) {
res.status(204).send();
} else {
res.status(404).json({ error: 'Role not found' });
}
} catch (error) {
res.status(500).json({ error: 'Error deleting role' });
}
}
}
module.exports = new RoleController();

controllers/assetController.js


const assetRepository = require('../repositories/assetRepository');
class AssetController {
async createAsset(req, res) {
try {
const asset = await assetRepository.createAsset(req.body);
res.status(201).json(asset);
} catch (error) {
res.status(500).json({ error: 'Error creating asset' });
}
}
async getAllAssets(req, res) {
try {
const assets = await assetRepository.getAllAssets();
res.status(200).json(assets);
} catch (error) {
res.status(500).json({ error: 'Error fetching assets' });
}
}
async getAssetById(req, res) {
try {
const asset = await assetRepository.getAssetById(req.params.id);
if (asset) {
res.status(200).json(asset);
} else {
res.status(404).json({ error: 'Asset not found' });
}
} catch (error) {
res.status(500).json({ error: 'Error fetching asset' });
}
}
async updateAsset(req, res) {
try {
const updatedAsset = await assetRepository.updateAsset(req.params.id, req.body);
if (updatedAsset) {
res.status(200).json(updatedAsset);
} else {
res.status(404).json({ error: 'Asset not found' });
}
} catch (error) {
res.status(500).json({ error: 'Error updating asset' });
}
}
async deleteAsset(req, res) {
try {
const success = await assetRepository.deleteAsset(req.params.id);
if (success) {
res.status(204).send();
} else {
res.status(404).json({ error: 'Asset not found' });
}
} catch (error) {
res.status(500).json({ error: 'Error deleting asset' });
}
}
}
module.exports = new AssetController();

controllers/inventoryItemController.js


const inventoryItemRepository = require('../repositories/inventoryItemRepository');
class InventoryItemController {
async createInventoryItem(req, res) {
try {
const item = await inventoryItemRepository.createInventoryItem(req.body);
res.status(201).json(item);
} catch (error) {
res.status(500).json({ error: 'Error creating inventory item' });
}
}
async getAllInventoryItems(req, res) {
try {
const items = await inventoryItemRepository.getAllInventoryItems();
res.status(200).json(items);
} catch (error) {
res.status(500).json({ error: 'Error fetching inventory items' });
}
}
async getInventoryItemById(req, res) {
try {
const item = await inventoryItemRepository.getInventoryItemById(req.params.id);
if (item) {
res.status(200).json(item);
} else {
res.status(404).json({ error: 'Inventory item not found' });
}
} catch (error) {
res.status(500).json({ error: 'Error fetching inventory item' });
}
}
async updateInventoryItem(req, res) {
try {
const updatedItem = await inventoryItemRepository.updateInventoryItem(req.params.id, req.body);
if (updatedItem) {
res.status(200).json(updatedItem);
} else {
res.status(404).json({ error: 'Inventory item not found' });
}
} catch (error) {
res.status(500).json({ error: 'Error updating inventory item' });
}
}
async deleteInventoryItem(req, res) {
try {
const success = await inventoryItemRepository.deleteInventoryItem(req.params.id);
if (success) {
res.status(204).send();
} else {
res.status(404).json({ error: 'Inventory item not found' });
}
} catch (error) {
res.status(500).json({ error: 'Error deleting inventory item' });
}
}
}
module.exports = new Inventory ItemController();

controllers/documentController.js


const documentRepository = require('../repositories/documentRepository');
class DocumentController {
async createDocument(req, res) {
try {
const document = await documentRepository.createDocument(req.body);
res.status(201).json(document);
} catch (error) {
res.status(500).json({ error: 'Error creating document' });
}
}
async getAllDocuments(req, res) {
try {
const documents = await documentRepository.getAllDocuments();
res.status(200).json(documents);
} catch (error) {
res.status(500).json({ error: 'Error fetching documents' });
}
}
async getDocumentById(req, res) {
try {
const document = await documentRepository.getDocumentById(req.params.id);
if (document) {
res.status(200).json(document);
} else {
res.status(404).json({ error: 'Document not found' });
}
} catch (error) {
res.status(500).json({ error: 'Error fetching document' });
}
}
async updateDocument(req, res) {
try {
const updatedDocument = await documentRepository.updateDocument(req.params.id, req.body);
if (updatedDocument) {
res.status(200).json(updatedDocument);
} else {
res.status(404).json({ error: 'Document not found' });
}
} catch (error) {
res.status(500).json({ error: 'Error updating document' });
}
}
async deleteDocument(req, res) {
try {
const success = await documentRepository.deleteDocument(req.params.id);
if (success) {
res.status(204).send();
} else {
res.status(404).json({ error: 'Document not found' });
}
} catch (error) {
res.status(500).json({ error: 'Error deleting document' });
}
}
}
module.exports = new DocumentController();

controllers/meetingController.js


const meetingRepository = require('../repositories/meetingRepository');
class MeetingController {
async createMeeting(req, res) {
try {
const meeting = await meetingRepository.createMeeting(req.body);
res.status(201).json(meeting);
} catch (error) {
res.status(500).json({ error: 'Error creating meeting' });
}
}
async getAllMeetings(req, res) {
try {
const meetings = await meetingRepository.getAllMeetings();
res.status(200).json(meetings);
} catch (error) {
res.status(500).json({ error: 'Error fetching meetings' });
}
}
async getMeetingById(req, res) {
try {
const meeting = await meetingRepository.getMeetingById(req.params.id);
if (meeting) {
res.status(200).json(meeting);
} else {
res.status(404).json({ error: 'Meeting not found' });
}
} catch (error) {
res.status(500).json({ error: 'Error fetching meeting' });
}
}
async updateMeeting(req, res) {
try {
const updatedMeeting = await meetingRepository.updateMeeting(req.params.id, req.body);
if (updatedMeeting) {
res.status(200).json(updatedMeeting);
} else {
res.status(404).json({ error: 'Meeting not found' });
}
} catch (error) {
res.status(500).json({ error: 'Error updating meeting' });
}
}
async deleteMeeting(req, res) {
try {
const success = await meetingRepository.deleteMeeting(req.params.id);
if (success) {
res.status(204).send();
} else {
res.status(404).json({ error: 'Meeting not found' });
}
} catch (error) {
res.status(500).json({ error: 'Error deleting meeting' });
}
}
}
module.exports = new MeetingController();

controllers/taskController.js


const taskRepository = require('../repositories/taskRepository');
class TaskController {
async createTask(req, res) {
try {
const task = await taskRepository.createTask(req.body);
res.status(201).json(task);
} catch (error) {
res.status(500).json({ error: 'Error creating task' });
}
}
async getAllTasks(req, res) {
try {
const tasks = await taskRepository.getAllTasks();
res.status(200).json(tasks);
} catch (error) {
res.status(500).json({ error: 'Error fetching tasks' });
}
}
async getTaskById(req, res) {
try {
const task = await taskRepository.getTaskById(req.params.id);
if (task) {
res.status(200).json(task);
} else {
res.status(404).json({ error: 'Task not found' });
}
} catch (error) {
res.status(500).json({ error: 'Error fetching task' });
}
}
async updateTask(req, res) {
try {
const updatedTask = await taskRepository.updateTask(req.params.id, req.body);
if (updatedTask) {
res.status(200).json(updatedTask);
} else {
res.status(404).json({ error: 'Task not found' });
}
} catch (error) {
res.status(500).json({ error: 'Error updating task' });
}
}
async deleteTask(req, res) {
try {
const success = await taskRepository.deleteTask(req.params.id);
if (success) {
res.status(204).send();
} else {
res.status(404).json({ error: 'Task not found' });
}
} catch (error) {
res.status(500).json({ error: 'Error deleting task' });
}
}
}
module.exports = new TaskController();

controllers/attendanceController.js


const attendanceRepository = require('../repositories/attendanceRepository');
class AttendanceController {
async createAttendance(req, res) {
try {
const attendance = await attendanceRepository.createAttendance(req.body);
res.status(201).json(attendance);
} catch (error) {
res.status(500).json({ error: 'Error creating attendance record' });
}
}
async getAllAttendanceRecords(req, res) {
try {
const records = await attendanceRepository.getAllAttendanceRecords();
res.status(200).json(records);
} catch (error) {
res.status(500).json({ error: 'Error fetching attendance records' });
}
}
async getAttendanceById(req, res) {
try {
const record = await attendanceRepository.getAttendanceById(req.params.id);
if (record) {
res.status(200).json(record);
} else {
res.status(404).json({ error: 'Attendance record not found' });
}
} catch (error) {
res.status(500).json({ error: 'Error fetching attendance record' });
}
}
async updateAttendance(req, res) {
try {
const updatedRecord = await attendanceRepository.updateAttendance(req.params.id, req.body);
if (updatedRecord) {
res.status(200).json(updatedRecord);
} else {
res.status(404).json({ error: 'Attendance record not found' });
}
} catch (error) {
res.status(500).json({ error: 'Error updating attendance record' });
}
}
async deleteAttendance(req, res) {
try {
const success = await attendanceRepository.deleteAttendance(req.params.id);
if (success) {
res.status(204).send();
} else {
res.status(404).json({ error: 'Attendance record not found' });
}
} catch (error) {
res.status(500).json({ error: 'Error deleting attendance record' });
}
}
}
module.exports = new AttendanceController();

controllers/reportController.js


const reportRepository = require('../repositories/reportRepository');
class ReportController {
async createReport(req, res) {
try {
const report = await reportRepository.createReport(req.body);
res.status(201).json(report);
} catch (error) {
res.status(500).json({ error: 'Error creating report' });
}
}
async getAllReports(req, res) {
try {
const reports = await reportRepository.getAllReports();
res.status(200).json(reports);
} catch (error) {
res.status(500).json({ error: 'Error fetching reports' });
}
}
async getReportById(req, res) {
try {
const report = await reportRepository.getReportById(req.params.id);
if (report) {
res.status(200).json(report);
} else {
res.status(404).json({ error: 'Report not found' });
}
} catch (error) {
res.status(500).json({ error: 'Error fetching report' });
}
}
async updateReport(req, res) {
try {
const updatedReport = await reportRepository.updateReport(req.params.id, req.body);
if (updatedReport) {
res.status(200).json(updatedReport);
} else {
res.status(404).json({ error: 'Report not found' });
} catch (error) {
res.status(500).json({ error: 'Error updating report' });
}
}
async deleteReport(req, res) {
try {
const success = await reportRepository.deleteReport(req.params.id);
if (success) {
res.status(204).send();
} else {
res.status(404).json({ error: 'Report not found' });
}
} catch (error) {
res.status(500).json({ error: 'Error deleting report' });
}
}
}
module.exports = new ReportController();

controllers/feedbackController.js


const feedbackRepository = require('../repositories/feedbackRepository');
class FeedbackController {
async createFeedback(req, res) {
try {
const feedback = await feedbackRepository.createFeedback(req.body);
res.status(201).json(feedback);
} catch (error) {
res.status(500).json({ error: 'Error creating feedback' });
}
}
async getAllFeedbacks(req, res) {
try {
const feedbacks = await feedbackRepository.getAllFeedbacks();
res.status(200).json(feedbacks);
} catch (error) {
res.status(500).json({ error: 'Error fetching feedbacks' });
}
}
async getFeedbackById(req, res) {
try {
const feedback = await feedbackRepository.getFeedbackById(req.params.id);
if (feedback) {
res.status(200).json(feedback);
} else {
res.status(404).json({ error: 'Feedback not found' });
}
} catch (error) {
res.status(500).json({ error: 'Error fetching feedback' });
}
}
async updateFeedback(req, res) {
try {
const updatedFeedback = await feedbackRepository.updateFeedback(req.params.id, req.body);
if (updatedFeedback) {
res.status(200).json(updatedFeedback);
} else {
res.status(404).json({ error: 'Feedback not found' });
}
} catch (error) {
res.status(500).json({ error: 'Error updating feedback' });
}
}
async deleteFeedback(req, res) {
try {
const success = await feedbackRepository.deleteFeedback(req.params.id);
if (success) {
res.status(204).send();
} else {
res.status(404).json({ error: 'Feedback not found' });
}
} catch (error) {
res.status(500).json({ error: 'Error deleting feedback' });
}
}
}
module.exports = new FeedbackController();

Define 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.post('/', roleController.createRole);
router.get('/', roleController.getAllRoles);
router.get('/:id', roleController.getRoleById);
router.put('/:id', roleController.updateRole);
router.delete('/:id', roleController.deleteRole);
module.exports = router;

routes/assetRoutes.js


const express = require('express');
const router = express.Router();
const assetController = require('../controllers/assetController');
router.post('/', assetController.createAsset);
router.get('/', assetController.getAllAssets);
router.get('/:id', assetController.getAssetById);
router.put('/:id', assetController.updateAsset);
router.delete('/:id', assetController.deleteAsset);
module.exports = router;

routes/inventoryItemRoutes.js


const express = require('express');
const router = express.Router();
const inventoryItemController = require('../controllers/inventoryItemController');
router.post('/', inventoryItemController.createInventoryItem);
router.get('/', inventoryItemController.getAllInventoryItems);
router.get('/:id', inventoryItemController.getInventoryItemById);
router.put('/:id', inventoryItemController.updateInventoryItem);
router.delete('/:id', inventoryItemController.deleteInventoryItem);
module.exports = router;

routes/documentRoutes.js


const express = require('express');
const router = express.Router();
const documentController = require('../controllers/documentController');
router.post('/', documentController.createDocument);
router.get('/', documentController.getAllDocuments);
router.get('/:id', documentController.getDocumentById);
router.put('/:id', documentController.updateDocument);
router.delete('/:id', documentController.deleteDocument);
module.exports = router;

routes/meetingRoutes.js


const express = require('express');
const router = express.Router();
const meetingController = require('../controllers/meetingController');
router.post('/', meetingController.createMeeting);
router.get('/', meetingController.getAllMeetings);
router.get('/:id', meetingController.getMeetingById);
router.put('/:id', meetingController.updateMeeting);
router.delete('/:id', meetingController.deleteMeeting);
module.exports = router;

routes/taskRoutes.js


const express = require('express');
const router = express.Router();
const taskController = require('../controllers/taskController');
router.post('/', taskController.createTask);
router.get('/', taskController.getAllTasks);
router.get('/:id', taskController.getTaskById);
router.put('/:id', taskController.updateTask);
router.delete('/:id', taskController.deleteTask);
module.exports = router;

routes/attendanceRoutes.js


const express = require('express');
const router = express.Router();
const attendanceController = require('../controllers/attendanceController');
router.post('/', attendanceController.createAttendance);
router.get('/', attendanceController.getAllAttendanceRecords);
router.get('/:id', attendanceController.getAttendanceById);
router.put('/:id', attendanceController.updateAttendance);
router.delete('/:id', attendanceController.deleteAttendance);
module.exports = router;

routes/reportRoutes.js


const express = require('express');
const router = express.Router();
const reportController = require('../controllers/reportController');
router.post('/', reportController.createReport);
router.get('/', reportController.getAllReports);
router.get('/:id', reportController.getReportById);
router.put('/:id', reportController.updateReport);
router.delete('/:id', reportController.deleteReport);
module.exports = router;

routes/feedbackRoutes.js


const express = require('express');
const router = express.Router();
const feedbackController = require('../controllers/feedbackController');
router.post('/', feedbackController.createFeedback);
router.get('/', feedbackController.getAllFeedbacks);
router.get('/:id', feedbackController.getFeedbackById);
router.put('/:id', feedbackController.updateFeedback);
router.delete('/:id', feedbackController.deleteFeedback);
module.exports = router;

Update the Main Application

In your main application file (e.g., index.js), integrate the new routes.


const express = require('express');
const bodyParser = require('body-parser');
const userRoutes = require('./routes/userRoutes');
const roleRoutes = require('./routes/roleRoutes');
const assetRoutes = require('./routes/assetRoutes');
const inventoryItemRoutes = require('./routes/inventoryItemRoutes');
const documentRoutes = require('./routes/documentRoutes');
const meetingRoutes = require('./routes/meetingRoutes');
const taskRoutes = require('./routes/taskRoutes');
const attendanceRoutes = require('./routes/attendanceRoutes');
const reportRoutes = require('./routes/reportRoutes');
const feedbackRoutes = require('./routes/feedbackRoutes');
const sequelize = require('./config');
const app = express();
app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static('public'));
app.use('/users', userRoutes);
app.use('/roles', roleRoutes);
app.use('/assets', assetRoutes);
app.use('/inventory-items', inventoryItemRoutes);
app.use('/documents', documentRoutes);
app.use('/meetings', meetingRoutes);
app.use('/tasks', taskRoutes);
app.use('/attendance', attendanceRoutes);
app.use('/reports', reportRoutes);
app.use('/feedback', feedbackRoutes);
sequelize.sync().then(() => {
app.listen(3000, () => {
console.log('Server is running on http://localhost:3000');
});
}).catch(err => {
console.error('Unable to connect to the database:', err);
});

Create Views for Remaining Models

Create EJS views for each model in the views directory. Below are examples for Roles, Assets, and InventoryItems.

views/roles.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>Role Management</title>
</head>
<body>
<div class="container">
<h1 class="mt-4">Role Management</h1>
<table class="table mt-4">
<thead>
<tr>
<th>Role ID</th>
<th>Role Name</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<% roles.forEach(role => { %>
<tr>
<td><%= role.RoleId %></td>
<td><%= role.RoleName %></td>
<td>
<a href="/roles/<%= role.RoleId %>/edit" class="btn btn-warning">Edit</a>
<form action="/roles/<%= role.RoleId %>" method="POST" style="display:inline;">
<input type=" hidden" name="_method" value="DELETE">
<button type="submit" class="btn btn-danger">Delete</button>
</form>
</td>
</tr>
<% }) %>
</tbody>
</table>
<a href="/roles/new" class="btn btn-primary">Add Role</a>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

views/assets.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>Asset Management</title>
</head>
<body>
<div class="container">
<h1 class="mt-4">Asset Management</h1>
<table class="table mt-4">
<thead>
<tr>
<th>Asset ID</th>
<th>Asset Name</th>
<th>Asset Type</th>
<th>Purchase Date</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<% assets.forEach(asset => { %>
<tr>
<td><%= asset.AssetId %></td>
<td><%= asset.AssetName %></td>
<td><%= asset.AssetType %></td>
<td><%= asset.PurchaseDate.toISOString().split('T')[0] %></td>
<td><%= asset.Status %></td>
<td>
<a href="/assets/<%= asset.AssetId %>/edit" class="btn btn-warning">Edit</a>
<form action="/assets/<%= asset.AssetId %>" method="POST" style="display:inline;">
<input type="hidden" name="_method" value="DELETE">
<button type="submit" class="btn btn-danger">Delete</button>
</form>
</td>
</tr>
<% }) %>
</tbody>
</table>
<a href="/assets/new" class="btn btn-primary">Add Asset</a>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

views/inventoryItems.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>Inventory Item Management</title>
</head>
<body>
<div class="container">
<h1 class="mt-4">Inventory Item Management</h1>
<table class="table mt-4">
<thead>
<tr>
<th>Item ID</th>
<th>Item Name</th>
<th>Quantity</th>
<th>Location</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<% items.forEach(item => { %>
<tr>
<td><%= item.InventoryItemId %></td>
<td><%= item.ItemName %></td>
<td><%= item.Quantity %></td>
<td><%= item.Location %></td>
<td>
<a href="/inventory-items/<%= item.InventoryItemId %>/edit" class="btn btn-warning">Edit</a>
<form action="/inventory-items/<%= item.InventoryItemId %>" method="POST" style="display:inline;">
<input type="hidden" name="_method" value="DELETE">
<button type="submit" class="btn btn-danger">Delete</button>
</form>
</td>
</tr>
<% }) %>
</tbody>
</table>
<a href="/inventory-items/new" class="btn btn-primary">Add Inventory Item</a>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

Run the Application

Start your application by running node index.js in your terminal.

Access the Management Pages: Open your browser and navigate to the respective routes for managing roles.

Create a Dashboard Page

To create a dashboard page that consolidates data related to the asset management system, we will follow these steps:

Create a Dashboard Route: Define a route for the dashboard.

Create a Dashboard Controller: Implement a controller to fetch and aggregate data from various models.

Create a Dashboard View: Design a view to display the consolidated data.

Update the Main Application: Integrate the dashboard into the main application.

Step 1: Create a Dashboard Route

Create a new file named dashboardRoutes.js in the routes directory.

routes/dashboardRoutes.js


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

Step 2: Create a Dashboard Controller

Create a new file named dashboardController.js in the controllers directory.

controllers/dashboardController.js


const User = require('../models/User');
const Role = require('../models/Role');
const Asset = require('../models/Asset');
const InventoryItem = require('../models/InventoryItem');
const Document = require('../models/Document');
const Meeting = require('../models/Meeting');
const Task = require('../models/Task');
const Attendance = require('../models/Attendance');
const Report = require('../models/Report');
const Feedback = require('../models/Feedback');
class DashboardController {
async getDashboard(req, res) {
try {
const userCount = await User.count();
const roleCount = await Role.count();
const assetCount = await Asset.count();
const inventoryItemCount = await InventoryItem.count();
const documentCount = await Document.count();
const meetingCount = await Meeting.count();
const taskCount = await Task.count();
const attendanceCount = await Attendance.count();
const reportCount = await Report.count();
const feedbackCount = await Feedback.count();
res.render('dashboard', {
userCount,
roleCount,
assetCount,
inventoryItemCount,
documentCount,
meetingCount,
taskCount,
attendanceCount,
reportCount,
feedbackCount,
});
} catch (error) {
console.error(error);
res.status(500).send('Internal Server Error');
}
}
}
module.exports = new DashboardController();

Step 3: Create a Dashboard View

Create a new file named dashboard.ejs in the views directory.

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>
<div class="row mt-4">
<div class="col-md-3">
<div class="card text-white bg-primary mb-3">
<div class="card-header">Total Users</div>
<div class="card-body">
<h5 class="card-title"><%= userCount %></h5>
<p class="card-text">Total number of registered users.</p>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card text-white bg-success mb-3">
<div class="card-header">Total Roles</div>
<div class="card-body">
<h5 class="card-title"><%= roleCount %></h5>
<p class="card-text">Total roles defined in the system.</p>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card text-white bg-info mb-3">
<div class="card-header">Total Assets</div>
<div class="card-body">
<h5 class="card-title"><%= assetCount %></h5>
<p class="card-text">Total assets managed.</p>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card text-white bg-warning mb-3">
<div class="card-header">Total Inventory Items</div>
<div class="card-body">
<h5 class="card-title"><%= inventoryItemCount %></h5>
<p class="card-text">Total inventory items available.</p>
</div>
</div>
</div>
</div>
<div class="row mt-4">
<div class="col-md-3">
<div class="card text-white bg-danger mb-3">
<div class="card-header">Total Documents</div>
<div class="card-body">
<h5 class="card-title"><%= documentCount %></h5>
<p class="card-text">Total documents uploaded.</p>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card text-white bg-secondary mb-3">
<div class="card-header">Total Meetings</div>
<div class="card-body">
<h5 class="card-title"><%= meetingCount %></h5>
<p class="card-text">Total meetings scheduled.</p>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card text-white bg-light mb-3">
<div class="card-header">Total Tasks</div>
<div class ="card-body">
<h5 class="card-title"><%= taskCount %></h5>
<p class="card-text">Total tasks assigned.</p>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card text-white bg-dark mb-3">
<div class="card-header">Total Attendance Records</div>
<div class="card-body">
<h5 class="card-title"><%= attendanceCount %></h5>
<p class="card-text">Total attendance records logged.</p>
</div>
</div>
</div>
</div>
<div class="row mt-4">
<div class="col-md-3">
<div class="card text-white bg-primary mb-3">
<div class="card-header">Total Reports</div>
<div class="card-body">
<h5 class="card-title"><%= reportCount %></h5>
<p class="card-text">Total reports generated.</p>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card text-white bg-success mb-3">
<div class="card-header">Total Feedbacks</div>
<div class="card-body">
<h5 class="card-title"><%= feedbackCount %></h5>
<p class="card-text">Total feedback received.</p>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

Step 4: Update the Main Application

In your main application file (e.g., index.js), integrate the dashboard route.


const express = require('express');
const bodyParser = require('body-parser');
const userRoutes = require('./routes/userRoutes');
const roleRoutes = require('./routes/roleRoutes');
const assetRoutes = require('./routes/assetRoutes');
const inventoryItemRoutes = require('./routes/inventoryItemRoutes');
const documentRoutes = require('./routes/documentRoutes');
const meetingRoutes = require('./routes/meetingRoutes');
const taskRoutes = require('./routes/taskRoutes');
const attendanceRoutes = require('./routes/attendanceRoutes');
const reportRoutes = require('./routes/reportRoutes');
const feedbackRoutes = require('./routes/feedbackRoutes');
const dashboardRoutes = require('./routes/dashboardRoutes'); // Import dashboard routes
const sequelize = require('./config');
const app = express();
app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static('public'));
app.use('/users', userRoutes);
app.use('/roles', roleRoutes);
app.use('/assets', assetRoutes);
app.use('/inventory-items', inventoryItemRoutes);
app.use('/documents', documentRoutes);
app.use('/meetings', meetingRoutes);
app.use('/tasks', taskRoutes);
app.use('/attendance', attendanceRoutes);
app.use('/reports', reportRoutes);
app.use('/feedback', feedbackRoutes);
app.use('/dashboard', dashboardRoutes); // Use dashboard routes
sequelize.sync().then(() => {
app.listen(3000, () => {
console.log('Server is running on http://localhost:3000');
});
}).catch(err => {
console.error('Unable to connect to the database:', err);
});

Run the Application

Start your application by running node index.js in your terminal.

Access the Dashboard: Open your browser and navigate to http://localhost:3000/dashboard to view the consolidated data related to the project.