An open-source client portal built with Next.js, Supabase, Umami Analytics, and Uptime Kuma. Gives clients a self-service dashboard to view website analytics, monitor uptime, submit support tickets, and access invoices — all in one place.
- Real-time pageview and visitor statistics pulled from Umami
- Interactive charts (bar chart with Recharts) showing page views and sessions
- Bounce rate, total visitors, and pageview counters
- Auto-refreshes every 5 minutes via client-side API polling
- Deep link to full Umami analytics dashboard
- Live status badges from Uptime Kuma (embedded via image tags)
- Monitor list showing individual service status
- Per-client configuration — each client can have their own Kuma status page slug
- Clients create tickets with subject, description, and optional screenshots (2MB max)
- Full conversation view with message threading
- Admin replies shown in distinct styling
- Ticket statuses: Open → In Progress → Resolved → Closed
- Auto-cleanup of closed tickets after 30 days
- Email notifications for new tickets and status updates
- Invoice list with date, description, amount, and payment status
- Paid / Open status badges
- Direct links to Zoho invoices for payment
- Admin panel for uploading and managing invoices
- View any client's dashboard by their client ID
- Manage all tickets (reply, update status, bulk delete)
- Upload and manage invoices for any client
- Session secret rotation
- Supabase Auth with magic link login
- Password reset flow with session validation
- 30-minute auto-logout for inactivity
- Row-Level Security (RLS) enforced via Supabase
- Server-side session verification via middleware
| Layer | Technology |
|---|---|
| Framework | Next.js 16 (App Router) |
| Language | TypeScript |
| Authentication | Supabase Auth |
| Database | Supabase (PostgreSQL) |
| Analytics | Umami |
| Uptime | Uptime Kuma |
| Charts | Recharts |
| Styling | Tailwind CSS 4 |
| Nodemailer (SMTP) | |
| Deployment | Node.js server (VPS or any host) |
- Node.js 20+ and npm
- A Supabase project (free tier works)
- Umami Analytics instance (self-hosted or cloud)
- Uptime Kuma instance (optional — for uptime monitoring)
- SMTP server for email notifications
# Clone the repository
git clone https://github.com/ttldsgn/Simple-Dashboard.git
cd Simple-Dashboard/client-dashboard
# Install dependencies
npm install
# Copy the example env file and fill in your values
cp .env.example .env.local
# Start the development server
npm run devOpen http://localhost:3000 in your browser.
Copy client-dashboard/.env.example to .env.local and configure:
| Variable | Description |
|---|---|
NEXT_PUBLIC_SUPABASE_URL |
Your Supabase project URL |
NEXT_PUBLIC_SUPABASE_ANON_KEY |
Supabase anonymous/publishable key |
NEXT_PUBLIC_SITE_URL |
Public URL of your dashboard (e.g., https://dashboard.yourdomain.com) |
SUPABASE_SERVICE_ROLE_KEY |
Supabase service role key (server-only, never exposed to client) |
UMAMI_API_URL |
Base URL of your Umami instance |
UMAMI_AUTH_TOKEN |
Umami API auth token for stats queries |
KUMA_API_URL |
Base URL of your Uptime Kuma instance |
PURELYMAIL_SMTP_USER |
SMTP username for email notifications |
PURELYMAIL_SMTP_PASS |
SMTP password |
ADMIN_EMAIL |
Admin email for notifications |
EMAIL_FROM |
From address for outgoing emails |
💡 Any SMTP provider works — despite the
PURELYMAIL_prefix in the variable names, these accept credentials from any SMTP service (SendGrid, Mailgun, Gmail SMTP, Zoho, AWS SES, etc.). The nodemailer transport is configured inclient-dashboard/utils/email.ts.
This project runs on any Node.js host. The client-dashboard/ subdirectory contains the Next.js app, while the root package.json acts as a deployment proxy that forwards build and start commands into the subdirectory.
| Setting | Value |
|---|---|
| Node version | 20.x or 22.x |
| Build command | npm run build |
| Start command | npm run start |
| Port | 3003 (configurable via PORT env var) |
Place your .env file in client-dashboard/.env on the server with all required environment variables.
- Create a Supabase project
- Enable Email Auth with magic links
- Add your production URL to Authentication → URL Configuration → Redirect URLs
- Create a
profilestable with columns:id,company_name,role,umami_website_id,kuma_status_slug,kuma_badges - Create
ticketsandticket_messagestables - Create
invoicestable - Set up Row-Level Security policies as needed
The data fetching is modular — edit these files:
client-dashboard/utils/umami.ts— swap Umami for Plausible, Matomo, Google Analytics, etc.client-dashboard/utils/kuma.ts— swap Uptime Kuma for Betterstack, Statuspage, etc.
The dashboard components in DashboardTabs.tsx consume typed interfaces (UmamiStats, KumaMonitor), so updating the utils is all that's needed.
The email transport is configured in client-dashboard/utils/email.ts. You can swap Purelymail for any SMTP service (SendGrid, Mailgun, Gmail SMTP, Zoho, AWS SES, etc.) by updating the host, port, and auth settings. The environment variable names (PURELYMAIL_SMTP_USER, PURELYMAIL_SMTP_PASS) can be renamed to match your provider if desired — just update the references in email.ts.
Edit PORT in your .env file and update the start scripts in both package.json files.
Simple-Dashboard/
├── package.json # Root proxy for deployment
├── client-dashboard/
│ ├── app/
│ │ ├── admin/ # Admin panel
│ │ ├── api/ # API routes (analytics polling)
│ │ ├── auth/ # Auth pages (callback, update-password)
│ │ ├── dashboard/ # Client dashboard (page, actions, tabs)
│ │ └── layout.tsx # Root layout & metadata
│ ├── hooks/ # React hooks (useAutoLogout)
│ ├── src/ # Middleware
│ ├── utils/
│ │ ├── supabase/ # Supabase clients (client, server, admin, middleware)
│ │ ├── umami.ts # Umami API integration
│ │ ├── kuma.ts # Uptime Kuma API integration
│ │ └── email.ts # Email notification helpers
│ └── public/ # Static assets
This project is licensed under the GNU General Public License v2.0 — see the LICENSE file for details.
You are free to clone, modify, and distribute this project. Attribution is appreciated but not required.
Built by Total Design. Questions? Open an issue or submit a pull request.