# FabDash **Fabrication Dashboard** — A sleek, modern project management & scheduling application. ![Version](https://img.shields.io/badge/version-1.0.0-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) --- ## Table of Contents - [Overview](#overview) - [Tech Stack](#tech-stack) - [Project Structure](#project-structure) - [Features](#features) - [API Reference](#api-reference) - [Docker Deployment](#docker-deployment) - [Unraid Installation](#unraid-installation) - [Local Development](#local-development) - [Environment Variables](#environment-variables) - [Database Schema](#database-schema) - [Roadmap](#roadmap) --- ## Overview FabDash is a self-hosted project management dashboard built for fabrication teams. It features a large interactive calendar, multi-deliverable project tracking, drag-and-drop scheduling, and a per-project timeline Focus View. All wrapped in a dark/gold UI and deployed as a single Docker container. --- ## Tech Stack | Layer | Technology | |---|---| | Frontend | React 18, Vite, Tailwind CSS | | Calendar | FullCalendar v6 (daygrid, timegrid, interaction) | | Focus View | Custom horizontal timeline with react-chrono | | State | Zustand | | HTTP | Axios | | Backend | Flask 3, Flask-SQLAlchemy, Flask-Migrate, Flask-CORS | | Database | SQLite (persisted via Docker volume) | | Server | Gunicorn (production) | --- ## Project Structure ``` fabdash/ ├── Dockerfile ├── docker-compose.yml ├── .env.example ├── .gitignore ├── README.md │ ├── backend/ │ ├── run.py │ ├── config.py │ ├── requirements.txt │ └── app/ │ ├── __init__.py │ ├── extensions.py │ ├── models.py │ └── routes/ │ ├── __init__.py │ ├── projects.py │ └── deliverables.py │ └── frontend/ ├── package.json ├── vite.config.js ├── tailwind.config.js ├── postcss.config.js ├── index.html └── src/ ├── main.jsx ├── App.jsx ├── api/ │ ├── projects.js │ └── deliverables.js ├── components/ │ ├── Calendar/ │ │ └── MainCalendar.jsx │ ├── Projects/ │ │ ├── ProjectList.jsx │ │ ├── ProjectCard.jsx │ │ └── ProjectModal.jsx │ ├── Deliverables/ │ │ └── DeliverableModal.jsx │ ├── FocusView/ │ │ ├── FocusDrawer.jsx │ │ ├── FocusTimeline.jsx │ │ └── DeliverableCard.jsx │ └── UI/ │ ├── Button.jsx │ ├── Badge.jsx │ ├── Modal.jsx │ └── Drawer.jsx ├── store/ │ ├── useProjectStore.js │ └── useFocusStore.js ├── utils/ │ ├── dateHelpers.js │ └── statusHelpers.js └── styles/ └── globals.css ``` --- ## Features - **Large calendar view** — Month, Week, and Day modes via FullCalendar - **Drag-and-drop** — Move deliverables to new dates; backend updates instantly - **Multi-deliverable projects** — Add unlimited deliverables per project, each with its own due date and status - **Color-coded projects** — 12-swatch palette + custom hex; colors appear on calendar events and sidebar cards - **Deliverable Focus View** — Click any calendar event to open a slide-up drawer showing the full project timeline, with the selected deliverable highlighted in gold - **Status tracking** — Upcoming / In Progress / Completed / Overdue badges per deliverable - **Dark/gold theme** — Dark surfaces with gold as the primary accent throughout - **Full persistence** — SQLite database via Flask-SQLAlchemy, mounted as a Docker volume --- ## API Reference ### Projects | Method | Endpoint | Description | |---|---|---| | `GET` | `/api/projects` | List all projects with nested deliverables | | `POST` | `/api/projects` | Create project (with optional deliverables inline) | | `GET` | `/api/projects/:id` | Get single project | | `PATCH` | `/api/projects/:id` | Update name, color, or description | | `DELETE` | `/api/projects/:id` | Delete project + cascade deliverables | ### Deliverables | Method | Endpoint | Description | |---|---|---| | `GET` | `/api/deliverables?project_id=:id` | List deliverables for a project | | `POST` | `/api/deliverables` | Create deliverable | | `PATCH` | `/api/deliverables/:id` | Update title, due_date, or status | | `DELETE` | `/api/deliverables/:id` | Delete deliverable | --- ## Docker Deployment FabDash uses a **multi-stage Docker build**: 1. Stage 1 compiles the React/Vite frontend into static files 2. Stage 2 copies those files into Flask's `static/` folder 3. Gunicorn serves the Flask API at `/api/*` and the React SPA at `/*` No Nginx, no separate containers, no reverse proxy required. ```bash git clone https://github.com/yourname/fabdash.git cd fabdash cp .env.example .env # Edit .env and set a strong SECRET_KEY docker compose up -d --build # App available at http://your-host:8080 ``` --- ## Unraid Installation FabDash is designed to run cleanly on Unraid via a Docker Compose build from source. Two methods are provided below — **Terminal (recommended)** and **Unraid Docker GUI**. --- ### Method 1 — Terminal via SSH (Recommended) This method builds the image directly on your Unraid server and uses `docker compose` to manage the container. #### Step 1 — Enable SSH on Unraid Go to **Settings → Management Access → SSH** and ensure SSH is enabled. #### Step 2 — SSH into your Unraid server ```bash ssh root@YOUR_UNRAID_IP ``` #### Step 3 — Clone the repository ```bash cd /mnt/user/appdata git clone https://github.com/yourname/fabdash.git cd fabdash ``` #### Step 4 — Create your environment file ```bash cp .env.example .env nano .env ``` Set a strong `SECRET_KEY`: ```env SECRET_KEY=your-strong-random-secret-key-here FLASK_ENV=production DATABASE_URL=sqlite:////app/data/fabdash.db ``` Press `Ctrl+X`, then `Y` to save. #### Step 5 — Build and start the container ```bash docker compose up -d --build ``` The build will take 2–4 minutes the first time (downloading Node and Python layers, compiling the React app). #### Step 6 — Access FabDash Open your browser and navigate to: ``` http://YOUR_UNRAID_IP:8080 ``` #### Useful Commands ```bash # View live logs docker compose logs -f fabdash # Stop the container docker compose down # Rebuild after a git pull (update) git pull docker compose up -d --build # Open a shell inside the container docker exec -it fabdash bash # Run database migrations (after schema changes) docker exec -it fabdash flask db upgrade ``` --- ### Method 2 — Unraid Docker GUI (Manual Container) Use this method if you have already built and pushed the FabDash image to a registry (Docker Hub or GHCR). If you are running from source, use Method 1. #### Step 1 — Push image to a registry (on your dev machine) ```bash docker build -t yourdockerhubuser/fabdash:latest . docker push yourdockerhubuser/fabdash:latest ``` #### Step 2 — Add container via Unraid Docker tab 1. In Unraid, go to the **Docker** tab 2. Click **Add Container** 3. Switch to **Advanced View** (toggle top-right) Fill in the fields: | Field | Value | |---|---| | **Name** | `fabdash` | | **Repository** | `yourdockerhubuser/fabdash:latest` | | **Network Type** | Bridge | | **Port** | Host: `8080` → Container: `8080` (TCP) | | **Path** | Host: `/mnt/user/appdata/fabdash/data` → Container: `/app/data` | #### Step 3 — Add Environment Variables Click **Add another Path, Port, Variable...** and add: | Key | Value | |---|---| | `SECRET_KEY` | `your-strong-random-key` | | `FLASK_ENV` | `production` | | `DATABASE_URL` | `sqlite:////app/data/fabdash.db` | #### Step 4 — Apply Click **Apply**. Unraid will pull the image and start the container. Access at: ``` http://YOUR_UNRAID_IP:8080 ``` #### Updating the Container (GUI method) 1. SSH into Unraid 2. Run: `docker pull yourdockerhubuser/fabdash:latest` 3. In the Docker tab, click the FabDash container icon → **Update** --- ### Data Persistence on Unraid Your SQLite database is stored at: ``` /mnt/user/appdata/fabdash/data/fabdash.db ``` This path survives container restarts, image rebuilds, and Unraid reboots. Back it up with Unraid's **Appdata Backup** plugin or manually: ```bash cp /mnt/user/appdata/fabdash/data/fabdash.db /mnt/user/backups/fabdash-$(date +%Y%m%d).db ``` --- ## Local Development Run backend and frontend separately to get Vite hot-module reloading: **Terminal 1 — Flask:** ```bash cd backend python -m venv venv source venv/bin/activate # Windows: venv\Scripts\activate pip install -r requirements.txt export FLASK_ENV=development flask run --port 5000 ``` **Terminal 2 — React:** ```bash cd frontend npm install npm run dev # http://localhost:5173 ``` Vite proxies `/api/*` calls to Flask on port 5000 automatically via `vite.config.js`. --- ## Environment Variables | Variable | Default | Description | |---|---|---| | `SECRET_KEY` | *(required)* | Flask session secret — use a long random string | | `FLASK_ENV` | `production` | Set to `development` for debug mode | | `DATABASE_URL` | `sqlite:////app/data/fabdash.db` | Full SQLite path (4 slashes = absolute path) | --- ## Database Schema ```sql CREATE TABLE projects ( 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')), created_at DATETIME DEFAULT CURRENT_TIMESTAMP ); 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)* - [x] Dark/gold Tailwind design system - [x] FullCalendar with Month / Week / Day views - [x] Drag-and-drop deliverable rescheduling - [x] Multi-deliverable project creation with inline rows - [x] Add / Edit / Delete for projects and deliverables - [x] Deliverable Focus View (slide-up drawer + horizontal timeline) - [x] Active deliverable gold highlight in Focus View - [x] Status badges (Upcoming / In Progress / Completed / Overdue) - [x] Flask REST API + SQLite persistence - [x] Cascade delete (project → deliverables) - [x] Single Docker container deployment - [x] Unraid installation guide (Terminal + GUI) ### v1.1 — Polish & UX - [ ] Keyboard shortcuts (`N` = new project, `Esc` = close, arrow keys = calendar nav) - [ ] 30-second undo toast for drag-and-drop moves - [ ] Animated modal/drawer enter and exit transitions - [ ] Hover tooltip on calendar events (preview without opening Focus View) - [ ] Responsive layout with collapsible sidebar - [ ] Empty state illustrations ### v1.2 — Calendar Enhancements - [ ] Agenda sidebar showing all upcoming deliverables across projects - [ ] Click empty date → pre-filled Add Deliverable modal with project selector - [ ] Date range selection for bulk deliverable creation - [ ] "Today" jump button - [ ] Week numbers in calendar header ### v2.0 — Auth & Multi-user - [ ] User login (Flask-Login + JWT) - [ ] Multi-user support with project ownership - [ ] Role-based access per project (Owner / Editor / Viewer) - [ ] Activity log per project - [ ] Comment threads on deliverables ### v2.1 — Notifications & Integrations - [ ] In-app notification center for approaching due dates - [ ] Email reminders at configurable intervals (Flask-Mail) - [ ] iCal / Google Calendar export per project - [ ] Slack webhook for deliverable status changes - [ ] CSV import/export for bulk setup ### v2.2 — Advanced Views - [ ] Gantt view alternate layout - [ ] Kanban board (columns by status) - [ ] Cross-project timeline view - [ ] Workload heatmap showing deliverable density per day - [ ] Archived projects with searchable history ### v3.0 — Intelligence Layer - [ ] AI scheduling suggestions based on project cadence - [ ] Conflict detection — flag overloaded days - [ ] Natural language input ("Add final draft due next Friday to CODA") --- *Built with intention. No subscriptions. No bloat. Just your fabrication workflow.*