Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SalesRealtime Dashboard

A real-time sales operations dashboard. Sales stream in over a WebSocket and the panel updates instantly — live KPIs, a revenue trend, product performance, a regional bubble map, a conversion gauge and a streaming order feed. Built with a Node.js + Express + WebSocket backend, PostgreSQL (with a zero-config in-memory fallback) and a React + Vite + Chart.js frontend dressed in the "Pulse" teal-cyan theme.

Stack: Node.js (ESM) · Express · ws · PostgreSQL / pg-mem · React 18 · Vite · Chart.js Port: 5252 · Theme: Pulse (dark + light) · Backend default: pg-mem (zero-config)


Features

  • Live overview — Revenue, Orders, Average Order Value and Conversion Rate KPIs, each with a period-over-period delta and an inline sparkline.
  • Real-time updates — a server-side sale simulator and every manually recorded sale broadcast over a WebSocket; the dashboard feed, the live badge and (debounced) the aggregate charts refresh the instant a sale lands.
  • Revenue trend — area line chart, switchable between day / week / month grouping and 7 / 30 / 90-day ranges.
  • Sales volume — orders-per-period bar chart with rich hover tooltips.
  • Product performance — top 5 products by revenue with share bars.
  • Regional sales — custom SVG bubble map; bubble size encodes revenue per region, with on-hover detail.
  • Conversion gauge — semicircular gauge of orders ÷ visits.
  • Channel mix — revenue doughnut across web / mobile / marketplace / in-store.
  • Order stream — paginated, resizable orders table; record a sale from a modal and watch it propagate live.
  • Product catalog — 220 seeded products, searchable, category-filterable, paginated, with drag-to-resize columns.
  • System log monitor — in-app live log tail with level filtering.
  • Exports — real .xlsx (ExcelJS) and .pdf (PDFKit) report downloads.
  • Dark / light theme — persisted to localStorage, initialised from prefers-color-scheme, toggled from the top bar.
  • Collapsible sidebar — a floating edge-chevron collapses the rail to icons.

Quick start

Zero-config (in-memory pg-mem)

No database, no Docker. The server boots an in-memory PostgreSQL (pg-mem), seeds 220 products / 8 regions / 3,000+ orders automatically, and starts the live simulator.

npm run setup      # install server + client deps, then build the client
npm start          # → http://localhost:5252

npm run setup is shorthand for: install root deps, build the client (cd client && npm install && npm run build). After it finishes, npm start serves the built SPA and the API on the same port.

Development (hot reload)

Run the API and the Vite dev server side by side:

npm install
npm run dev                 # API + simulator on :5252
cd client && npm install && npm run dev   # Vite on :5300, proxies /api and /ws → :5252

Open http://localhost:5300 for the hot-reloading client.

Real PostgreSQL (optional)

docker compose up -d
export DATABASE_URL=postgres://sales:sales@localhost:5432/salesrealtime   # PowerShell: $env:DATABASE_URL="..."
npm run seed       # one-time: populate the database
npm start

When DATABASE_URL is set the app uses the real pg driver; otherwise it falls back to pg-mem. The SQL is identical either way.


Scripts

Script What it does
npm start Run the server (serves API, WebSocket and built client)
npm run dev Run the server with --watch
npm run seed Reseed the database (mainly for real PostgreSQL)
npm run build Install client deps and build the SPA into client/dist
npm run setup Install everything and build the client

Architecture

SalesRealtime Dashboard/
├── server/
│   ├── index.js          # Express app, HTTP server, WS init, static SPA, bootstrap
│   ├── db.js             # pg / pg-mem abstraction + schema
│   ├── seed.js           # 220 products, 8 regions, 3k orders, 60d traffic
│   ├── sales.js          # recordSale() — insert order + broadcast live
│   ├── simulator.js      # periodic random sales → broadcast (the "real-time" engine)
│   ├── analytics.js      # dashboard aggregations (SQL roll-ups + JS time bucketing)
│   ├── export.js         # ExcelJS + PDFKit report streams
│   ├── ws.js             # WebSocket broadcast hub
│   ├── logger.js         # fire-and-forget log writer
│   └── routes/           # dashboard · products · sales · logs · export
└── client/
    └── src/
        ├── App.jsx              # app shell: sidebar + topbar + WS-driven live badge
        ├── views/               # Dashboard · Products · Sales · Logs
        ├── components/          # Charts · RegionalMap · ConversionGauge · ResizableTable · …
        ├── useWebSocket.js      # auto-reconnecting WS hook
        ├── theme.jsx            # dark/light context
        └── styles.css           # the "Pulse" design system

How real-time works

  1. simulator.js fires every 4–9s, inserts a random order via recordSale(), and bumps today's visit count so conversion stays realistic.
  2. recordSale() (also used by the POST /api/sales endpoint) writes the order and calls broadcast('sale', …) in ws.js.
  3. The browser's useWebSocket hook receives the frame; App.jsx increments the live badge and hands the sale to the dashboard, which prepends it to the feed instantly and debounces a full refresh so the KPIs and charts catch up.

Data notes

  • The dashboard reads ranged roll-ups via SQL GROUP BY; time-series bucketing (day/week/month) is done in JS so it behaves identically on pg-mem and PostgreSQL without depending on date_trunc/to_char.
  • PostgreSQL returns NUMERIC/BIGINT aggregates as strings, so values are coerced with Number() on the way out.

API

Method Endpoint Description
GET /api/health Status + active backend
GET /api/dashboard?range=&group= Full dashboard payload (KPIs, charts, feed)
GET /api/dashboard/timeseries Revenue/order time-series only
GET /api/products?page=&search=&category= Paginated catalog
GET /api/products/categories Category list
GET /api/sales?page= Paginated orders
GET /api/sales/meta Products + regions for the record-sale form
POST /api/sales Record a sale → broadcasts live
GET /api/logs?limit=&level= Recent log entries
GET /api/export/excel?range= .xlsx report download
GET /api/export/pdf?range= .pdf report download
WS /ws Live sale broadcast channel

Responses follow a consistent envelope: { success, data, meta? }.


Notes

  • The bundled pg-mem backend is in-memory: data resets on each restart and is re-seeded automatically. Use the PostgreSQL path for durable storage.
  • The esbuild advisory surfaced by npm audit affects Vite's dev toolchain only; the shipped artifact is static HTML/CSS/JS served by Express, so esbuild is not part of the runtime.

License

Apache License 2.0 — see LICENSE.

About

Real-time sales dashboard — WebSocket live sale stream, KPIs, revenue trend, regional bubble map, conversion gauge and exports. Node.js + Express + ws + React + Vite + Chart.js, with a zero-config pg-mem / PostgreSQL backend.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages