A dated task manager with a stationery-style UI: cream paper, black type, and checkbox rows. Guests see the empty list behind a sign-in modal. Signed-in users get a week strip, calendar, profile, and per-day tasks stored in MongoDB.
- Auth — email/password sign up and sign in (NextAuth JWT). Guests cannot use calendar, add-task, or profile until they sign in.
- Daily board — tasks for the selected day with priority, assignee, in-progress, and done.
- Week strip — Monday–Sunday header to jump between days.
- Calendar — month view of dated tasks; undated items listed separately.
- Add task — title, who, due date, high / medium / low priority.
- Notes — freeform notes on the home board, saved per user.
- Profile — name, email, password change, plus week and month completion tracking.
- Visible passwords — show/hide on auth and profile fields.
- English toasts — success and error messages in English.
| Layer | Choice |
|---|---|
| Framework | Next.js 16 (App Router) |
| UI | React 19, CSS (no UI kit) |
| Auth | NextAuth.js v4 (credentials + JWT) |
| Database | MongoDB via Mongoose 7 |
| Passwords | bcryptjs |
| Fonts | next/font (Montserrat) |
| Hosting | Vercel |
| Local DB | Docker Compose (MongoDB 7) |
Node.js 20.9+ is required (engines in package.json).
Server Components load user data. Client components handle interaction only (forms, checkboxes, week strip, footer).
Browser
└── App Router pages (SSR)
├── getSession() cached per request
├── getTodoBoard()
└── getProfileData()
└── MongoDB (User + embedded todos)
Mutations go through Route Handlers:
POST /api/auth/signup
POST /api/auth/[...nextauth]
GET /api/todo | POST | PATCH
GET /api/profile | POST
Rendering
- SSR — home, calendar, profile, and add-task read the session and MongoDB on the server, then pass serializable props to the client.
- Streaming — the root layout wraps auth in
Suspenseso a static sheet fallback can paint first. - SSG — icons and other static assets. User pages stay dynamic because they depend on cookies.
Auth
Protected pages (/calendar, /profile, /todos, /add-todo) call getSession() and redirect("/") when there is no session. The layout still shows the empty board plus the auth modal for guests.
Folder layout
src/
app/ routes, layouts, Route Handlers
components/
layout/ AppShell, loading fallback
module/ small UI pieces (Tasks, WeekStrip, AuthModal)
template/ page-level client views
models/ Mongoose schemas
providers/ session + selected-day context
utils/ db, auth, dates, stats, serialization
Import aliases (@/utils/*, @/module/*, @/template/*, …) live in jsconfig.json.
- Server by default.
"use client"only where hooks or browser APIs are needed. - One session read per request.
getSession()is wrapped in Reactcache(). - Lean reads, documents for writes. List/profile pages use
.lean(); APIs that mutate load a Mongoose document. - Serialize before the client. ObjectIds become strings in
src/utils/todos.js. - Optimistic UI for checkbox status; failed PATCHes refresh from the server.
- Scoped updates. Task status changes go through
user.todos.id(id)so users cannot update another user’s task. - Passwords are hashed; they are never selected on profile reads.
- English-only user-facing errors and toasts.
- No secrets in git.
.envis ignored; copy.env.example.
npm installcp .env.example .envLocal Docker values:
NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=replace-with-a-long-random-string
MONGO_USER=milad
MONGO_PASS=12345
MONGO_URI=mongodb://${MONGO_USER}:${MONGO_PASS}@127.0.0.1:27017/todolist?authSource=adminGenerate a secret: openssl rand -base64 32.
npm run db:upThis starts MongoDB 7 with the user/password from .env. Stop it with npm run db:down.
npm run devOpen http://localhost:3000.
| Script | Purpose |
|---|---|
npm run dev |
Next.js dev server |
npm run build |
Production build |
npm start |
Serve the production build |
npm run lint |
ESLint |
npm run db:up |
Start local MongoDB |
npm run db:down |
Stop local MongoDB |
Each User document holds:
email, hashedpassword,name,lastName,notestodos[]—title,status(todo|inProgress|done),who,dueDate,priority
- Connect the GitHub repo to Vercel (Next.js is detected automatically).
- Attach MongoDB Atlas from Vercel Storage (for example
mine-db). That injectsMONGODB_URI. - Set the remaining variables for Production (and Preview if you use it):
NEXTAUTH_URL=https://your-app.vercel.app
NEXTAUTH_SECRET=a-long-random-stringNEXTAUTH_URL must be the public origin, no trailing slash. Preview deployments use a host like https://todo-next-git-main-YOURTEAM.vercel.app.
Do not set local MONGO_URI / MONGO_USER / MONGO_PASS on Vercel. The app prefers MONGODB_URI.
- Redeploy after changing env vars.
To use the same Atlas database locally:
npx vercel env pull .env.localIf a preview URL asks you to log in to Vercel itself, that is Deployment Protection, not this app’s auth modal.
Private project — not licensed for reuse unless you add a license.