A full-stack web application for managing courses, enrollments, and academic journeys — built with React, Node.js, Express, and MongoDB.
Skills is a cloud-based course management platform that enables users to create, browse, enroll in, and manage academic courses. The application follows a client–server architecture with a React-based frontend communicating with a RESTful Express.js backend, all backed by MongoDB for persistent data storage.
The platform was built as a semester project for the Cloud Computing and AI Services course (8th Semester) and demonstrates full-stack development principles including JWT-based authentication, CRUD operations, role-based access control, and responsive UI design.
- User Registration — Create an account with name, email, and password
- Secure Login — JWT-based authentication with 1-hour token expiry
- Password Hashing — All passwords are hashed using bcrypt (10 salt rounds)
- Protected Routes — Auth middleware guards sensitive endpoints; token is stored in
localStorage - Conditional UI — Navbar dynamically shows Login/Logout based on auth state
- Create Courses — Authenticated users can create courses with a title, semester, and description
- View All Courses — Public listing of all available courses with creator information
- Edit Courses — Course creators can update title, semester, and details of their own courses
- Delete Courses — Remove courses from the system via API
- Manage My Courses — Dedicated dashboard showing only courses created by the logged-in user
- One-Click Enrollment — Enroll in any available course with a single button click
- Track Enrollments — View all courses you are currently enrolled in
- Unenroll — Leave a course at any time; updates both user and course records
- Duplicate Prevention — Server-side checks prevent enrolling in the same course twice
- Enrolled Users Tracking — View which users are enrolled in a specific course
- Responsive Design — Fully responsive layout with mobile hamburger menu (HeadlessUI Dialog)
- Landing Page — Hero section, feature highlights, Bento grid showcase, and platform statistics
- Restricted Access Pages — Unauthenticated users see clear prompts to sign up before accessing protected pages
- Clean Card-Based Layout — Courses are displayed in card format for easy browsing
| Layer | Technology |
|---|---|
| Frontend | React 18, React Router DOM v6, Vite 5, TailwindCSS 3, Axios |
| UI Library | HeadlessUI (Dialog, DialogPanel), Heroicons |
| Backend | Node.js, Express.js 4, body-parser, CORS |
| Database | MongoDB (via Mongoose 8) |
| Auth | JSON Web Tokens (jsonwebtoken), bcrypt |
| Dev Tools | ESLint, PostCSS, Autoprefixer, Vite Plugin React |
| Font | Inter (loaded via rsms.me/inter) |
Cloud-computing-project/
│
├── backend/ # Express.js REST API server
│ ├── index.js # Server entry point — Express app, MongoDB connection, route mounting
│ ├── package.json # Backend dependencies and scripts
│ ├── .gitignore # Ignores .env and node_modules
│ │
│ ├── models/ # Mongoose data models
│ │ ├── Course.js # Course schema (title, details, semester, enrollStatus, creator, enrolledUsers)
│ │ └── User.js # User schema (name, email, password, enrolledCourses, createdCourses)
│ │
│ ├── routes/ # API route handlers
│ │ ├── authRoutes.js # POST /signup and POST /signin endpoints
│ │ └── courseRoutes.js # Full CRUD for courses + enrollment/unenrollment endpoints
│ │
│ └── middleware/ # Express middleware
│ └── authMiddleware.js # JWT verification middleware — extracts user ID from token
│
├── frontend/ # React + Vite SPA
│ ├── index.html # HTML entry point
│ ├── package.json # Frontend dependencies and scripts
│ ├── vite.config.js # Vite configuration with React plugin
│ ├── tailwind.config.js # TailwindCSS configuration
│ ├── postcss.config.js # PostCSS configuration (TailwindCSS + Autoprefixer)
│ ├── eslint.config.js # ESLint configuration for React
│ │
│ ├── public/ # Static public assets
│ │
│ └── src/ # Application source code
│ ├── main.jsx # React DOM root render
│ ├── App.jsx # React Router setup with all route definitions
│ ├── App.css # Global application styles
│ ├── index.css # TailwindCSS base imports
│ │
│ ├── assets/ # Static images
│ │ ├── logo.png # Skills platform logo
│ │ ├── performance.png # Performance section graphic
│ │ ├── phoneimage.png # Mobile responsive showcase image
│ │ └── viewcoursesphoto.png# Feature section screenshot
│ │
│ ├── pages/ # Route-level page components
│ │ ├── Landing.jsx # Home page — assembles Hero, Features, Bento, Stats, Footer
│ │ ├── Signin.jsx # Sign in page wrapper
│ │ ├── Signup.jsx # Sign up page wrapper
│ │ ├── ViewCourses.jsx # Browse and enroll in all available courses
│ │ ├── CreateCourse.jsx # Create a new course (auth-gated)
│ │ ├── EditCourse.jsx # Edit an existing course by ID
│ │ ├── ManageCourses.jsx # Dashboard for user-created courses (auth-gated)
│ │ └── TrackEnrollment.jsx # View and manage enrolled courses (auth-gated)
│ │
│ └── components/ # Reusable UI components
│ ├── Navbar.jsx # Global navigation bar with mobile menu and auth state
│ ├── Hero.jsx # Landing page hero section with CTA buttons
│ ├── Features.jsx # Feature highlights with icons and screenshot
│ ├── BentoGrid.jsx # Bento-style grid showcasing platform capabilities
│ ├── Stats.jsx # Platform statistics display
│ ├── FooterSection.jsx # Footer with copyright and links
│ ├── SigninComponent.jsx # Sign in form with JWT token storage
│ ├── SignupComponent.jsx # Sign up form with validation
│ ├── FormCreateCourse.jsx # Course creation form
│ ├── CardViewCourses.jsx # Course card for browsing (with Enroll button)
│ ├── ManageCourseCard.jsx # Course card for management (with Edit button)
│ └── TrackEnrollmentCard.jsx # Enrolled course card (with Unenroll button)
│
└── README.md # This file
Ensure you have the following installed on your system:
- Node.js (v16 or higher) — Download
- npm (comes bundled with Node.js)
- MongoDB — Either a local instance or a MongoDB Atlas cloud cluster
- Git — Download
git clone https://github.com/yourusername/Cloud-computing-project.git
cd Cloud-computing-projectcd backend
npm install- Create a free MongoDB Atlas cluster at mongodb.com/atlas (or install MongoDB locally).
- Get your connection string (Node.js driver) and replace
<password>with your database user password. Don't forget to append a database name (e.g.cloud_course) before the?. - Create a
.envfile in thebackend/directory and add your connection string:
mongoDBUrl=mongodb+srv://<username>:<password>@cluster0.xxxx.mongodb.net/cloud_course?retryWrites=true&w=majorityNote: If you are running MongoDB locally, use
mongoDBUrl=mongodb://localhost:27017/cloud_course
cd ../frontend
npm installOpen two terminal windows:
Terminal 1 — Backend Server:
cd backend
node index.jsThe backend server starts at http://localhost:3000.
Terminal 2 — Frontend Dev Server:
cd frontend
npm run devThe frontend starts at http://localhost:5173 (default Vite port).
- Open the app — Navigate to
http://localhost:5173in your browser - Browse courses — Click "View Courses" to see all available courses (no login required)
- Create an account — Click "Get Started" or navigate to
/signupto register - Sign in — Navigate to
/signinand log in with your credentials - Create a course — Go to "Create Course" and fill in the title, semester, and description
- Manage your courses — Visit "Manage Courses" to see courses you created, then click "Edit" to modify them
- Enroll in courses — On the "View Courses" page, click "Enroll Now!" on any course card
- Track enrollments — Go to "Track Enrollment" to see all courses you are enrolled in
- Unenroll — Click "Unenroll" on any enrolled course card to leave the course
- Log out — Click "Log out" in the navbar to clear your session
| Variable | Location | Description | Required |
|---|---|---|---|
mongoDBUrl |
backend/.env |
MongoDB connection string | ✅ Yes |
| Service | Default Port | Configurable In |
|---|---|---|
| Backend | 3000 |
backend/index.js |
| Frontend | 5173 |
frontend/vite.config.js |
| Parameter | Value | Location |
|---|---|---|
| Secret Key | CloudProject |
backend/routes/authRoutes.js and backend/middleware/authMiddleware.js |
| Expiry | 1 hour |
backend/routes/authRoutes.js |
⚠️ Security Note: The JWT secret is currently hardcoded. For production deployments, move it to an environment variable.
Screenshots of the application can be found in the
frontend/src/assets/directory. Below are the key pages:
| Page | Description |
|---|---|
| Landing Page | Hero section with CTA, feature highlights, bento grid |
| View Courses | Card-based listing of all available courses |
| Create Course | Form to create a new course (title, semester, details) |
| Manage Courses | Dashboard showing user-created courses with edit option |
| Track Enrollment | List of enrolled courses with unenroll option |
| Sign Up / Sign In | Authentication forms with feedback messages |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | /api/auth/signup |
❌ | Register a new user (name, email, password) |
| POST | /api/auth/signin |
❌ | Login and receive a JWT token |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| GET | /api/courses |
❌ | Retrieve all courses with creator names |
| GET | /api/course/:id |
❌ | Retrieve a specific course by its ID |
| POST | /api/course |
✅ | Create a new course (linked to logged-in user) |
| PUT | /api/course/:id |
❌ | Update a course by ID |
| DELETE | /api/course/:id |
❌ | Delete a course by ID |
| GET | /api/my-courses |
✅ | Get courses created by the logged-in user |
| GET | /api/course/:id/enrolled-users |
❌ | Get list of users enrolled in a specific course |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | /api/enroll/:id |
✅ | Enroll the logged-in user in a course |
| GET | /api/enrolled-courses |
✅ | Get all courses the logged-in user is enrolled in |
| DELETE | /api/unenroll/:courseId |
✅ | Unenroll the logged-in user from a course |
Auth Legend: ✅ = Requires
Authorization: Bearer <token>header | ❌ = Public endpoint
- Hardcoded JWT Secret — The JWT secret key (
CloudProject) is hardcoded in the source code instead of being stored as an environment variable. This is a security risk in production. - Hardcoded API Base URL — The frontend uses
http://localhost:3000as the API base URL in multiple components. This should be extracted to an environment variable for deployment flexibility. - No Input Validation on Frontend — While required fields are enforced, there is no email format validation or password strength enforcement on the client side.
- No Course Deletion UI — The delete API endpoint exists, but there is no corresponding button or UI for deleting courses from the frontend.
- Alert-Based Feedback — Some user actions (enroll, unenroll) use
alert()for feedback instead of in-page toast notifications. - No Pagination — Course listings are not paginated; loading large numbers of courses may impact performance.
- PUT/DELETE Routes Unprotected — The
PUT /api/course/:idandDELETE /api/course/:idendpoints do not require authentication, meaning any client can modify or delete any course.
- Environment-based Configuration — Move JWT secret and API URLs to
.envfiles - Role-Based Access Control — Introduce admin and student roles with distinct permissions
- Course Deletion UI — Add a delete button with confirmation dialog on the Manage Courses page
- Search & Filter — Enable searching courses by title, semester, or creator
- Pagination — Implement paginated course listing for better scalability
- Toast Notifications — Replace
alert()calls with modern toast/snackbar notifications - Profile Page — Display user details, enrolled courses, and created courses in one view
- Password Reset — Implement forgot-password flow with email verification
- Google OAuth — Activate Google OAuth sign-in (Passport.js dependencies are already installed)
- Deployment — Deploy backend to a cloud platform (AWS, Heroku, Railway) and frontend to Vercel/Netlify
- Unit & Integration Tests — Add test coverage for API endpoints and UI components
- Course Categories & Tags — Allow tagging courses for better discoverability
Contributions are welcome! Follow these steps to contribute:
- Fork the repository
- Clone your fork locally:
git clone https://github.com/your-username/Cloud-computing-project.git
- Create a feature branch:
git checkout -b feature/your-feature-name
- Make your changes and commit with descriptive messages:
git add . git commit -m "feat: add course search functionality"
- Push to your fork:
git push origin feature/your-feature-name
- Open a Pull Request against the
mainbranch with a clear description of your changes.
- Follow existing code conventions and folder structure
- Use meaningful variable and function names
- Add comments explaining why code exists, not what it does
- Test your changes locally before opening a PR
This project is licensed under the MIT License.
MIT License
Copyright (c) 2024 Skills
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Built with ❤️ for the Cloud Computing and AI Services course
"# Cloud-computing-project"