TABLE OF CONTENTS
CHAPTE PAGE NO.
R TITLE
NO.
ABSTRACT i
LIST OF FIGURES ii
1.1 OBJECTIVES
1
1.2 SCOPE OF THE PROJECT 1
SYSTEM ANALYSIS AND 2
2
SPECIFICATION
2
2.1 PROBLEM DESCRIPTION
FUNCTIONAL REQUIREMENT - 2
2.2
HARDWARE & SOFTWARE
NON – FUNCTIONAL 2
2.3 REQUIREMENT
3
3 SYSTEM DESIGN
USECASE DIAGRAM 3
3.1
CLASS DIAGRAM 3
3.2
4 MODULE DESCRIPTION 4
5 IMPLEMENTATION 5
RESULTS AND DISCUSSION 30
6
7 CONCLUSION & FUTURE 33
ENHANCEMENT
REFERENCES 34
ABSTRACT
The ‘ClassConnect’ – Virtual Classroom Platform is a full-stack web application
developed using the MERN stack (MongoDB, Express.js, React.js, and Node.js)
designed to facilitate seamless interaction between students, teachers, and
administrators in an online educational environment. The system features a secure
login and registration module to ensure personalized access and data privacy for
each user. Upon successful login, teachers can create and manage courses, upload
learning materials, conduct live classes, and evaluate students through quizzes
and assignments, while students can join courses, attend sessions, access study
content, and submit their work.
One of the core functionalities of the platform is its real-time communication
system, including live chat and instant notifications, enhancing engagement
during live sessions. Notifications are implemented using browser alerts or push
services, depending on device compatibility. The backend handles data storage
and retrieval using MongoDB, while the frontend provides a responsive and user-
friendly interface built with React. The application ensures efficient course
management, smooth live class experiences, and organized student tracking,
making it especially beneficial for institutions offering remote or blended
learning. The app’s architecture is designed to be scalable, responsive, and easily
extendable to future features like certificate generation, performance analytics,
and integration with video conferencing tools and cloud storage.
i
LIST OF FIGURES
S NO TITLE PAGE NO
1 USECASE DIAGRAM 3
2 CLASS DIAGRAM 3
3 DASHBOARD PAGE 30
4 LOGIN PAGE 30
5 REGISTER PAGE 31
6 MEDICINE REMINDER PAGE 31
7 NOTIFICATION 32
8 MANGODB CONNECTION PAGE 32
ii
CHAPTER 1
INTRODUCTION
1.1 OBJECTIVES
The objective of the ClassConnect – Virtual Classroom Platform is to develop a
secure, interactive, and user-friendly web application that enhances digital
learning experiences for students, teachers, and administrators. The platform aims
to provide personalized user access through a secure login and registration system,
enabling role-based functionality for each user type. It allows teachers to create
and manage courses, upload materials, conduct live sessions, and track student
performance, while students can enroll in courses, attend live classes, and
complete quizzes and assignments.
1.2 SCOPE OF THE PROJECT
The scope of the project includes the development of a full-stack web application
that supports user authentication, role-based access, course management, and real-
time collaboration features. Users are categorized into three main roles: students,
teachers, and administrators, each with dedicated access and functionality.
Teachers can create and manage courses, upload study materials, host live classes,
and assign quizzes, while students can enroll in courses, attend sessions, and
interact via real-time chat and notifications. Administrators can oversee platform
activities, manage user accounts, and ensure smooth academic operations. All data,
including user profiles, course content, and assessments, is securely stored in
MongoDB, ensuring data persistence and reliability. The application currently
serves as a comprehensive online learning management system but is designed
with scalability in mind, allowing future integration of advanced features such as
certificate generation, performance analytics, cloud storage integration, and
mobile app support. It primarily serves educational institutions and individual
educators aiming to provide structured and interactive
1
CHAPTER 2
SYSTEM ANALYSIS AND SPECIFICATION
2.1 PROBLEM DESCRIPTION
In today’s evolving educational landscape, students and educators face significant challenges
in maintaining effective communication, engagement, and structured learning in a virtual
environment. Traditional online platforms often lack real-time interaction, personalized
learning experiences, and centralized management of academic content. This leads to decreased
student participation, inefficient course delivery, and administrative difficulties in managing
learning outcomes. There is a growing need for a comprehensive digital solution that supports
real-time collaboration, streamlined course management, and interactive learning. The
ClassConnect – Virtual Classroom Platform aims to address these challenges by providing a
secure, responsive, and feature-rich web application that fosters seamless communication,
efficient teaching, and organized academic administration in a virtual setting.
2.2 FUNCTIONAL REQUIREMENT –
SOFTWARE AND HARDWARE REQUIREMENTS
▪ Frontend: React.js, HTML, CSS, JavaScript, React Router
▪ Backend: Node.js, Express.js, RESTful APIs
▪ Database: MongoDB (Local or Atlas)
▪ Authentication: bcrypt.js for password hashing, express-session or JWT
▪ Notifications: Browser Notifications (Web APIs)
2.3 NON-FUNCTIONAL REQUIREMENT
▪ Usability: The user interface should be simple, intuitive, and accessible across all
devices to ensure smooth experience for students, teachers, and administrators.
▪ Scalability: The system should support increasing numbers of users, courses, and
real-time interactions without compromising performance
▪ Performance: The platform should maintain fast loading times and responsive behavior,
even during high-traffic situations such as live classes or simultaneous quiz submissions
2
CHAPTER 3
SYSTEM DESIGN
USECASE DIAGRAM
FIGURE 1 USECASE DIAGRAM
CLASS DIAGRAM
FIGURE 2 CLASS DIAGRAM
3
CHAPTER 4
MODULE DESCRIPTION
4.1 APP MODULE
This is the main React component that serves as the root of the application. It manages routing and
renders core components such as Login, Register, Dashboard, Student Panel, and Teacher Panel. It
controls the overall UI flow and connects various modules like Course Management, Live Class
Scheduling, and Performance Tracking. The App module also integrates global CSS styles and context
providers to ensure a consistent user experience across the platform.
4.2 COMPONENT MODULE
4.2.1 Login Component
Responsible for user login functionality. It provides a login form where users (students or
teachers) enter their email and password. It performs input validation and communicates with
the backend to verify credentials and route users to their respective dashboards based on their
roles.
4.2.2 Register Component
Handles new user registration. It collects user information such as name, email, password, and
role (student or teacher). The component validates the input fields and submits the data to the
backend API to create a new user account securely.
4.2.3 Dashboard Component
Acts as the central hub after login. Based on the user role, it displays either the Student
Dashboard or Teacher Dashboard. It provides quick access to courses, assignments, live
classes, and other relevant features.
4.2.4 Course Management Component
Used mainly by teachers to create, update, and manage course content. It includes
functionalities to upload materials, schedule lessons, and organize modules that students can
access after enrollment.
4.2.5 Real-Time Class/Chat Component
Enables live class interactions and chat between students and teachers. It uses technologies like
WebSocket or WebRTC for real-time communication and supports messaging, attendance
tracking, and screen sharing.
4
CHAPTER 4
IMPLEMENTATION
COMPONENTS:
DASHBOARD.JSX
import { motion } from 'framer-motion'
import { useState, useEffect } from 'react'
import { Link, Routes, Route, useNavigate } from 'react-router-dom'
import styles from './TeacherDashboard.module.css'
import { getTeacherCourses } from '../../services/teacherService'
// Import teacher feature components
import CourseManagement from './CourseManagement/CourseManagement'
import StudyMaterials from './StudyMaterials/StudyMaterials'
import LiveClasses from './LiveClasses/LiveClasses'
import Quizzes from './Quizzes/Quizzes'
import StudentTracking from './StudentTracking/StudentTracking'
const TeacherDashboard = () => {
const navigate = useNavigate();
const [activeTab, setActiveTab] = useState('overview');
const [courses, setCourses] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const [stats, setStats] = useState({
coursesTeaching: 0,
totalStudents: 0,
pendingGrading: 0,
averageRating: 0
});
const [user, setUser] = useState(() => {
const stored = localStorage.getItem('user');
return stored ? JSON.parse(stored) : { name: 'Teacher' };
});
useEffect(() => {
const fetchCourses = async () => {
try {
const data = await getTeacherCourses();
setCourses(data);
// Calculate stats
const totalStudents = data.reduce((acc, course) => acc + course.students.length, 0);
const pendingGrading = data.reduce((acc, course) => {
return acc + course.quizzes.reduce((quizAcc, quiz) => {
return quizAcc + (quiz.submissions?.length || 0);
5
}, 0);
}, 0);
setStats({
coursesTeaching: data.length,
totalStudents,
pendingGrading,
averageRating: 4.8 // This would come from student feedback in a real app
});
setLoading(false);
} catch (err) {
setError('Failed to fetch courses');
setLoading(false);
}
};
fetchCourses();
}, []);
const cardVariants = {
hidden: { opacity: 0, y: 20 },
visible: { opacity: 1, y: 0 }
}
const handleTabChange = (tab) => {
setActiveTab(tab);
navigate(`/teacher-dashboard/${tab}`);
};
if (loading) {
return <div className={styles.loading}>Loading...</div>;
}
if (error) {
return <div className={styles.error}>{error}</div>;
}
return (
<div className={styles.dashboardContainer}>
<motion.div
className={styles.sideNav}
initial={{ x: -50, opacity: 0 }}
animate={{ x: 0, opacity: 1 }}
transition={{ duration: 0.5 }}
>
<div className={styles.profileSection}>
<div className={styles.profileImage}>
<span>{user.name ? user.name.split(' ').map(n => n[0]).join('').toUpperCase() :
'T'}</span>
6
</div>
<h3>{user.name || 'Teacher'}</h3>
<p>Mathematics Professor</p>
</div>
<nav className={styles.navMenu}>
<button
className={`${styles.navItem} ${activeTab === 'overview' ? styles.active : ''}`}
onClick={() => handleTabChange('overview')}
>
<i className={styles.icon}> </i> Overview
</button>
<button
className={`${styles.navItem} ${activeTab === 'courses' ? styles.active : ''}`}
onClick={() => handleTabChange('courses')}
>
<i className={styles.icon}> </i> Courses
</button>
<button
className={`${styles.navItem} ${activeTab === 'materials' ? styles.active : ''}`}
onClick={() => handleTabChange('materials')}
>
<i className={styles.icon}> </i> Study Materials
</button>
<button
className={`${styles.navItem} ${activeTab === 'live-classes' ? styles.active : ''}`}
onClick={() => handleTabChange('live-classes')}
>
<i className={styles.icon}> </i> Live Classes
</button>
<button
className={`${styles.navItem} ${activeTab === 'quizzes' ? styles.active : ''}`}
onClick={() => handleTabChange('quizzes')}
>
<i className={styles.icon}> </i> Quizzes
</button>
<button
className={`${styles.navItem} ${activeTab === 'students' ? styles.active : ''}`}
onClick={() => handleTabChange('students')}
>
<i className={styles.icon}> </i> Student Tracking
</button>
</nav>
</motion.div>
<div className={styles.mainContent}>
{activeTab === 'overview' && (
<>
<motion.div
7
className={styles.welcomeSection}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.5 }}
>
<h1>Welcome back, Teacher!</h1>
<p>Here's your teaching overview</p>
</motion.div>
<div className={styles.statsGrid}>
{Object.entries(stats).map(([key, value], index) => (
<motion.div
key={key}
className={styles.statCard}
variants={cardVariants}
initial="hidden"
animate="visible"
transition={{ delay: index * 0.1 }}
>
<h3>{key.replace(/([A-Z])/g, ' $1').trim()}</h3>
<p className={styles.statValue}>{value}</p>
</motion.div>
))}
</div>
<motion.div
className={styles.coursesSection}
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.4 }}
>
<h2>Your Courses</h2>
<div className={styles.coursesList}>
{courses.map((course, index) => (
<motion.div
key={course._id}
className={styles.courseCard}
initial={{ opacity: 0, x: -20 }}
animate={{ opacity: 1, x: 0 }}
transition={{ delay: index * 0.1 }}
>
<h3>{course.title}</h3>
<div className={styles.progressBar}>
<div
className={styles.progressFill}
style={{ width: `${course.progress}%` }}
/>
</div>
<p>Course Progress: {course.progress}%</p>
<p className={styles.students}>Students: {course.students.length}</p>
8
</motion.div>
))}
</div>
</motion.div>
<motion.div
className={styles.activitySection}
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.6 }}
>
<h2>Recent Activities</h2>
<div className={styles.timeline}>
{courses.flatMap(course => [
...course.materials.map(material => ({
activity: `Published ${material.title}`,
time: new Date(material.uploadDate).toLocaleDateString()
})),
...course.liveClasses.map(liveClass => ({
activity: `Hosted ${liveClass.title}`,
time: new Date(liveClass.scheduledDate).toLocaleDateString()
}))
]).sort((a, b) => new Date(b.time) - new Date(a.time))
.slice(0, 4)
.map((activity, index) => (
<motion.div
key={activity.activity}
className={styles.timelineItem}
initial={{ opacity: 0, x: -20 }}
animate={{ opacity: 1, x: 0 }}
transition={{ delay: index * 0.1 }}
>
<div className={styles.timelineDot} />
<div className={styles.timelineContent}>
<h4>{activity.activity}</h4>
<p>{activity.time}</p>
</div>
</motion.div>
))}
</div>
</motion.div>
</>
)}
{activeTab === 'courses' && <CourseManagement courses={courses}
setCourses={setCourses} />}
{activeTab === 'materials' && <StudyMaterials courses={courses} />}
{activeTab === 'live-classes' && <LiveClasses courses={courses} />}
{activeTab === 'quizzes' && <Quizzes courses={courses} />}
{activeTab === 'students' && <StudentTracking courses={courses} />}
9
</div>
</div>
)
}
export default TeacherDashboard
DASHBOARD.CSS
.dashboard-container {
display: flex;
flex-direction: column;
height: 100vh;
background: linear-gradient(to right, #74ebd5, #acb6e5);
}
.header {
background-color: #007bff;
color: white;
padding: 10px 20px;
display: flex;
justify-content: space-between;
align-items: center;
}
.app-name {
font-weight: bold;
font-size: 20px;
}
.auth-buttons {
display: flex;
gap: 15px;
}
.auth-buttons button {
padding: 12px 25px;
font-size: 16px;
color: white;
background-color: #007bff;
border: none;
border-radius: 5px;
cursor: pointer;
10
transition: background-color 0.3s ease, transform 0.2s ease;
}
.auth-buttons button:hover {
background-color: #0056b3;
transform: translateY(-2px);
}
.auth-buttons button:active {
transform: translateY(2px);
}
.auth-buttons button:focus {
outline: none;
}
.content {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
flex-grow: 1;
padding: 20px;
text-align: center;
}
h1 {
font-size: 28px;
color: #333;
margin-bottom: 20px;
}
p{
font-size: 18px;
color: #555;
margin-bottom: 30px;
}
.dashboard-image {
max-width: 100%;
height: auto;
margin-bottom: 30px;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
11
}
.get-started-btn {
padding: 12px 30px;
font-size: 18px;
background-color: #007bff;
.dashboard-container {
display: flex;
flex-direction: column;
height: 100vh;
background: linear-gradient(to right, #74ebd5, #acb6e5);
}
.header {
background-color: #007bff;
color: white;
padding: 10px 20px;
display: flex;
justify-content: space-between;
align-items: center;
}
.app-name {
font-weight: bold;
font-size: 20px;
}
.auth-buttons {
display: flex;
gap: 15px;
}
.auth-buttons button {
padding: 12px 25px;
font-size: 16px;
color: white;
background-color: #007bff;
border: none;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s ease, transform 0.2s ease;
}
.auth-buttons button:hover {
12
background-color: #0056b3;
transform: translateY(-2px);
}
.auth-buttons button:active {
transform: translateY(2px);
}
.auth-buttons button:focus {
outline: none;
}
.content {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
flex-grow: 1;
padding: 20px;
text-align: left;
}
.text-content {
flex: 1;
padding-right: 20px;
}
h1 {
font-size: 28px;
color: #333;
margin-bottom: 20px;
}
p{
font-size: 18px;
color: #555;
margin-bottom: 30px;
}
.dashboard-image {
max-width: 100%;
13
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
.get-started-btn {
padding: 12px 30px;
font-size: 18px;
background-color: #007bff;
color: white;
border: none;
border-radius: 8px;
cursor: pointer;
transition: background-color 0.3s ease, transform 0.2s ease;
margin-top: 20px;
width: auto;
}
.get-started-btn:hover {
background-color: #0056b3;
transform: translateY(-2px);
}
.get-started-btn:active {
transform: translateY(2px);
}
.get-started-btn:focus {
outline: none;
}
.footer {
color: white;
text-align: center;
padding: 10px 20px;
margin-bottom: 30px;
}
.footer p {
margin: 0;
font-size: 14px;
}
14
color: white;
border: none;
border-radius: 8px;
cursor: pointer;
transition: background-color 0.3s ease, transform 0.2s ease;
}
.get-started-btn:hover {
background-color: #0056b3;
transform: translateY(-2px);
}
.get-started-btn:active {
transform: translateY(2px);
}
.get-started-btn:focus {
outline: none;
}
.footer {
color: white;
text-align: center;
padding: 10px 20px;
margin-bottom: 30px;
}
.footer p {
margin: 0;
font-size: 14px;
}
REGISTER.JSX
import React, { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import './Register.css';
const Register = () => {
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [error, setError] = useState('');
const navigate = useNavigate();
const handleSubmit = async (e) => {
15
e.preventDefault();
try {
const response = await fetch('http://localhost:5000/api/register', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ name, email, password }),
});
const data = await response.json();
if (response.ok) {
navigate('/login');
} else {
setError(data.msg);
}
} catch (err) {
setError('Server error. Please try again.');
}
};
return (
<div className="register-wrapper">
<div className="register-container">
<h1>Register</h1>
{error && <div className="error-message">{error}</div>}
<form onSubmit={handleSubmit}>
<input
type="text"
placeholder="Name"
value={name}
onChange={(e) => setName(e.target.value)}
required
/>
<input
type="email"
placeholder="Email"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
/>
<input
type="password"
placeholder="Password"
value={password}
onChange={(e) => setPassword(e.target.value)}
required
/>
16
<button type="submit">Register</button>
</form>
<p>
Already have an account? <a href="/login">Login</a>
</p>
</div>
</div>
);
};
export default Register;
REGISTER.CSS
.register-wrapper {
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(to right, #74ebd5, #acb6e5);
margin: 0;
padding: 0;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
.register-container {
background: white;
padding: 40px;
border-radius: 12px;
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.15);
max-width: 400px;
width: 100%;
text-align: center;
animation: fadeIn 0.8s ease-in-out;
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(-20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.register-container h1 {
17
margin-bottom: 24px;
font-size: 32px;
color: #333;
}
.register-container input {
width: 100%;
padding: 12px;
margin-bottom: 16px;
border: 1px solid #ccc;
border-radius: 8px;
font-size: 16px;
transition: border 0.3s;
}
.register-container input:focus {
border-color: #007bff;
outline: none;
}
.register-container button {
width: 100%;
padding: 12px;
background-color: #007bff;
color: white;
font-size: 16px;
font-weight: bold;
border: none;
border-radius: 8px;
cursor: pointer;
transition: background 0.3s;
}
.register-container button:hover {
background-color: blueviolet;
}
.register-container .error-message {
background: #ffdddd;
color: #d8000c;
padding: 10px;
border-radius: 6px;
margin-bottom: 16px;
border: 1px solid #d8000c;
font-size: 14px;
}
.register-container p {
margin-top: 20px;
font-size: 14px;
18
}
.register-container a {
color: #007bff;
text-decoration: none;
}
.register-container a:hover {
text-decoration: underline;
}
APP.JS
import { BrowserRouter as Router, Routes, Route, useLocation } from 'react-router-dom'
import Home from './pages/Home/Home'
import Features from './pages/Features/Features'
import Courses from './pages/Courses/Courses'
import About from './pages/About/About'
import Contact from './pages/Contact/Contact'
import Login from './pages/Auth/Login'
import Signup from './pages/Auth/Signup'
import StudentDashboard from './pages/Student/StudentDashboard'
import TeacherDashboard from './pages/Teacher/TeacherDashboard'
import Navbar from './components/Navbar/Navbar'
import './App.css'
// Scrollable page wrapper component
const ScrollablePage = ({ children }) => {
return (
<div style={{
width: '100%',
height: 'auto',
minHeight: '100vh',
overflowY: 'auto',
overflowX: 'hidden',
paddingTop: '70px', // Space for navbar
position: 'relative',
display: 'block'
}}>
{children}
</div>
)
}
const AppContent = () => {
const location = useLocation()
const hideNavbar = [
'/login',
'/signup',
19
'/student-dashboard',
'/teacher-dashboard',
'/teacher-dashboard/overview',
'/teacher-dashboard/courses',
'/teacher-dashboard/materials',
'/teacher-dashboard/live-classes',
'/teacher-dashboard/quizzes',
'/teacher-dashboard/students'
].some(path => location.pathname.startsWith(path))
return (
<div style={{
width: '100%',
height: 'auto',
minHeight: '100vh',
overflowY: 'auto',
overflowX: 'hidden',
position: 'relative',
display: 'block'
}}>
{!hideNavbar && <Navbar />}
<Routes>
<Route path="/" element={<ScrollablePage><Home /></ScrollablePage>} />
<Route path="/features" element={<ScrollablePage><Features /></ScrollablePage>} />
<Route path="/courses" element={<ScrollablePage><Courses /></ScrollablePage>} />
<Route path="/about" element={<ScrollablePage><About /></ScrollablePage>} />
<Route path="/contact" element={<ScrollablePage><Contact /></ScrollablePage>} />
<Route path="/login" element={<ScrollablePage><Login /></ScrollablePage>} />
<Route path="/signup" element={<ScrollablePage><Signup /></ScrollablePage>} />
<Route path="/student-dashboard/*" element={<ScrollablePage><StudentDashboard
/></ScrollablePage>} />
<Route path="/teacher-dashboard/*" element={<ScrollablePage><TeacherDashboard
/></ScrollablePage>} />
</Routes>
</div>
)
}
function App() {
return (
<Router>
<div style={{
width: '100%',
height: 'auto',
minHeight: '100vh',
overflowY: 'auto',
overflowX: 'hidden',
position: 'relative',
display: 'block'
20
}}>
<AppContent />
</div>
</Router>
)
}
export default App
APP.CSS
body {
margin: 0;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: radial-gradient(circle at top left, #eb74d1, #9face6);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.app {
background-color: rgba(255, 255, 255, 0.95);
padding: 40px;
border-radius: 20px;
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.25);
max-width: 500px;
width: 100%;
text-align: center;
}
h1 {
margin-bottom: 20px;
color: #333;
}
form {
display: flex;
flex-direction: column;
gap: 15px;
}
input {
padding: 10px;
font-size: 1rem;
border: 1px solid #ccc;
border-radius: 10px;
outline: none;
transition: all 0.3s ease;
21
}
input:focus {
border-color: #74ebd5;
box-shadow: 0 0 5px rgba(116, 235, 213, 0.5);
}
button {
padding: 12px;
background-color: #b667a5;
border: none;
color: white;
font-size: 1rem;
border-radius: 10px;
cursor: pointer;
transition: background-color 0.3s ease;
}
button:hover {
background-color: #58d3c5;
}
h2 {
margin-top: 30px;
color: #222;
}
ul {
list-style-type: none;
padding: 0;
}
li {
background: #f0f8ff;
margin-top: 10px;
padding: 10px;
border-radius: 8px;
font-size: 0.95rem;
}
INDEX.JS
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
22
<App />
</React.StrictMode>
);
SERVER
SERVER.JS
const express = require('express'); require('dotenv').config();
const express = require('express');
const cors = require('cors');
const path = require('path');
const fs = require('fs');
const connectDB = require('./config/db');
const authRoutes = require('./routes/authRoutes');
const courseRoutes = require('./routes/courseRoutes');
const quizRoutes = require('./routes/quizRoutes');
const userRoutes = require('./routes/userRoutes');
const liveClassRoutes = require('./routes/liveClassRoutes');
const app = express();
// Middleware
app.use(cors());
app.use(express.json());
// Create uploads directory if it doesn't exist
const uploadsDir = path.join(__dirname, 'uploads', 'materials');
if (!fs.existsSync(uploadsDir)) {
fs.mkdirSync(uploadsDir, { recursive: true });
}
// Serve static files from uploads directory
app.use('/uploads', express.static(path.join(__dirname, 'uploads')));
// Routes
app.use('/api/auth', authRoutes);
app.use('/api/courses', courseRoutes);
app.use('/api/quizzes', quizRoutes);
app.use('/api/users', userRoutes);
app.use('/api/live-classes', liveClassRoutes);
// Connect to Database
connectDB();
const PORT = process.env.PORT || 5000;
const server = app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
// --- SOCKET.IO CHAT INTEGRATION ---
23
const { Server } = require('socket.io');
const io = new Server(server, {
cors: {
origin: '*', // Allow all origins for dev; restrict in prod
methods: ['GET', 'POST']
}
});
io.on('connection', (socket) => {
console.log('A user connected:', socket.id);
socket.on('chat message', (msg) => {
// Broadcast the message to all clients
io.emit('chat message', msg);
});
socket.on('disconnect', () => {
console.log('User disconnected:', socket.id);
});
});
:${PORT}`);
24
CHAPTER 6
RESULTS AND DISCUSSIONS
FIGURE 3 Home Page
FIGURE 4 Register page
25
FIGURE 5 Login Page
FIGURE 6 Teacher Dashboard
26
FIGURE 8 MongoDB Connection Page
27
CHAPTER 7
CONCLUSION AND FUTURE ENHANCEMENT
The ClassConnect – Virtual Classroom Platform, developed using the MERN stack (MongoDB,
Express.js, React.js, Node.js), provides a powerful and scalable solution for managing online learning
environments. With features like secure user authentication, role-based dashboards for students and
teachers, course management, live classes, quizzes, and real-time communication, the platform addresses
the growing need for flexible and accessible education. The use of MongoDB ensures efficient data
management, while Express.js and Node.js handle backend logic and APIs. React.js powers a dynamic
and responsive user interface, enhancing the overall user experience.
To expand the platform’s capabilities, several future enhancements are planned. Integrating
video conferencing APIs (e.g., Zoom, Jitsi, or WebRTC) can improve live class experiences.
Adding AI-driven features like automated quiz evaluation, performance prediction, and
personalized learning paths will enrich learning outcomes. Gamification modules such as
badges, leaderboards, and points can boost student engagement. Mobile app compatibility will
offer better accessibility. Integrating Cloudinary or similar services for multimedia
management, offline support for limited connectivity regions, and analytics dashboards for
both students and teachers will elevate the platform’s educational impact. With continuous
development, ClassConnect is envisioned to become a comprehensive, intelligent, and user-
centric virtual learning ecosystem.
28
REFERENCES
[1] https://www.youtube.com/watch?v=B6v9uQ1bD8I – Building a Full Stack
MERN Application – Online Classroom Platform Tutorial.
[2] https://www.sciencedirect.com/science/article/pii/S0360131523002631 –
"Blended learning and virtual classrooms: A critical review of digital
education practices and trends."
[3]https://www.researchgate.net/publication/364253574_A_Study_on_Online
_Learning_Platforms_and_its_Impact_on_Student_Performance – "A
Study on Online Learning Platforms and its Impact on Student
Performance."
[4] https://www.sciencedirect.com/science/article/pii/S2666374021000483 –
"AI-powered features in virtual learning platforms: Opportunities and
challenges."
[5] https://www.youtube.com/watch?v=1jSrbL8TxE4 – "MERN Stack
Classroom Management System – Complete Project Walkthrough."
[6] Chugh, R., & Ruhi, U. (2018). "Open Educational Resources: Addressing
Challenges of Accessibility and Student Engagement in Virtual
Classrooms," Journal of Information Technology Education: Research, 17,
241–260.
[7] Al-Mukhaini, E.M., Al-Qayoudhi, W.S., & Al-Badi, A.H. (2014).
"Adoption of Social Networking in Education: A Study of the Use of Social
Networks by Higher Education Students in Oman," Journal of
International Education Research, 10(2), 143–154.
29