diff --git a/README.md b/README.md index 15fbe10..18318a6 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,11 @@ # FabDash -### Fabrication Dashboard — A Sleek, Modern Project Management & Scheduling Application + +**Fabrication Dashboard** — A sleek, modern project management & scheduling application built for fabrication workflows. ![Version](https://img.shields.io/badge/version-1.0.0--alpha-gold) ![Stack](https://img.shields.io/badge/stack-React%20%2B%20Flask%20%2B%20SQLite-informational) ![Theme](https://img.shields.io/badge/theme-Dark%20%2F%20Gold-yellow) +![Docker](https://img.shields.io/badge/deployment-Single%20Docker%20Container-blue) ![License](https://img.shields.io/badge/license-MIT-green) --- @@ -16,28 +18,21 @@ - [Project Structure](#project-structure) - [Data Architecture](#data-architecture) - [Features](#features) - - [Main Calendar View](#main-calendar-view) - - [Project & Deliverable Management](#project--deliverable-management) - - [Deliverable Focus View](#deliverable-focus-view) - - [Color Coding System](#color-coding-system) - - [Theme & Design System](#theme--design-system) - [API Reference](#api-reference) - [Component Architecture](#component-architecture) -- [Getting Started](#getting-started) - - [Prerequisites](#prerequisites) - - [Backend Setup](#backend-setup) - - [Frontend Setup](#frontend-setup) - - [Running the App](#running-the-app) +- [Docker Deployment](#docker-deployment) +- [Local Development](#local-development) - [Environment Variables](#environment-variables) - [Database Schema](#database-schema) - [Roadmap](#roadmap) + --- ## Overview -**FabDash** is a self-hosted, full-stack project management and scheduling application built for professionals who need a clean, fast, and visually intuitive way to manage multi-deliverable projects across time. It combines a large, interactive calendar view with a powerful per-project timeline focus system — all wrapped in a dark, modern UI with gold accents. +**FabDash** is a self-hosted, full-stack project management and scheduling application built for fabrication teams who need a clean, fast, and visually intuitive way to manage multi-deliverable projects across time. It combines a large interactive calendar with a per-project timeline focus system — all wrapped in a dark, modern UI with gold accents. -Unlike bloated SaaS tools, FABDASH runs locally with zero subscription fees, full data ownership, and a UI designed with intention — not feature creep. +Deployed as a **single Docker container**, FabDash runs anywhere Docker runs with zero external dependencies. --- @@ -46,8 +41,9 @@ Unlike bloated SaaS tools, FABDASH runs locally with zero subscription fees, ful | Principle | Implementation | |---|---| | **Clarity over clutter** | One focused view at a time — calendar or timeline, never both fighting for space | -| **Speed of interaction** | Drag, click, and edit without leaving context | +| **Speed of interaction** | Drag, click, and edit without losing context | | **Data ownership** | Local SQLite persistence, no cloud dependency | +| **Easy deployment** | Single Docker container — one command to run anywhere | | **Visual hierarchy** | Gold accents guide the eye to what matters most | --- @@ -55,14 +51,15 @@ Unlike bloated SaaS tools, FABDASH runs locally with zero subscription fees, ful ## Tech Stack ### Frontend + | Package | Version | Purpose | |---|---|---| | React | ^18.x | UI component framework | -| Vite | ^5.x | Build tool & dev server | +| Vite | ^5.x | Build tool and dev server | | Tailwind CSS | ^3.x | Utility-first styling with custom tokens | | @fullcalendar/react | ^6.x | Main calendar view | | @fullcalendar/daygrid | ^6.x | Month/week/day grid views | -| @fullcalendar/interaction | ^6.x | Drag-and-drop + click events | +| @fullcalendar/interaction | ^6.x | Drag-and-drop and click events | | @fullcalendar/timegrid | ^6.x | Time-slot grid view | | react-chrono | ^2.x | Deliverable Focus View timeline | | Zustand | ^4.x | Global state management | @@ -71,84 +68,88 @@ Unlike bloated SaaS tools, FABDASH runs locally with zero subscription fees, ful | date-fns | ^3.x | Date formatting and manipulation | ### Backend + | Package | Version | Purpose | |---|---|---| -| Flask | ^3.x | REST API server | +| Flask | ^3.x | REST API server + static file serving | | Flask-SQLAlchemy | ^3.x | ORM for SQLite | | Flask-CORS | ^4.x | Cross-origin support for React dev server | -| Flask-Migrate | ^4.x | Database migrations | +| Flask-Migrate | ^4.x | Database schema migrations | +| Gunicorn | ^21.x | Production WSGI server (inside Docker) | ### Database -- **SQLite** — Zero-config, file-based persistence. Located at `/backend/fabdash.db` + +- **SQLite** — Zero-config, file-based persistence at `/app/data/fabdash.db` +- Mounted as a Docker volume so data survives container restarts --- ## Project Structure -\`\`\` +``` fabdash/ -│ -├── backend/ # Flask REST API -│ ├── app/ -│ │ ├── __init__.py # App factory -│ │ ├── models.py # SQLAlchemy models -│ │ ├── routes/ -│ │ │ ├── projects.py # Project CRUD endpoints -│ │ │ └── deliverables.py # Deliverable CRUD endpoints -│ │ └── extensions.py # db, cors, migrate instances -│ ├── migrations/ # Flask-Migrate migration files -│ ├── fabdash.db # SQLite database (auto-generated) -│ ├── config.py # Environment config -│ └── run.py # App entry point -│ -├── frontend/ # React + Vite application -│ ├── public/ -│ ├── src/ -│ │ ├── api/ -│ │ │ ├── projects.js # Axios calls for projects -│ │ │ └── deliverables.js # Axios calls for deliverables -│ │ ├── components/ -│ │ │ ├── Calendar/ -│ │ │ │ ├── MainCalendar.jsx # FullCalendar wrapper -│ │ │ │ ├── EventChip.jsx # Color-coded event pill -│ │ │ │ └── CalendarToolbar.jsx # Custom nav toolbar -│ │ │ ├── Projects/ -│ │ │ │ ├── ProjectList.jsx # Sidebar project list -│ │ │ │ ├── ProjectCard.jsx # Individual project entry -│ │ │ │ └── ProjectModal.jsx # Add/edit project modal -│ │ │ ├── Deliverables/ -│ │ │ │ ├── DeliverableModal.jsx # Add/edit deliverable modal -│ │ │ │ └── DeliverableChip.jsx # Badge inside ProjectCard -│ │ │ ├── FocusView/ -│ │ │ │ ├── FocusDrawer.jsx # Slide-up drawer container -│ │ │ │ ├── FocusTimeline.jsx # react-chrono wrapper -│ │ │ │ └── DeliverableCard.jsx # Individual timeline card -│ │ │ └── UI/ -│ │ │ ├── Button.jsx -│ │ │ ├── Badge.jsx # Status badge (Upcoming/Overdue) -│ │ │ ├── Modal.jsx # Base modal wrapper -│ │ │ └── Drawer.jsx # Base slide-up drawer -│ │ ├── store/ -│ │ │ ├── useProjectStore.js # Zustand: project state -│ │ │ └── useFocusStore.js # Zustand: focus view state -│ │ ├── hooks/ -│ │ │ ├── useProjects.js # Data fetching hook -│ │ │ └── useDeliverables.js # Data fetching hook -│ │ ├── utils/ -│ │ │ ├── dateHelpers.js # date-fns wrappers -│ │ │ └── statusHelpers.js # Overdue/Upcoming logic -│ │ ├── styles/ -│ │ │ └── globals.css # Tailwind base + custom vars -│ │ ├── App.jsx -│ │ └── main.jsx -│ ├── tailwind.config.js -│ ├── vite.config.js -│ └── package.json -│ +├── Dockerfile +├── docker-compose.yml ├── .env.example ├── .gitignore -└── README.md -\`\`\` +├── README.md +│ +├── backend/ +│ ├── run.py +│ ├── config.py +│ ├── requirements.txt +│ └── app/ +│ ├── __init__.py +│ ├── extensions.py +│ ├── models.py +│ └── routes/ +│ ├── projects.py +│ └── deliverables.py +│ +└── frontend/ + ├── package.json + ├── vite.config.js + ├── tailwind.config.js + ├── index.html + └── src/ + ├── main.jsx + ├── App.jsx + ├── api/ + │ ├── projects.js + │ └── deliverables.js + ├── components/ + │ ├── Calendar/ + │ │ ├── MainCalendar.jsx + │ │ ├── EventChip.jsx + │ │ └── CalendarToolbar.jsx + │ ├── Projects/ + │ │ ├── ProjectList.jsx + │ │ ├── ProjectCard.jsx + │ │ └── ProjectModal.jsx + │ ├── Deliverables/ + │ │ ├── DeliverableModal.jsx + │ │ └── DeliverableChip.jsx + │ ├── FocusView/ + │ │ ├── FocusDrawer.jsx + │ │ ├── FocusTimeline.jsx + │ │ └── DeliverableCard.jsx + │ └── UI/ + │ ├── Button.jsx + │ ├── Badge.jsx + │ ├── Modal.jsx + │ └── Drawer.jsx + ├── store/ + │ ├── useProjectStore.js + │ └── useFocusStore.js + ├── hooks/ + │ ├── useProjects.js + │ └── useDeliverables.js + ├── utils/ + │ ├── dateHelpers.js + │ └── statusHelpers.js + └── styles/ + └── globals.css +``` --- @@ -156,16 +157,16 @@ fabdash/ ### Relationships -\`\`\` -Project (1) ──────────── (many) Deliverable - │ │ - ├── id (PK) ├── id (PK) - ├── name ├── project_id (FK) - ├── color (hex) ├── title - ├── description ├── due_date - └── created_at ├── status (enum) - └── created_at -\`\`\` +``` +Project (1) ─────────────── (many) Deliverable + │ │ + ├── id (PK) ├── id (PK) + ├── name ├── project_id (FK → projects.id) + ├── color (hex) ├── title + ├── description ├── due_date + └── created_at ├── status (enum) + └── created_at +``` Each **Project** owns one or more **Deliverables**. Every deliverable inherits the parent project's color when rendered on the calendar. Deleting a project cascades to remove all its deliverables. @@ -175,93 +176,84 @@ Each **Project** owns one or more **Deliverables**. Every deliverable inherits t ### Main Calendar View -The primary interface is a large, full-width **FullCalendar** grid. It supports three view modes switchable from the toolbar: +The primary interface is a large, full-width FullCalendar grid with three switchable view modes: - **Month View** — Full month overview, all deliverables visible as colored event chips - **Week View** — Focused 7-day view with time slots - **Day View** — Single-day granularity for heavy scheduling days -**Interaction behaviors:** -- **Drag-and-drop** any deliverable event to a new date — the backend is updated immediately via `PATCH /deliverables/:id` -- **Click** any event to open the **Deliverable Focus View** for that project -- **Right-click** (context menu) on an event to access quick actions: Edit, Delete, Open Project -- **Click empty date cell** to open the Add Deliverable modal pre-filled with that date +**Interactions:** + +- Drag-and-drop any deliverable to a new date — backend is patched immediately +- Click any event to open the Deliverable Focus View +- Right-click an event for quick actions: Edit, Delete, Open Project +- Click an empty date cell to open the Add Deliverable modal pre-filled with that date --- ### Project & Deliverable Management **Adding a Project:** -1. Click the **"+ New Project"** button in the sidebar -2. Enter project name, optional description, and select a color swatch -3. Immediately add one or more deliverables inline before saving -4. Submit — project and all deliverables are persisted in a single transaction -**Adding a Deliverable to an Existing Project:** -- Open a project via the sidebar and click **"+ Add Deliverable"** -- Or click an empty calendar cell and select an existing project from the dropdown +1. Click **"+ New Project"** in the sidebar +2. Enter project name, optional description, and choose a color swatch +3. Add one or more deliverables inline before saving +4. Submit — project and all deliverables persist in a single transaction -**Editing:** -- Click any deliverable chip in the sidebar or calendar event to open its edit modal -- All fields (title, date, status) are editable inline +**Editing & Deleting:** -**Deleting:** -- Projects can be deleted from the sidebar (with a confirmation dialog warning of cascade delete) -- Individual deliverables can be deleted from their edit modal or via calendar right-click context menu +- Edit any deliverable from the sidebar, calendar event click, or Focus View +- Delete a project via the sidebar (confirmation dialog warns of cascade delete) +- Delete individual deliverables from their edit modal or via right-click context menu --- ### Deliverable Focus View -Clicking any deliverable on the calendar opens a **slide-up drawer** from the bottom of the screen containing the full project timeline for that deliverable's parent project. +Clicking any calendar event opens a **slide-up drawer** with the full project timeline. -**Behavior:** -- All deliverables for the project are rendered as a **horizontal timeline** using `react-chrono` in `HORIZONTAL_ALL` mode -- The **clicked deliverable is highlighted** with a gold glowing border (`ring-2 ring-gold`) and elevated scale -- All other deliverables appear as dimmed context nodes -- Each card displays: deliverable title, due date, and status badge -- The drawer can be dismissed by clicking outside it, pressing `Escape`, or clicking the close button -- An **"Edit Deliverable"** and **"Edit Project"** button are available within the drawer without navigating away +- All deliverables render as a horizontal timeline via `react-chrono` in `HORIZONTAL_ALL` mode +- The clicked deliverable is highlighted with a gold glow and elevated scale +- Other deliverables appear as dimmed context nodes +- Drawer dismisses on outside click, `Escape` key, or close button +- Edit Deliverable and Edit Project buttons are available inline -**Active Node Visual Treatment:** -\`\`\` -[ Deliverable 1 ]──────[ Deliverable 2 ]──────[ ★ Deliverable 3 ★ ] - Jan 15, 2026 Feb 28, 2026 Mar 28, 2026 - Completed In Progress ← ACTIVE / FOCUSED -\`\`\` +``` +[ Deliverable 1 ]────────[ Deliverable 2 ]────────[ ★ Deliverable 3 ★ ] + Jan 15, 2026 Feb 28, 2026 Mar 28, 2026 + Completed In Progress ← ACTIVE / FOCUSED +``` --- ### Color Coding System -Each project is assigned a hex color at creation. This color is used: -- As the **background of event chips** on the FullCalendar grid -- As the **left border accent** on sidebar project cards -- As the **timeline node color** in the Focus View for non-active deliverables +Each project is assigned a hex color used across: -Colors are fully user-selectable from a curated palette of 12 swatches (chosen to remain readable against the dark background) plus a custom hex input. +- Background of event chips on the calendar grid +- Left border accent on sidebar project cards +- Timeline node color in the Focus View for non-active deliverables + +Colors are selectable from a curated 12-swatch palette (all readable on dark backgrounds) plus a custom hex input. --- ### Theme & Design System -The entire application uses a **dark, modern aesthetic** with gold as the primary accent color. - -**Tailwind Custom Tokens:** -\`\`\`js +```js // tailwind.config.js theme: { extend: { colors: { - gold: '#C9A84C', - 'gold-light': '#E8C96A', - 'gold-muted': '#8A6E2F', - surface: '#111111', - 'surface-raised': '#1A1A1A', - 'surface-elevated':'#242424', - 'surface-border': '#2E2E2E', - 'text-primary': '#F5F5F5', - 'text-muted': '#888888', + gold: '#C9A84C', + 'gold-light': '#E8C96A', + 'gold-muted': '#8A6E2F', + surface: '#111111', + 'surface-raised': '#1A1A1A', + 'surface-elevated': '#242424', + 'surface-border': '#2E2E2E', + 'text-primary': '#F5F5F5', + 'text-muted': '#888888', }, boxShadow: { gold: '0 0 12px rgba(201, 168, 76, 0.4)', @@ -269,10 +261,10 @@ theme: { fontFamily: { sans: ['Inter', 'sans-serif'], mono: ['JetBrains Mono', 'monospace'], - } - } + }, + }, } -\`\`\` +``` --- @@ -297,200 +289,297 @@ theme: { | `PATCH` | `/api/deliverables/:id` | Update title, date, or status | | `DELETE` | `/api/deliverables/:id` | Delete a single deliverable | -**Example Payload — Create Project with Deliverables:** -\`\`\`json +**Example — Create Project with Deliverables:** + +```json POST /api/projects { "name": "CODA", "color": "#4A90D9", "description": "Example fabrication project", "deliverables": [ - { "title": "Deliverable 1 – Concept Brief", "due_date": "2026-01-15" }, - { "title": "Deliverable 2 – Draft Review", "due_date": "2026-02-28" }, + { "title": "Deliverable 1 – Concept Brief", "due_date": "2026-01-15" }, + { "title": "Deliverable 2 – Draft Review", "due_date": "2026-02-28" }, { "title": "Deliverable 3 – Final Submission", "due_date": "2026-03-28" } ] } -\`\`\` +``` --- ## Component Architecture -\`\`\` +``` App ├── Sidebar │ ├── ProjectList │ │ └── ProjectCard (× N) │ │ └── DeliverableChip (× N) │ └── Button ["+ New Project"] -│ ├── MainCalendar -│ ├── CalendarToolbar (Month / Week / Day + nav arrows) +│ ├── CalendarToolbar │ └── FullCalendar -│ └── EventChip (rendered per deliverable) -│ -├── ProjectModal (Add / Edit project) -├── DeliverableModal (Add / Edit deliverable) -│ -└── FocusDrawer (slide-up, conditionally rendered) +│ └── EventChip (× N) +├── ProjectModal +├── DeliverableModal +└── FocusDrawer └── FocusTimeline └── DeliverableCard (× N, one highlighted) -\`\`\` +``` --- -## Getting Started +## Docker Deployment -### Prerequisites -- Node.js >= 18.x -- Python >= 3.11 -- pip -- Git +FabDash ships as a **single Docker container**. The build process compiles the React frontend with Vite, copies the static output into Flask's `static/` folder, and serves everything through Gunicorn. No separate web server or container needed. + +### How It Works + +``` +Docker Build +├── Stage 1 (node:18-alpine) +│ └── npm run build → frontend/dist/ +└── Stage 2 (python:3.12-slim) + ├── Copy dist/ → backend/app/static/ + ├── pip install -r requirements.txt + ├── Flask serves API at /api/* + ├── Flask serves React at /* (catch-all → index.html) + └── Gunicorn runs on port 8080 +``` + +### Dockerfile + +```dockerfile +# ── Stage 1: Build React frontend ────────────────────────────────────── +FROM node:18-alpine AS frontend-build + +WORKDIR /app/frontend +COPY frontend/package*.json ./ +RUN npm ci +COPY frontend/ ./ +RUN npm run build + +# ── Stage 2: Flask + Gunicorn production image ───────────────────────── +FROM python:3.12-slim + +WORKDIR /app + +# Install Python dependencies +COPY backend/requirements.txt ./ +RUN pip install --no-cache-dir -r requirements.txt + +# Copy Flask app +COPY backend/ ./ + +# Copy compiled React build into Flask static folder +COPY --from=frontend-build /app/frontend/dist ./app/static + +# Persistent volume mount point for SQLite database +RUN mkdir -p /app/data + +EXPOSE 8080 + +CMD ["gunicorn", "--bind", "0.0.0.0:8080", "--workers", "2", "run:app"] +``` + +### docker-compose.yml + +```yaml +version: "3.9" + +services: + fabdash: + build: . + container_name: fabdash + ports: + - "8080:8080" + volumes: + - fabdash-data:/app/data # Persists SQLite database across restarts + environment: + - FLASK_ENV=production + - DATABASE_URL=sqlite:////app/data/fabdash.db + - SECRET_KEY=${SECRET_KEY} + restart: unless-stopped + +volumes: + fabdash-data: +``` + +### Flask Catch-All Route (SPA Support) + +Add this to `backend/app/__init__.py` so React Router handles all non-API routes: + +```python +import os +from flask import send_from_directory + +@app.route("/", defaults={"path": ""}) +@app.route("/") +def serve_react(path): + static_folder = os.path.join(app.root_path, "static") + if path and os.path.exists(os.path.join(static_folder, path)): + return send_from_directory(static_folder, path) + return send_from_directory(static_folder, "index.html") +``` + +### Deploy (One Command) + +```bash +# Clone and run +git clone https://github.com/yourname/fabdash.git +cd fabdash +cp .env.example .env # Add your SECRET_KEY +docker compose up -d --build + +# FabDash is live at http://localhost:8080 +``` + +### Useful Docker Commands + +```bash +docker compose logs -f fabdash # Stream logs +docker compose down # Stop container +docker compose up -d --build # Rebuild and restart +docker exec -it fabdash flask db upgrade # Run migrations +``` --- -### Backend Setup +## Local Development -\`\`\`bash +For active development, run frontend and backend separately so Vite HMR works: + +**Terminal 1 — Flask backend:** + +```bash cd backend python -m venv venv source venv/bin/activate # Windows: venv\Scripts\activate pip install -r requirements.txt -flask db init -flask db migrate -m "Initial schema" flask db upgrade -\`\`\` - ---- - -### Frontend Setup - -\`\`\`bash -cd frontend -npm install -\`\`\` - ---- - -### Running the App - -**Terminal 1 — Flask backend:** -\`\`\`bash -cd backend -source venv/bin/activate flask run --port 5000 -\`\`\` +``` **Terminal 2 — React frontend:** -\`\`\`bash -cd frontend -npm run dev -\`\`\` -App will be available at: **http://localhost:5173** +```bash +cd frontend +npm install +npm run dev # Vite dev server at http://localhost:5173 +``` + +Set `VITE_API_BASE_URL=http://localhost:5000/api` in `frontend/.env` during development. +In production (Docker), the frontend calls `/api/*` relative to the same origin — no CORS needed. --- ## Environment Variables -\`\`\`env -# backend/.env -FLASK_APP=run.py -FLASK_ENV=development -DATABASE_URL=sqlite:///fabdash.db -SECRET_KEY=your-secret-key-here +```env +# .env (used by docker-compose.yml) +SECRET_KEY=replace-with-a-strong-random-key +FLASK_ENV=production +DATABASE_URL=sqlite:////app/data/fabdash.db -# frontend/.env +# frontend/.env (development only) VITE_API_BASE_URL=http://localhost:5000/api -\`\`\` +``` --- ## Database Schema -\`\`\`sql +```sql CREATE TABLE projects ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - name TEXT NOT NULL, - color TEXT NOT NULL DEFAULT '#C9A84C', + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT NOT NULL, + color TEXT NOT NULL DEFAULT '#C9A84C', description TEXT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE deliverables ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - project_id INTEGER NOT NULL REFERENCES projects(id) ON DELETE CASCADE, - title TEXT NOT NULL, - due_date DATE NOT NULL, - status TEXT NOT NULL DEFAULT 'upcoming' - CHECK(status IN ('upcoming', 'in_progress', 'completed', 'overdue')), + id INTEGER PRIMARY KEY AUTOINCREMENT, + project_id INTEGER NOT NULL REFERENCES projects(id) ON DELETE CASCADE, + title TEXT NOT NULL, + due_date DATE NOT NULL, + status TEXT NOT NULL DEFAULT 'upcoming' + CHECK(status IN ('upcoming','in_progress','completed','overdue')), created_at DATETIME DEFAULT CURRENT_TIMESTAMP ); -CREATE INDEX idx_deliverables_project ON deliverables(project_id); +CREATE INDEX idx_deliverables_project ON deliverables(project_id); CREATE INDEX idx_deliverables_due_date ON deliverables(due_date); -\`\`\` +``` --- ## Roadmap ### v1.0 — Core Release *(current scope)* + - [x] Dark/gold design system with Tailwind custom tokens - [x] FullCalendar main view with Month / Week / Day modes - [x] Drag-and-drop deliverable rescheduling - [x] Project creation with multiple deliverables and color selection -- [x] Add / Edit / Delete for both projects and deliverables -- [x] Deliverable Focus View (slide-up drawer with react-chrono horizontal timeline) +- [x] Add / Edit / Delete for projects and deliverables +- [x] Deliverable Focus View — slide-up drawer with horizontal timeline - [x] Active deliverable highlighting in Focus View - [x] Status badges (Upcoming / In Progress / Completed / Overdue) - [x] Flask REST API with SQLite persistence - [x] Cascade delete (project → deliverables) - [x] Right-click context menu on calendar events +- [x] Single Docker container deployment with persistent volume --- ### v1.1 — Polish & UX -- [ ] Keyboard shortcuts (N = new project, Esc = close modal/drawer, ←→ = calendar navigation) -- [ ] Undo/redo for drag-and-drop moves (30-second undo toast) -- [ ] Animated transitions on drawer open/close and modal enter/exit -- [ ] Deliverable sorting within Focus View (by date, by status) -- [ ] Empty state illustrations for no projects / no deliverables -- [ ] Responsive layout for smaller screens (collapsible sidebar) + +- [ ] Keyboard shortcuts (`N` = new project, `Esc` = close modal, arrow keys = calendar nav) +- [ ] Undo/redo for drag-and-drop with 30-second undo toast +- [ ] Animated transitions on drawer and modal open/close +- [ ] Deliverable sorting in Focus View (by date, by status) +- [ ] Empty state illustrations for no projects or no deliverables +- [ ] Responsive layout with collapsible sidebar for smaller screens ### v1.2 — Enhanced Calendar -- [ ] Mini-map / agenda sidebar showing upcoming deliverables across all projects + +- [ ] Agenda sidebar showing all upcoming deliverables across projects - [ ] Week numbers in calendar header -- [ ] "Today" jump button with smooth scroll animation -- [ ] Hoverable event tooltip previewing deliverable details without opening Focus View -- [ ] Date range selection to bulk-create deliverables +- [ ] Hover tooltip previewing deliverable details without opening Focus View +- [ ] Date range selection for bulk deliverable creation +- [ ] "Today" jump button with smooth scroll ### v2.0 — Collaboration & Auth + - [ ] User authentication (Flask-Login + JWT) - [ ] Multi-user support with project ownership and sharing -- [ ] Role-based access (Owner / Editor / Viewer per project) +- [ ] Role-based access per project (Owner / Editor / Viewer) - [ ] Activity log per project (who changed what, when) - [ ] Comment threads on individual deliverables ### v2.1 — Notifications & Integrations + - [ ] In-app notification center for approaching due dates -- [ ] Email reminders (Flask-Mail) at configurable intervals before due date +- [ ] Email reminders at configurable intervals before due date - [ ] iCal / Google Calendar export per project - [ ] Slack webhook integration for deliverable status changes - [ ] CSV import/export for bulk project setup ### v2.2 — Advanced Views -- [ ] Gantt view (using dhtmlx-gantt or Bryntum) as an alternate layout -- [ ] Kanban board view (columns by status: Upcoming / In Progress / Completed) -- [ ] Cross-project timeline view showing all projects on one horizontal axis -- [ ] Workload heatmap showing deliverable density per day across all projects + +- [ ] Gantt view as an alternate layout +- [ ] Kanban board (columns: Upcoming / In Progress / Completed) +- [ ] Cross-project timeline showing all projects on one horizontal axis +- [ ] Workload heatmap showing deliverable density per day - [ ] Archived projects with searchable history ### v3.0 — Intelligence Layer -- [ ] AI-assisted scheduling: suggest optimal due dates based on project cadence -- [ ] Auto-detect overdue deliverables and surface them on dashboard load -- [ ] Smart conflict detection: flag days with too many concurrent deliverables -- [ ] Natural language input for creating deliverables ("Add final draft due next Friday to CODA") + +- [ ] AI-assisted scheduling suggestions based on project cadence +- [ ] Auto-detect and surface overdue deliverables on dashboard load +- [ ] Conflict detection — flag days with too many concurrent deliverables +- [ ] Natural language input ("Add final draft due next Friday to CODA") ---