A full-stack Employee Management System built with React, Node.js, Express, and MongoDB.
- Node.js v18+
- MongoDB (local or Atlas)
# Navigate to the project root
cd emscd backend
npm installEdit .env if needed:
PORT=5000
MONGO_URI=mongodb://localhost:27017/ems
JWT_SECRET=ems_super_secret_jwt_key_2024
JWT_EXPIRE=7d
Start MongoDB locally, then:
# Seed the database with dummy data
npm run seed
# Start the API server (development)
npm run devcd frontend
npm install
npm run dev| Role | Password | |
|---|---|---|
| Admin | admin@ems.com | admin123 |
| HR | priya@ems.com | EMP0002 |
| Employee | rajesh@ems.com | EMP0001 |
All newly created employees have their Employee ID as their default password (e.g.,
EMP0001)
ems/
├── backend/
│ ├── src/
│ │ ├── config/ # MongoDB connection
│ │ ├── controllers/ # Business logic
│ │ ├── middleware/ # Auth, error handling
│ │ ├── models/ # Mongoose schemas
│ │ ├── routes/ # Express routes
│ │ └── utils/ # JWT helper, seed script
│ └── .env
│
└── frontend/
└── src/
├── api/ # Axios instance
├── components/ # Layout, UI components
├── context/ # Auth + Theme context
├── pages/ # Route-level pages
└── routes/ # Protected route guard
- JWT-based login/logout
- Role-based access: Admin, HR, Employee
- Password hashing with bcrypt
- Auto token refresh / expiry handling
- Total employees, departments, attendance stats
- Bar chart (monthly attendance)
- Pie chart (department distribution)
- Recent employees table
- Add, edit, delete employees
- Search by name/ID/email/designation
- Filter by department and status
- Export to CSV
- Pagination
- Create / edit / delete departments
- Set department head
- Employee count per department
- Mark attendance (present/absent/late/half-day/on-leave)
- View history with filters
- Monthly report with CSV export
- Apply for leave (all types)
- Approve / reject with reason
- Status tracking (pending/approved/rejected)
- Generate payroll for all employees in one click
- Auto-calculate HRA, PF, tax, allowances
- Annual payroll overview chart
- PDF payslip download (jsPDF)
- Dark mode (with toggle)
- Collapsible sidebar
- Skeleton loading states
- Toast notifications
- Responsive design
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/auth/login | Login |
| GET | /api/auth/me | Current user |
| GET | /api/employees | List employees |
| POST | /api/employees | Create employee |
| PUT | /api/employees/:id | Update employee |
| DELETE | /api/employees/:id | Delete employee |
| GET | /api/departments | List departments |
| POST | /api/departments | Create department |
| GET | /api/attendance | List attendance |
| POST | /api/attendance | Mark attendance |
| GET | /api/attendance/report | Monthly report |
| GET | /api/leave | List leaves |
| POST | /api/leave | Apply leave |
| PUT | /api/leave/:id/status | Approve/reject leave |
| GET | /api/payroll | List payroll |
| POST | /api/payroll | Generate payroll |
| GET | /api/payroll/overview | Annual overview |
| GET | /api/dashboard/stats | Dashboard metrics |
| Layer | Technology |
|---|---|
| Frontend | React 18 + Vite |
| Styling | Tailwind CSS v4 |
| Charts | Recharts |
| HTTP | Axios |
| jsPDF + autotable | |
| Toast | react-hot-toast |
| Backend | Node.js + Express |
| Database | MongoDB + Mongoose |
| Auth | JWT + bcryptjs |
- Profile image upload placeholder is ready (Multer configured); connect to Cloudinary by updating the upload config.
- Default employee password is their Employee ID. Employees should change it on first login.