Skip to content

Latest commit

 

History

6 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

📝 Planora

A full-stack task management platform with JWT authentication, color-tagged categories, task assignment, and full-text search — built on the MERN stack and deployed serverless.

Live Demo

React Node.js Express MongoDB Tailwind CSS JWT Vercel

Live App • Features • Tech Stack • Quick Start • API Reference


📋 Table of Contents


🔎 Overview

Planora is a MERN-stack task manager built to keep a simple promise: log in, see what's on your plate, and get through it — with categories, priorities, and search to keep things organized as the list grows.

Why this project:

  • ✅ Real authentication — JWT access + refresh token flow with bcrypt password hashing and automatic silent token refresh on the frontend, not a mock login
  • ✅ Soft-delete safe — deleting a task marks it removed instead of destroying the record
  • ✅ Task assignment — tasks can be owned by one user and assigned to another, with access checks on both sides
  • ✅ Deployed serverless — backend and frontend both run on Vercel, connected to MongoDB Atlas, with the Express app adapted to a serverless entry point
  • ✅ Custom design system — a distinct visual identity (teal/amber/sage palette, serif + monospace type pairing) rather than default component styling

✨ Features

🔐 Authentication & Access

  • Register / login with JWT access + refresh tokens
  • Access tokens auto-refresh transparently via an Axios interceptor — no forced re-login on expiry
  • Protected routes on both frontend (React Router guards) and backend (middleware)
  • Rate-limited auth endpoints to slow brute-force attempts

✅ Task Management

  • Create, edit, and soft-delete tasks with title, description, priority, due date, and category
  • Status workflow: To do → In progress → Done → Archived, with completed_at tracked automatically
  • Full-text search across title and description
  • Filter by status, priority, or category
  • Assign a task to another user; both the owner and assignee can view and update status

🏷️ Categories

  • Color-tagged categories for quick visual grouping
  • Three default categories (Personal, Work, Urgent) auto-created on signup
  • Create, rename, or delete custom categories (defaults are protected from deletion)

📊 Dashboard

  • At-a-glance counts of To do / In progress / Done
  • "Coming up next" view of unfinished tasks sorted by due date

⚙️ Profile

  • Editable name and email
  • Secure password change flow (current password required)

🛠 Tech Stack

Frontend

  • React 18 (Vite)
  • React Router
  • Tailwind CSS
  • Axios (with token-refresh interceptor)
  • lucide-react (icons)

Backend

  • Node.js + Express
  • MongoDB + Mongoose
  • JWT (jsonwebtoken) — separate access/refresh secrets
  • bcryptjs
  • express-validator, express-rate-limit, helmet, cors

Infrastructure

  • MongoDB Atlas (database)
  • Vercel (frontend + backend hosting, backend as serverless functions)

📁 Project Structure

planora-mern/
├── backend/
│   ├── api/
│   │   └── index.js         # Vercel serverless entry point
│   ├── src/
│   │   ├── config/           # Database connection (with connection caching)
│   │   ├── controllers/      # Route handlers (auth, tasks, categories, users)
│   │   ├── middleware/       # JWT auth guard, centralized error handler
│   │   ├── models/           # Mongoose schemas (User, Task, Category, RefreshToken)
│   │   ├── routes/           # Express route definitions
│   │   └── utils/            # JWT helpers, validators
│   ├── app.js                 # Express app (exported for both local + serverless use)
│   ├── server.js              # Local dev entry point (app.listen)
│   └── vercel.json
└── frontend/
    ├── src/
    │   ├── api/                # Axios client with refresh-token interceptor
    │   ├── components/         # Layout, TaskCard, StatusPill, PriorityPill, ProtectedRoute
    │   ├── context/             # Auth context
    │   └── pages/               # Login, Register, Dashboard, Tasks, Categories, Profile
    └── vercel.json

🚀 Quick Start

Prerequisites

  • Node.js 18+
  • A MongoDB connection string (local or MongoDB Atlas)

Backend

cd backend
npm install
cp .env.example .env      # then fill in your values
npm run dev                # http://localhost:5000

Frontend

cd frontend
npm install
cp .env.example .env       # VITE_API_URL=http://localhost:5000/api/v1
npm run dev                 # http://localhost:5173

Open http://localhost:5173, click Create an account, and start adding tasks — three default categories are created for you automatically.


🔑 Environment Variables

backend/.env

PORT=5000
NODE_ENV=development
MONGO_URI=your_mongodb_connection_string
JWT_ACCESS_SECRET=your_access_token_secret
JWT_REFRESH_SECRET=your_refresh_token_secret
JWT_ACCESS_EXPIRES=15m
JWT_REFRESH_EXPIRES=7d
CLIENT_ORIGINS=http://localhost:5173

frontend/.env

VITE_API_URL=http://localhost:5000/api/v1

On Vercel, CLIENT_ORIGINS must exactly match the deployed frontend URL, and VITE_API_URL must point at the deployed backend + /api/v1.


📡 API Reference

All routes are prefixed /api/v1.

Method Route Access Description
POST /auth/register Public Create an account (also creates default categories)
POST /auth/login Public Log in
POST /auth/refresh Public Exchange refresh token for a new access token
POST /auth/logout Public Revoke a refresh token
GET /auth/me Auth Current user
GET /tasks Auth List tasks (filter by status, priority, category_id; paginated)
GET /tasks/search?q= Auth Full-text search
POST /tasks Auth Create a task
GET /tasks/:id Auth Get a single task
PUT /tasks/:id Auth (owner) Update a task
PATCH /tasks/:id/status Auth (owner/assignee) Update task status
DELETE /tasks/:id Auth (owner) Soft-delete a task
POST /tasks/:id/assign Auth (owner) Assign a task to another user
GET /categories Auth List categories
POST /categories Auth Create a category
PUT /categories/:id Auth Update a category
DELETE /categories/:id Auth Delete a category (defaults protected)
GET /users/me Auth View profile
PUT /users/me Auth Update profile
PUT /users/me/password Auth Change password

🗄️ Data Models

User — name, email, password (hashed), createdAt

Task — title, description, status (todo/in_progress/done/archived), priority (low/medium/high), due_date, completed_at, deleted_at, user, assigned_to, category

Category — name, color, is_default, user

RefreshToken — token, user, expires_at, revoked (auto-expiring via MongoDB TTL index)


☁️ Deployment

This project is deployed as two separate Vercel projects sharing one MongoDB Atlas cluster:

  • Frontend → Vercel (root directory: frontend)
  • Backend → Vercel serverless functions (root directory: backend, entry point api/index.js)

See backend/vercel.json and frontend/vercel.json for the routing configuration. The Express app in backend/app.js is shared between the local dev server (server.js) and the serverless handler (api/index.js), with the MongoDB connection cached across warm serverless invocations.


⚠️ Known Limitations

  • No seeded demo account yet — every visitor needs to register their own account to try the app
  • No automated test suite
  • Task assignment is single-assignee only; no multi-user collaboration on one task yet
  • Category colors are chosen from a fixed swatch rather than a full color picker

📄 License

This project is open for personal and educational use.

About

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages