A modern, full-stack task management application that allows users to create, manage, and track tasks through both traditional UI and innovative voice commands. Built with React, Express.js, MongoDB, and Web Audio APIs.
- Features
- Project Structure
- Tech Stack
- Prerequisites
- Installation
- Configuration
- Running the Application
- API Documentation
- Project Architecture
- Key Features Explanation
- Troubleshooting
- Contributing
- License
✅ User Authentication - Secure JWT-based authentication with password hashing
✅ Voice Input - Create and manage tasks using voice commands
✅ Task Management - Full CRUD operations with filtering and search
✅ Task Priority & Status - Organize tasks by priority (low/medium/high) and status (todo/in-progress/done)
✅ Responsive UI - Material-UI based modern frontend with React
✅ Real-time Updates - Instant task synchronization
✅ Secure API - Protected endpoints with JWT middleware
✅ MongoDB Persistence - Reliable data storage with Mongoose ODM
VoiceIT/
├── backend/ # Express.js server
│ ├── src/
│ │ ├── server.js # Main server configuration
│ │ ├── auth.routes.js # Authentication endpoints
│ │ ├── auth.middleware.js # JWT verification middleware
│ │ ├── tasks.routes.js # Task CRUD endpoints
│ │ ├── task.model.js # Task MongoDB schema
│ │ ├── user.model.js # User MongoDB schema
│ ├── package.json
│ ├── .env # Backend environment variables
│ └── .gitignore
│
├── frontend/ # React + Vite application
│ ├── src/
│ │ ├── components/ # Reusable React components
│ │ │ ├── Header.jsx
│ │ │ ├── TaskBoard.jsx
│ │ │ ├── TaskCard.jsx
│ │ │ ├── TaskFormModal.jsx
│ │ │ ├── TaskList.jsx
│ │ │ ├── todoContainer.jsx
│ │ │ └── VoiceInputModal.jsx
│ │ ├── context/ # React Context for state management
│ │ │ ├── AuthContext.jsx
│ │ │ └── TasksContext.jsx
│ │ ├── pages/ # Page components
│ │ │ ├── homePage.jsx
│ │ │ ├── login.jsx
│ │ │ └── signupPage.jsx
│ │ ├── services/ # API service modules
│ │ │ ├── auth.js
│ │ │ └── tasksApi.js
│ │ ├── hooks/ # Custom React hooks
│ │ │ └── useVoiceInput.js
│ │ ├── utils/ # Utility functions
│ │ │ ├── parseVoiceTask.js
│ │ │ ├── protectedRoutes.jsx
│ │ │ └── publicOnly.jsx
│ │ ├── App.jsx
│ │ ├── main.jsx
│ │ └── index.css
│ ├── package.json
│ ├── vite.config.js
│ ├── eslint.config.js
│ ├── .env # Frontend environment variables
│ └── .gitignore
│
└── README.md
- Runtime: Node.js (ES Modules)
- Framework: Express.js 4.22.x
- Database: MongoDB 8.0.x with Mongoose ODM
- Authentication: JWT (jsonwebtoken 9.0.x)
- Security: bcryptjs 3.0.x, CORS, Cookie-parser
- Logging: Morgan
- Development: Nodemon
- Framework: React 18.3.x
- Build Tool: Vite 7.2.x
- Routing: React Router DOM 7.10.x
- UI Library: Material-UI 5.18.x
- HTTP Client: Axios 1.13.x
- Styling: Styled Components 6.1.x
- Utilities: date-fns 4.1.x
- Linting: ESLint 8.57.x
Before installation, ensure you have the following installed:
- Node.js (v16 or higher) - Download
- npm (v7 or higher) - Comes with Node.js
- MongoDB (Local or Atlas) - Download or Atlas
- Git - Download
node --version # v16.x or higher
npm --version # v7.x or higher-
Navigate to the backend directory:
cd backend -
Install dependencies:
npm install
-
Create
.envfile in thebackend/directory:# Copy the content from the Configuration section below -
Verify the setup:
npm run dev
You should see:
Server running on http://localhost:5000
-
Navigate to the frontend directory:
cd frontend -
Install dependencies:
npm install
-
Create
.envfile in thefrontend/directory:# Copy the content from the Configuration section below -
Verify the setup:
npm run dev
You should see:
Local: http://localhost:5173
# Server Configuration
PORT=5000
NODE_ENV=development
# MongoDB Configuration
MONGO_URI=mongodb://localhost:27017/voice_tasks
# JWT Secret (Generate a strong secret)
JWT_SECRET=your_super_secret_jwt_key_change_this_in_production
# Client URL for CORS
CLIENT_URL=http://localhost:5173For Production:
PORT=5000
NODE_ENV=production
# Use MongoDB Atlas
MONGO_URI=mongodb+srv://username:password@cluster.mongodb.net/voice_tasks?retryWrites=true&w=majority
# Generate a strong JWT secret
JWT_SECRET=your_long_random_secret_key_32_characters_minimum
# Your production domain
CLIENT_URL=https://yourdomain.com# Development
VITE_API_URL=http://localhost:5000
# Production (uncomment and update)
# VITE_API_URL=https://api.yourdomain.com# Using Node.js
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
# Using OpenSSL
openssl rand -hex 32Terminal 1 - Start Backend:
cd backend
npm run devTerminal 2 - Start Frontend:
cd frontend
npm run devAccess the application at: http://localhost:5173
Build Frontend:
cd frontend
npm run buildStart Backend (Production Mode):
cd backend
NODE_ENV=production npm start- Development:
http://localhost:5000 - Production:
https://api.yourdomain.com
All protected endpoints require a valid JWT token sent via HTTP-Only cookies. The authentication system uses:
- Login/Signup: Issues a JWT token stored in HTTP-Only cookies
- Cookie Name:
token - Token Expiry: 7 days
- Secure Flag: Enabled in production
Create a new user account.
Request:
POST /auth/signup
Content-Type: application/json
{
"username": "john_doe",
"email": "john@example.com",
"password": "SecurePassword123!"
}Response (201 Created):
{
"success": true,
"user": {
"id": "507f1f77bcf86cd799439011",
"username": "john_doe",
"email": "john@example.com"
}
}Error Responses:
400 Bad Request- Email already exists500 Server Error- Server error
Authenticate user and receive a token.
Request:
POST /auth/login
Content-Type: application/json
{
"username": "john_doe",
"password": "SecurePassword123!"
}Response (200 OK):
{
"success": true,
"user": {
"id": "507f1f77bcf86cd799439011",
"username": "john_doe",
"email": "john@example.com"
}
}Error Responses:
400 Bad Request- User not found or incorrect password500 Server Error- Server error
Retrieve the authenticated user's information.
Request:
GET /auth/me
Cookie: token=<your_jwt_token>Response (200 OK):
{
"user": {
"id": "507f1f77bcf86cd799439011",
"username": "john_doe",
"email": "john@example.com"
}
}Error Responses:
401 Unauthorized- No valid token provided
Clear the authentication token.
Request:
POST /auth/logout
Cookie: token=<your_jwt_token>Response (200 OK):
{
"success": true,
"message": "Logged out"
}Retrieve all tasks with optional filtering.
Request:
GET /api/tasks?status=todo&priority=high&q=important
Cookie: token=<your_jwt_token>Query Parameters (Optional):
| Parameter | Type | Description |
|---|---|---|
status |
String | Filter by status: todo, in-progress, done |
priority |
String | Filter by priority: low, medium, high |
q |
String | Search in title and description (case-insensitive) |
Response (200 OK):
[
{
"_id": "507f1f77bcf86cd799439011",
"title": "Complete project documentation",
"description": "Write comprehensive API documentation",
"status": "in-progress",
"priority": "high",
"dueDate": "2024-12-31T23:59:59.000Z",
"createdAt": "2024-12-01T10:00:00.000Z",
"updatedAt": "2024-12-05T14:30:00.000Z"
},
{
"_id": "507f1f77bcf86cd799439012",
"title": "Review pull requests",
"description": "Check and review pending PRs",
"status": "todo",
"priority": "medium",
"dueDate": null,
"createdAt": "2024-12-02T09:30:00.000Z",
"updatedAt": "2024-12-02T09:30:00.000Z"
}
]Retrieve a single task by its ID.
Request:
GET /api/tasks/507f1f77bcf86cd799439011
Cookie: token=<your_jwt_token>Response (200 OK):
{
"_id": "507f1f77bcf86cd799439011",
"title": "Complete project documentation",
"description": "Write comprehensive API documentation",
"status": "in-progress",
"priority": "high",
"dueDate": "2024-12-31T23:59:59.000Z",
"createdAt": "2024-12-01T10:00:00.000Z",
"updatedAt": "2024-12-05T14:30:00.000Z"
}Error Responses:
404 Not Found- Task not found400 Bad Request- Invalid task ID format
Create a new task.
Request:
POST /api/tasks
Content-Type: application/json
Cookie: token=<your_jwt_token>
{
"title": "Fix login bug",
"description": "Users unable to login with special characters in password",
"status": "todo",
"priority": "high",
"dueDate": "2024-12-15T00:00:00Z"
}Request Body Fields:
| Field | Type | Required | Description |
|---|---|---|---|
title |
String | ✅ Yes | Task title (must be a non-empty string) |
description |
String | ❌ No | Task description (default: empty string) |
status |
String | ❌ No | One of: todo, in-progress, done (default: todo) |
priority |
String | ❌ No | One of: low, medium, high (default: medium) |
dueDate |
ISO String | ❌ No | Due date in ISO 8601 format (default: null) |
Response (201 Created):
{
"_id": "507f1f77bcf86cd799439013",
"title": "Fix login bug",
"description": "Users unable to login with special characters in password",
"status": "todo",
"priority": "high",
"dueDate": "2024-12-15T00:00:00.000Z",
"createdAt": "2024-12-06T10:15:00.000Z",
"updatedAt": "2024-12-06T10:15:00.000Z"
}Error Responses:
400 Bad Request- Title is required or invalid format500 Server Error- Failed to create task
Update an existing task (all fields optional).
Request:
PUT /api/tasks/507f1f77bcf86cd799439013
Content-Type: application/json
Cookie: token=<your_jwt_token>
{
"status": "in-progress",
"priority": "medium",
"dueDate": "2024-12-20T00:00:00Z"
}Request Body Fields (Optional):
| Field | Type | Description |
|---|---|---|
title |
String | Updated task title |
description |
String | Updated task description |
status |
String | One of: todo, in-progress, done |
priority |
String | One of: low, medium, high |
dueDate |
ISO String | Updated due date or null to clear |
Response (200 OK):
{
"_id": "507f1f77bcf86cd799439013",
"title": "Fix login bug",
"description": "Users unable to login with special characters in password",
"status": "in-progress",
"priority": "medium",
"dueDate": "2024-12-20T00:00:00.000Z",
"createdAt": "2024-12-06T10:15:00.000Z",
"updatedAt": "2024-12-06T11:45:00.000Z"
}Error Responses:
404 Not Found- Task not found400 Bad Request- Invalid task ID or update data500 Server Error- Failed to update task
Delete a task by its ID.
Request:
DELETE /api/tasks/507f1f77bcf86cd799439013
Cookie: token=<your_jwt_token>Response (200 OK):
{
"message": "Task deleted"
}Error Responses:
404 Not Found- Task not found400 Bad Request- Invalid task ID500 Server Error- Failed to delete task
Check if the server is running.
Request:
GET /healthResponse (200 OK):
{
"status": "ok"
}Express.js Server
├── CORS & Security Middleware
├── Routes
│ ├── /auth (Authentication)
│ │ ├── POST /signup
│ │ ├── POST /login
│ │ ├── POST /logout
│ │ └── GET /me
│ └── /api/tasks (Task CRUD)
│ ├── GET / (all tasks with filters)
│ ├── GET /:id
│ ├── POST / (create)
│ ├── PUT /:id (update)
│ └── DELETE /:id
└── MongoDB Database
├── users collection
└── tasks collection
React Application (Vite)
├── Context API (Global State)
│ ├── AuthContext (User authentication)
│ └── TasksContext (Task management)
├── Pages
│ ├── Login Page
│ ├── Signup Page
│ └── Home Page (Main dashboard)
├── Components
│ ├── Header
│ ├── TaskBoard (Kanban-style board)
│ ├── TaskList
│ ├── TaskCard
│ ├── TaskFormModal
│ └── VoiceInputModal (Voice command interface)
├── Services (API Layer)
│ ├── auth.js (Authentication API calls)
│ └── tasksApi.js (Task API calls)
└── Utilities
├── Voice input parsing
├── Protected routes
└── Public-only routes
The useVoiceInput hook provides voice command capabilities:
- Uses Web Audio API for recording
- Processes voice input through
parseVoiceTaskutility - Converts speech to structured task data
- Creates tasks with automatic parsing of priority and status
Users can filter tasks by:
- Status: todo, in-progress, done
- Priority: low, medium, high
- Search: Full-text search on title and description
- Stateless authentication using JWT tokens
- Tokens stored in HTTP-Only cookies (secure against XSS)
- 7-day expiration
- Automatic token refresh on login
- Frontend routes protected via
protectedRoutes.jsx - Backend endpoints secured with
auth.middleware.js - Unauthorized requests return 401 status
MongoDB Connection Error:
MongoDB connection error: connect ECONNREFUSED 127.0.0.1:27017
Solution:
- Ensure MongoDB service is running
- Check
MONGO_URIin.envfile - Verify MongoDB credentials if using Atlas
Port Already in Use:
Error: listen EADDRINUSE: address already in use :::5000
Solution:
# Windows PowerShell
Get-Process -Id (Get-NetTCPConnection -LocalPort 5000).OwningProcess | Stop-Process
# Mac/Linux
lsof -ti:5000 | xargs kill -9CORS Error:
Access to XMLHttpRequest blocked by CORS policy
Solution:
- Verify
CLIENT_URLin backend.envmatches your frontend URL - Check
VITE_API_URLin frontend.env - Ensure credentials are included in API calls
Blank Page on Startup:
# Clear node_modules and reinstall
rm -r node_modules package-lock.json
npm install
npm run devToken Not Persisting:
- Ensure cookies are enabled in browser
- Check that
SECUREflag is appropriate for your environment - Verify same-site cookie policy matches your setup
"Invalid Token" Error:
- Token may have expired (7 days)
- Clear cookies and login again
- Verify
JWT_SECRETis consistent across restarts
- Fork the repository
- Create a feature branch:
git checkout -b feature/your-feature - Commit changes:
git commit -m 'Add your feature' - Push to branch:
git push origin feature/your-feature - Submit a Pull Request
- Use ES6+ syntax
- Follow existing code style
- Add meaningful commit messages
- Test changes before submitting PR
# Set environment variables on Heroku
heroku config:set JWT_SECRET=your_secret
heroku config:set MONGO_URI=your_mongo_atlas_uri
heroku config:set CLIENT_URL=https://yourfrontend.com
# Deploy
git push heroku main# Install Vercel CLI
npm install -g vercel
# Deploy
vercelUpdate VITE_API_URL to point to your production backend.
This project is licensed under the MIT License - see the LICENSE file for details.
For issues, questions, or suggestions:
- Open an issue on GitHub
- Check existing documentation
- Review troubleshooting section
- Initial release
- Authentication system (signup/login/logout)
- Full task CRUD operations
- Voice input integration
- Task filtering and search
- Material-UI responsive design
Maintainer: VoiceIT Team