Skip to content

Latest commit

History

58 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Task Manager

A MERN task-management app — React + Firebase authentication, TanStack Query for server state, Express + MongoDB CRUD API.

🔗 Live:https://task-manager-client.web.app/

Task Manager lets a signed-in user create tasks, mark them complete, comment on them, edit, and delete — with completed and incomplete tasks served from dedicated endpoints. It was built to practice server-state management with TanStack Query and a full CRUD lifecycle across a React client and an Express/MongoDB API.

Scope note: a learning project with no real users. Authentication is currently handled on the client; the API's trust model and the next step to harden it are described under Known limitations.


What this demonstrates

  • Goal: keep server data fresh without hand-rolled fetch logic → Approach: TanStack Query owns every read, with mutations invalidating the relevant query keys → Outcome: task lists refetch automatically after create/edit/complete/delete, with no manual state syncing.
  • Goal: filter by completion status without shipping the whole list → Approach: dedicated /incompleteTasks/:email and /completedTasks/:email endpoints filter in MongoDB → Outcome: the client fetches only the subset it renders.
  • Goal: validated forms without boilerplate → Approach: React Hook Form across sign-in, register, add-task, edit-task, and the comment modal → Outcome: consistent validation and submission handling in six components.
  • Goal: gate the app behind a login → Approach: a Firebase AuthProvider context (email/password + Google) feeding protected routes → Outcome: unauthenticated users are redirected away from task views.
  • Goal: attach a note to a task → Approach: a comment modal writing through PUT /addComment/:idOutcome: per-task commenting backed by a single document update.

Architecture

┌──────────────────────────────┐ ┌────────────────────────────────┐
│ Client (React SPA) │ HTTP │ Server (Express) │
│ │ ─────▶ │ │
│ • AuthProvider (Firebase) │ │ • CRUD routes over /alltask │
│ • TanStack Query (server │ ◀───── │ • status-filtered reads │
│ state + invalidation) │ JSON │ (/incompleteTasks/:email) │
│ • React Hook Form │ │ • cors + express.json │
└──────────────────────────────┘ └───────────────┬────────────────┘
│ ▼
▼ MongoDB Atlas (native driver)
Firebase Authentication taskManagerDBUser · allTask
(email/password · Google)
│
└─▶ identity lives in the browser only; no token reaches the API

Trust model: Firebase handles authentication in the browser. At this stage the API scopes tasks by an email value from the request rather than by a verified token — a deliberate simplification for a learning build, with token verification noted as the next step below.


Tech stack

LayerStack
FrontendReact 18.2, React Router DOM 6.6, React-Bootstrap 2.7, react-icons, AOS
Server stateTanStack Query 4.20
FormsReact Hook Form 7.41
Auth (client)Firebase 9.15 Authentication (email/password, Google)
UXreact-toastify 9.1, react-loader-spinner
BackendNode.js, Express 4.18, MongoDB native driver 4.13
HostingFirebase Hosting (client) · Vercel (API)

API surface

MethodRoutePurpose
GET/mytasks?email=all tasks for a user
GET/incompleteTasks/:emailstatus-filtered read
GET/completedTasks/:emailstatus-filtered read
GET/editReview/:idfetch one task for editing
GET/commentTask/:idfetch one task for commenting
POST/alltaskcreate a task
PUT/addComment/:idset a task's comment
PATCH/updateReview/:idrename a task
PATCH/updateStatus/:idmark a task complete
DELETE/deleteTask/:iddelete a task

Deep-dive — server state with TanStack Query

The piece worth examining is how the client stays consistent. Every task view (MyTasks, CompletedTasks, NotCompletedTasks) is a query keyed by the user's email and the view's status; every write (add, edit, complete, comment, delete) invalidates the affected keys rather than mutating local state by hand. Combined with the status-filtered endpoints, this means a "mark complete" action moves a task between two independently-cached lists with a single invalidation, and the UI never holds a stale copy it has to reconcile. This is the difference between caching server data and owning it in component state — and it's the concept the project set out to practice.


Known limitations & next steps

  • API authentication is the main next step. Routes currently scope tasks by a caller-supplied email rather than a verified Firebase ID token, so the API trusts that value rather than a proven identity — fine for a demo, but not production-ready. The planned fix is to send the Firebase ID token as a Bearer header and verify it server-side (Firebase Admin SDK) before trusting any email.
  • Completion is one-way.PATCH /updateStatus/:id unconditionally sets status: 'complete'; there is no un-complete path. It should accept the target status.
  • Legacy route names. Task routes are named from an earlier review-oriented iteration (/editReview, /updateReview) and should be renamed to match the domain.
  • No server-side validation. Request bodies are trusted as-is; a schema layer belongs at the edge.

Run locally

git clone https://github.com/mahmud035/task-manager.git
cd task-manager
# Clientcd client
npm install
npm start # http://localhost:3000# Server (second terminal)cd ../server
npm install
npm run start-dev # nodemon, http://localhost:5000

Server env (server/.env):

DB_USER=...
DB_PASSWORD=...
PORT=5000

Provide your own Firebase web config in client/src/firebase config/firebase.config.js.

About

MERN task-management app — React + Firebase auth (client-side), TanStack Query server state, React Hook Form, and an Express/MongoDB CRUD API with status-filtered endpoints.

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages