A Kanban board web app for organising tasks, contacts and team workflows — built as vanilla JavaScript ES modules on top of Firebase, with no framework and no build step.
Join covers the full flow: sign up or jump in as a guest, get a dashboard overview of your workload, create tasks with priorities, assignees and subtasks, then drag them across the board as work progresses.
Live demo: add your deployment URL here — use the Guest Log in button, no account needed.
- Authentication — email/password sign-up and login via Firebase Auth, plus an anonymous guest login for visitors who just want to look around.
- Protected member area — an auth guard on every internal page redirects unauthenticated visitors back to the login screen.
- Summary dashboard — counters for to-do, in-progress, awaiting-feedback, done and urgent tasks, the nearest upcoming urgent deadline, and a time-of-day greeting.
- Kanban board — four status columns (
todo,in-progress,await-feedback,done) with live search across task title, description, category and priority. - Drag and drop — mouse and touch support, so the board works on phones; the new status is written straight back to the Realtime Database.
- Task management — create, edit and delete tasks with title, description, due date, priority, category, assignees and subtasks.
- Subtasks — add, rename, delete and tick off subtasks; the card shows a progress bar.
- Contact management — grouped alphabetically, with detail view, colour-coded initial avatars, and create/edit/delete overlays.
- Assignee picker — dropdown fed from the contact list, showing avatars for the selected people.
- Responsive — the desktop sidebar collapses to a mobile bottom bar; overlays and forms adapt down to phone widths.
| Layer | Choice |
|---|---|
| Frontend | HTML, CSS, vanilla JavaScript (ES modules) |
| Backend | Firebase Authentication, Firebase Realtime Database |
| Docs | JSDoc |
| Tooling | None — no bundler, no dependencies, no build step |
Firebase is imported directly from the gstatic.com CDN as ES modules, so the whole app runs from any static file server.
You need a Firebase project with Authentication (Email/Password and Anonymous providers enabled) and a Realtime Database.
git clone https://github.com/NouBou1/join.git
cd join
cp scripts/firebase/firebase.example.js scripts/firebase/firebase.jsOpen scripts/firebase/firebase.js and paste in your own Firebase config values (Firebase console → Project settings → General → Your apps → SDK setup and configuration). That file is git-ignored, so credentials stay out of the repository.
Then serve the folder over HTTP — the app uses ES modules, so opening index.html straight from the filesystem will not work:
npx serve .
# or the VS Code "Live Server" extensionThe app is split into a public half and an authenticated half, each with its own script and template layer. Firebase reads and writes are funnelled through scripts/firebase/, so no page talks to the database directly.
join/
├── index.html # login screen — the entry point
├── robots.txt
├── assets/ # icons, fonts, logos
│ └── templates/ # shared header + sidebar markup
├── styles/ # global styles: reset, colours, fonts, layout
├── login/
│ ├── login.js # email/password + anonymous guest login
│ └── auth-guard.js # blocks member pages for unauthenticated visitors
├── public/ # reachable without an account
│ ├── signup.html
│ ├── legal-notice-public.html
│ ├── privacy-policy-public.html
│ ├── css/
│ └── js/ # signup, signup-validation, shared UI + templates
├── member/ # auth-protected application
│ ├── summary.html
│ ├── board.html
│ ├── add-task.html
│ ├── contacts.html
│ ├── help.html
│ ├── css/
│ └── js/
│ ├── board.js # task overlays, edit view, delete
│ ├── drag-n-drop.js # mouse + touch dragging, search, status writes
│ ├── drag-n-drop-render.js # column rendering and search matching
│ ├── add-task*.js # form, validation, assignee picker, subtask editor
│ ├── contacts*.js # list, alphabetical grouping, create/edit overlays
│ ├── subtask.js # subtask CRUD + completion toggle
│ ├── summary.js # dashboard counters and greeting
│ └── member-templates.js # HTML template functions
└── scripts/firebase/
├── firebase.example.js # config template — copy to firebase.js
├── get-firebase.js # read contacts + current user
├── get-task.js # read tasks
├── push-contact.js # write contacts
└── push-task.js # write tasks
Tasks are stored under /tasks in the Realtime Database:
{
"title": "Implement board search",
"description": "Add search support for kanban tasks",
"due_date": "2026-05-10",
"priority": "medium",
"assigned_to": {
"0": "Alex Example",
"1": "Sam Example"
},
"category": "technical-task",
"subtasks": {
"Subtask1": {
"status": false,
"title": "Create search input"
}
},
"status": "todo",
"createdAt": "2026-04-23T12:00:00.000Z"
}Contacts live under /contacts and are referenced by name from assigned_to.
Modules and exported functions carry JSDoc comments. Generate the browsable docs with:
npx jsdoc -r login member public scripts -d outThe generated out/ folder is git-ignored.
Join was built by a team of four as part of the Developer Akademie web development bootcamp.
My own contributions (294 of 967 commits) centred on:
- the Add Task page — form, validation, assignee dropdown and subtask editor
- the Contacts section — list rendering, alphabetical grouping and the create/edit overlays
- the shared template layer (
member-templates.js) and the header/sidebar components - the responsive CSS across the board, add-task and contacts views
- the Firebase read layer (
get-firebase.js) and parts of the drag-and-drop implementation
- Separate UI, data and state handling into clearer layers
- Add tests for auth, board status changes and form validation
- Replace the remaining inline
onclickhandlers with delegated event listeners - Tighten the Realtime Database security rules for a production deployment