Vitruvian
April 12, 2026 · View on GitHub
Personal fitness tracker and workout logger. Built with Next.js 16, Supabase, and Tailwind CSS 4.
Stack
- Framework: Next.js 16 (App Router, React 19)
- Database: Supabase (Postgres + Auth + RLS)
- Styling: Tailwind CSS 4 with custom design tokens
- Charts: Recharts
- Deployment: Vercel (planned)
Structure
fitness/
├── app/ # Next.js application
│ ├── src/
│ │ ├── app/
│ │ │ ├── (app)/ # Authenticated routes (dashboard, workout, etc.)
│ │ │ ├── (auth)/ # Login, signup, auth callback
│ │ │ ├── globals.css # Design tokens + type scale
│ │ │ └── layout.tsx # Root layout
│ │ ├── components/ # UI components by domain
│ │ ├── lib/queries.ts # Supabase query layer
│ │ ├── utils/supabase/ # Supabase client helpers (server, client, middleware)
│ │ └── middleware.ts # Auth guard
│ ├── package.json
│ └── .env.local # Supabase credentials (not committed)
└── README.md
Getting Started
cd app
cp .env.local.example .env.local # Add your Supabase credentials
pnpm install
pnpm dev
Environment Variables
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=sb_publishable_...
Local Database (optional)
To run Postgres locally instead of using hosted Supabase:
docker compose up -d # starts Postgres on port 54322 + Studio on 54323
The schema in app/supabase/schema.sql is automatically applied on first start.
Connect directly to Postgres on port 54322 (user: postgres, password: postgres).
Studio is available at http://localhost:54323 for browsing tables.
Dev Container
Open this repo in VS Code or GitHub Codespaces to get a pre-configured environment with Node.js 22, pnpm, gh CLI, and recommended extensions (ESLint, Prettier, Tailwind CSS IntelliSense, Playwright, Vitest).
Design
Dark theme with a classical/terminal hybrid aesthetic. Three-font system:
- Playfair Display (serif) — headings
- JetBrains Mono (mono) — data, labels, navigation
- Inter (sans) — body text
Gold (#c9a84c) accent reserved for interactive elements and the primary goal metric (S/W ratio). Green for completion states. All data values in warm white.
Auth
Email/password authentication via Supabase Auth. All tables have user_id columns with RLS policies — users can only access their own data. A BEFORE INSERT trigger auto-sets user_id from auth.uid().
Database
14 tables covering training, body composition, supplements, AI chat, and notifications.
Full schema definition: app/supabase/schema.sql.
All tables use RLS with auth.uid() = user_id policies and BEFORE INSERT triggers.