All work

TaskCraft

A task and project manager for a small team, written in plain JavaScript, with a mock REST backend that enforces who can do what.

  • Live demo
  • 2026
taskcraft.oussama.tech

At a glance

Why it matters
A small team gets projects, a board and roles that are enforced by the backend, so a member cannot edit or delete someone else's work.
My role
Solo, end to end
Stack
JavaScript, HTML, CSS, Chart.js

The problem

Most task tools are either a list with no rules or a product so large that setting it up becomes a project of its own. I wanted the middle: projects, tasks and a board, with roles that actually stop a member from deleting someone else's work.

I also wanted to build it without a framework, to see how far plain JavaScript goes when the structure is kept strict.

What it does

TaskCraft has a dashboard, a task list and a kanban board with drag and drop, projects with their own progress and hours, a team page, analytics and notifications. A search box finds tasks and projects, and the top bar scopes everything to one project.

There are three roles. An admin can do everything, a manager cannot delete projects or manage the team, and a member can only edit their own tasks. You can switch person in Settings and watch the interface change. Simulated teammates move tasks every twenty seconds or so, so the dashboard changes while you look at it.

Captures

How it works

Views never talk to the data directly

Views

  • components/*.jsDashboard, tasks, board, projects, team, settings
  • router.jsHash routes, one view at a time

Services

  • taskService.js and othersOne per resource. The only layer views call

HTTP seam

  • httpClient.jsSpeaks REST. Mock today, fetch to a real server later

Mock backend

  • mockServer.jsRoutes, validation, permissions, 403 answers
  • storage.jsThe database, kept in localStorage
  • realtime.jsEvents a WebSocket would deliver

Drawn from the js folder. Each layer only calls the one below it.

Decisions

Permissions live on the server side

The mock API checks every call against the role and answers 403 when it is not allowed. The interface hides or disables what a role cannot do, but that is a courtesy. The rule is enforced underneath it.

One seam to a real backend

Views call services, services call one HTTP client, and only that client knows the backend is a mock. The docs folder describes the REST contract and a PostgreSQL schema, so replacing the mock changes one file.

Everything rendered is escaped

Views are template strings, so every value goes through one escaping function. Routing reads only a page name and an id from the address, and those are matched against fixed patterns.

No build step to run it

It is classic scripts in a fixed order. It opens from a file on disk. For the public demo the scripts are minified and Chart.js and the font are served from the same site.

What I would build next

  • Implement the REST contract from the docs on a real server, with real sign-in and tokens.
  • Replace the simulated teammates with a WebSocket channel carrying the same events.
  • Comments and attachments on tasks.
  • Move it into a typed project with tests, now that the structure has held up.