Skip to content

timur123-star/Lumen-Analytics

Repository files navigation

Lumen Analytics — SaaS dashboard

A login-gated, fully wired analytics dashboard for a fictional product studio. Multilingual, theme-aware, animated, and grounded in deterministic mock data so it ships and demos identically on any host.

Next.js 14 · TypeScript · Tailwind CSS · Recharts · NextAuth · Radix UI · Groq

Next.js TypeScript Tailwind CSS NextAuth Recharts Radix UI Groq License

Live demo → · Source · NOVA Agency landing (live) · NOVA Agency (source)


About this project

Lumen Analytics is the second half of a two-part portfolio piece.

The first half — NOVA Agency — is a full marketing site for a fictional product studio. The hero claims that the studio ships "Lumen Analytics — a calm control room for SaaS metrics". This repository is that control room.

So the two projects together form one continuous narrative:

NOVA Agency landing page sets up the story and pitches the product → Lumen Analytics is the actual product the visitor lands inside.

Everything is hand-crafted: every chart, every animation, every translation, every page. There is no CMS, no boilerplate template, no design system bought off the shelf — and there is no real database either. Dashboard data is generated by a seeded PRNG so the demo is deterministic, runs without infrastructure, and looks identical on Railway, Vercel, or your laptop.

Disclaimer. Lumen Analytics is not a real product. NOVA Agency is not a real company. The brand, copy, customers, invoices and metrics are fictional, written as a portfolio piece. Designed and built by Тимур Валерьевич.


What is inside

Pages

  • / — marketing splash with hero, KPI strip, "what's inside" feature grid and a link to the NOVA Agency landing page.
  • /login — split-screen login. Aurora gradient on the left, credentials form on the right, demo creds visible.
  • /dashboard — overview: 4 KPI cards (MRR, active customers, churn, ARPU) with sparklines, revenue area chart, plan-distribution donut, user growth, churn & NRR, billing health, geography list and onboarding checklist.
  • /revenue — MRR / ARR / Net new tabs, expansion vs contraction, MRR composition table, plan distribution and revenue by country.
  • /growth — daily signup-vs-churn bar chart, monthly retention cohorts (M0 → M9), signup funnel and acquisition channels.
  • /customers — sortable, filterable, URL-synced table with avatar gradient, status pills, CSV export, and per-customer detail pages at /customers/[id] (health score, MRR sparkline, invoices and the customer's own activity feed).
  • /pricing — public pricing page with plan comparison, FAQ and CTA.
  • /insights — AI insights grid, 30-day MRR forecast, anomaly alerts and an "Ask Lumen AI" CTA.
  • /activity — searchable, filterable event log + GitHub-style hour-of-day × day-of-week heatmap.
  • /team — seats, members, role pills, invite flow, role permissions matrix.
  • /billing — current plan, usage meters, payment method, plans comparison and recent invoices with CSV export.
  • /developers, /webhooks, /audit, /settings, /help — API keys, webhook endpoints, audit log, workspace + integrations + notifications, and an FAQ + status page.

Localisation

Four locales served from one codebase via a custom dictionary loader, identical to the NOVA Agency landing page:

Code Language Default
en English yes
ru Русский
uk Українська
es Español

Each locale has its own metadata, OG title, navigation labels, table headers, KPI tooltips and AI prompts. The locale picker lives in the topbar and persists via the NEXT_LOCALE cookie.

Animations & micro-interactions

Every animation honours prefers-reduced-motion.

  • Theme switch with a radial clip-path reveal that originates from the toggle button.
  • Staggered fade-in-up on KPI cards, funnel rows and tables (each row delayed by index × 60ms).
  • Animated ai-gradient (purple → pink loop) + inner shimmer sweep on every "AI summary" / "Ask Lumen AI" CTA.
  • Animated mini-sparklines in KPI cards with unique gradient ids via React.useId.
  • Live pulse dot (two synchronized rings) next to the topbar AI CTA and the activity sidebar item.
  • Recharts custom tooltips with backdrop-blur, allowEscapeViewBox and a 20-px offset so they never overlap their parent chart.
  • Hover lift on every card (translateY(-2px) + softened primary-tinted shadow) and an icon micro-rotation on the AI buttons.
  • Hover-state highlights between the plan-distribution donut and its legend rows (active slice scales, others fade).
  • Aurora blobs on the marketing and login pages, plus a faint grid background masked with a radial gradient.

UX details

  • ⌘K / Ctrl+K command palette (layout-independent — works with Russian keyboards too) with theme switcher, sign-out and recent-customer / country / plan jump.
  • ? opens the keyboard-shortcuts dialog. g d, g r, g g, g i, g a, g c for navigation. t toggles theme. r refreshes data.
  • Notifications dropdown with unread badge and seeded alerts.
  • Click-to-copy API key and webhook secret with toast confirmation.
  • Skip-to-content link, global :focus-visible rings, ARIA-correct disclosure widgets.
  • Tables that scroll horizontally instead of breaking on narrow viewports.

Lumen AI (Groq)

A streaming chat sheet grounded in live KPIs, the funnel, cohorts, top customers and recent events.

  • Model: llama-3.3-70b-versatile on Groq's free tier.
  • System prompt is regenerated on every request from lib/ai-context.ts against the seeded dataset, so the model can quote real numbers.
  • Open with the topbar button, ⌘K → Ask Lumen AI, or ⌘J.
  • If GROQ_API_KEY is not set, the dashboard still works — only the chat returns a graceful 503.

SEO & metadata

  • Locale-aware metadata, OpenGraph, Twitter cards.
  • Custom app/opengraph-image.tsx rendered at the edge.
  • not-found.tsx, error.tsx, favicon.svg and a brand wordmark component.

Mock API

All endpoints live under /api/*, are session-gated by NextAuth middleware, and read from a single seeded PRNG (lib/data.ts):

Route Returns
/api/metrics/summary top-line KPI summary (MRR, ARPU, NRR, churn, …).
/api/metrics/mrr daily MRR series + new / expansion / contraction / churn split.
/api/metrics/users daily signups vs churn series.
/api/metrics/churn churn rate + NRR series.
/api/customers filterable, sortable list of customers.
/api/events activity-feed events with type / actor / target metadata.
/api/ai Groq chat completion proxy (streamed, KPI-grounded prompt).
/api/auth/[...nextauth] NextAuth credentials provider.

Stack

Layer Tooling
Framework Next.js 14 (App Router, RSC)
Styling Tailwind CSS + HSL CSS variables
Charts Recharts
Auth NextAuth (credentials, JWT sessions)
Primitives Radix UI + shadcn/ui
Icons Lucide
Animations Tailwind keyframes + tailwindcss-animate
Forms Native <form> + Server Actions / NextAuth credentials
Theme next-themes + View Transitions API
Command palette cmdk
Toasts Sonner
AI Groqllama-3.3-70b-versatile
Hosting Railway / Vercel

Getting started

npm install
cp .env.example .env.local
# at minimum set NEXTAUTH_SECRET — see "Environment variables" below
npm run dev

Then open http://localhost:3000 and sign in with the demo credentials shown on the login page.

Scripts

npm run dev        # development server on :3000
npm run build      # production build (strict TypeScript)
npm run start      # serve the production build
npm run lint       # ESLint with the Next.js config
npm run typecheck  # tsc --noEmit

Demo credentials

demo@lumenanalytics.io
lumen-demo-2026

These are seeded in lib/auth.ts — there is no signup flow because there is no database. The login page renders them right next to the form so reviewers don't have to dig.

Environment variables

Variable Purpose
NEXTAUTH_SECRET Required. Used by NextAuth to sign JWTs. Generate with openssl rand -base64 32.
NEXTAUTH_URL Required in production. Must match the public URL exactly (https://…, no trailing slash).
GROQ_API_KEY Optional. Without it, "Ask Lumen AI" returns a graceful 503 — everything else still works.

Project layout

src/
├── app/
│   ├── (app)/                # authenticated app shell
│   │   ├── dashboard/        # /dashboard
│   │   ├── revenue/          # /revenue
│   │   ├── growth/           # /growth
│   │   ├── customers/        # /customers, /customers/[id]
│   │   ├── insights/         # /insights
│   │   ├── activity/         # /activity
│   │   ├── billing/          # /billing
│   │   ├── team/             # /team
│   │   ├── developers/       # /developers
│   │   ├── webhooks/         # /webhooks
│   │   ├── audit/            # /audit
│   │   ├── settings/         # /settings
│   │   └── help/             # /help
│   ├── api/                  # session-gated mock APIs + Groq proxy
│   │   ├── auth/[...nextauth]/route.ts
│   │   ├── metrics/{summary,mrr,users,churn}/route.ts
│   │   ├── customers/route.ts
│   │   ├── events/route.ts
│   │   └── ai/route.ts
│   ├── login/                # /login (split-screen)
│   ├── pricing/              # /pricing (marketing pricing page)
│   ├── opengraph-image.tsx   # default OG image
│   ├── globals.css
│   ├── layout.tsx
│   └── page.tsx              # marketing splash at /
├── components/
│   ├── charts/               # all Recharts wrappers (custom tooltips)
│   ├── dashboard/            # KpiCard, FunnelList, CustomersTable, Sidebar, Topbar, …
│   ├── ui/                   # button, badge, card, tabs, animated-number, live-pulse, …
│   ├── theme-toggle.tsx
│   ├── radial-theme.tsx      # radial clip-path reveal between themes
│   ├── locale-switcher.tsx
│   └── locale-provider.tsx
└── lib/
    ├── auth.ts               # NextAuth credentials provider + demo user
    ├── data.ts               # seeded PRNG + every metric / customer / event
    ├── ai-context.ts         # KPI-grounded system prompt for Groq
    ├── csv.ts                # CSV export helper used by tables
    ├── i18n/                 # locales, dictionary loader, format helpers
    └── utils.ts              # cn(), formatCurrency, percent helpers

Theming

Themes are driven by HSL CSS variables in globals.css and orchestrated by next-themes with attribute="class". The theme switch uses the View Transitions API with a radial clip-path reveal that originates from the toggle button (components/radial-theme.tsx) and falls back to a CSS-only crossfade on browsers without VT support. Dark is the default.

Every chart, badge, button and tooltip is built against the same --primary / --success / --warning / --destructive tokens, so adding a third theme is a matter of redefining the variables.


Quality bar

  • npm run lint — clean, zero warnings.
  • npm run typecheck — strict TypeScript, zero errors.
  • npm run build — production build passes.
  • All animations honour prefers-reduced-motion.
  • WCAG AA contrast on dark and light themes.
  • Keyboard-accessible: every interactive element is reachable, every focus state is visible.
  • Tables, charts, sheets and dropdowns all behave correctly on touch + narrow viewports.

Deploying

This is a vanilla Next.js app and runs on any Node host.

Railway

  1. Create a new service from this repo. Railway autodetects the Next.js build (npm run build / npm run start).

  2. Open the service → Settings → Networking → Public Networking and click Generate Domain to get a *.up.railway.app URL.

  3. Open Variables and add:

    NEXTAUTH_SECRET=<output of `openssl rand -base64 32`>
    NEXTAUTH_URL=https://<your-service>.up.railway.app
    GROQ_API_KEY=<your Groq key>   # optional, only for Ask Lumen AI

    No quotes, no trailing slash. Use a fresh secret per environment. Without GROQ_API_KEY the dashboard works but "Ask Lumen AI" returns a 503.

  4. Railway redeploys automatically when variables change. After ~30 s, open the public URL and sign in with the demo credentials.

Do you need a database? No. Dashboard data is seeded mock data and the AI endpoint is stateless (it just proxies to Groq).

Troubleshooting "Server error / There is a problem with the server configuration." This is NextAuth's canonical error when NEXTAUTH_SECRET is missing in production. Add it in Railway → Variables and redeploy. If it persists, double-check that NEXTAUTH_URL matches the actual public URL exactly.

Vercel

  1. Import the repo into Vercel — the framework preset and build command are auto-detected.
  2. Add NEXTAUTH_SECRET, NEXTAUTH_URL and (optionally) GROQ_API_KEY under Project → Settings → Environment Variables.
  3. Deploy.

Credits

Designed and built by Тимур Валерьевич as a portfolio piece. Lumen Analytics is fictional — the brand, the customers, the invoices and the AI persona exist only inside this repository and its companion NOVA Agency landing page.

Releases

No releases published

Packages

 
 
 

Contributors