~/ Personal Dashboard (personal-dashboard)
A single-user, self-hosted dashboard that brings together Habit Tracking Analytics, Fitness & Health Analytics, Homeserver Monitoring, and a Tech-Minimalist AI Chat into one unified interface.
Built with Next.js 16 (App Router + Turbopack), React 19, Tailwind CSS v4, shadcn/ui (Base UI base-nova), Drizzle ORM, PostgreSQL, and Recharts, the dashboard embraces a dense, terminal-inspired design focused on clarity, speed, and resilience.
✨ Features
- 📊 Habit tracking analytics with streaks, trends, and achievements
- 🏃 Fitness analytics powered by Intervals.icu
- 🖥️ Homeserver monitoring with telemetry and uptime metrics
- 🤖 Terminal-inspired multi-model AI chat
- 🔒 Cloudflare Zero Trust + origin verification
- 📱 PWA support with mobile home screen icons
- ⚡ Graceful degradation when external services are unavailable
🧭 Architecture
The dashboard is built around five core design principles.
| Principle | Description |
|---|---|
| Tech-Minimalist UI | Flat dark theme, strong typography, minimal chrome, and clear visual hierarchy. |
| Resilient Degradation | Pages use Promise.allSettled() so individual service failures never take down the entire dashboard. |
| Lazy Database Initialization | Drizzle establishes connections only on the first query, preventing startup failures when PostgreSQL or environment variables are unavailable. |
| Power-Window Awareness | The homeserver is recognized as ASLEEP or TRANSITION outside configured schedules instead of being reported as offline. |
| Local Data Mirroring | Intervals.icu activities are mirrored into PostgreSQL, enabling advanced analytics without API rate-limit concerns. |
🛠️ Tech Stack
| Category | Technologies |
|---|---|
| Framework | Next.js 16, React 19, TypeScript |
| Styling | Tailwind CSS v4, shadcn/ui (Base UI) |
| Database | PostgreSQL, Drizzle ORM |
| Charts | Recharts |
| Utilities | date-fns, Zod |
📂 Project Structure
.
├── app/ # Route-level pages and API routes
├── components/ # Shared UI components and feature widgets
├── lib/ # Business logic, analytics, clients, config, DB, telemetry
├── scripts/ # CLI sync jobs
└── proxy.ts # Canonical routing and origin verification
Directory Overview
| Directory | Purpose |
|---|---|
app/ |
Route-level pages for Overview, Habits, Fitness, Server, and Chat |
components/ |
Shared UI primitives and feature-specific widgets |
lib/ |
Analytics, API clients, configuration, database schema, scheduling, telemetry, and chat utilities |
scripts/ |
Background sync jobs for habits, activities, and server data |
proxy.ts |
Canonical domain redirects and Cloudflare origin verification |
Database Schema
The application uses five primary tables:
- habits
- habit_entries
- settings
- activities
- activity_streams
💡 Dashboard Modules
🏠 Overview
A high-level snapshot of your daily activity and infrastructure. - Training readiness hero - Daily briefing - Habit, activity, and step summaries - Systems status board - Quick-launch links
✅ Habits
Analytics for long-term habit consistency. - Active streaks - Completion rates - Perfect weeks - Comeback rate - Automatic exercise sync from Intervals.icu
🏃 Fitness
Comprehensive endurance and training analytics. - CTL / ATL / TSB - ACWR - Foster Load - Personal Bests - Podium rankings - Activity heatmaps - GPS stream and run analysis
🖥️ Server
Self-hosted infrastructure monitoring. - Power schedule awareness - Uptime Kuma integration - Host telemetry - Backup monitoring - Cloudflare Access support
🤖 AI Chat
A terminal-inspired assistant interface. - Multi-model support - Prompt shortcuts - Live context inspection - Tech-minimalist interface
⚙️ Configuration
Environment Variables (.env)
[!IMPORTANT] All secrets are server-side only. Never expose them using the
NEXT_PUBLIC_prefix.
DATABASE_URL=postgresql://user:password@localhost:5432/dashboard
INTERVALS_API_KEY=your_intervals_api_key
INTERVALS_ATHLETE_ID=0
UPTIME_KUMA_URL=https://uptime.example.com
UPTIME_KUMA_API_KEY=your_kuma_prometheus_api_key
TELEMETRY_URL=https://telemetry.example.com/status
HABIT_TRACKER_URL=https://habits.example.com
CF_ACCESS_CLIENT_ID=your_client_id
CF_ACCESS_CLIENT_SECRET=your_client_secret
X_VERCEL_ORIGIN_SECRET=your_origin_secret
SERVER_TIMEZONE=Asia/Kolkata
SERVER_GRACE_MINUTES=5
Dashboard Configuration
Non-sensitive application settings are stored in:
lib/config.ts
This includes: - Power schedule windows - Quick links - Fitness thresholds - Miscellaneous application constants
🔄 Background Sync Jobs
Three lightweight cron jobs keep the dashboard synchronized.
| Job | Purpose |
|---|---|
sync-server |
Collects telemetry and Uptime Kuma metrics |
sync-activities |
Mirrors recent Intervals.icu workouts |
sync-habits |
Automatically checks today's exercise habit |
Example Cron Configuration:
*/15 * * * * curl -sS "https://home.parthjain.tech/api/cron/sync-server" > /dev/null
*/15 * * * * curl -sS "https://home.parthjain.tech/api/cron/sync-activities?days=3" > /dev/null
*/15 * * * * curl -sS "https://home.parthjain.tech/api/cron/sync-habits" > /dev/null
🔒 Security
The application uses multiple layers of protection. - Allows direct access from localhost, LAN, and Tailscale. - Redirects unknown hosts to the canonical domain. - Validates the Cloudflare origin-secret header. - Prevents direct access to the underlying Vercel deployment.
For a complete explanation, see the dedicated Architecture & Security documentation.