Skip to main content

Web admin (apps/web-admin)

The operator UI — a Next.js 16 (App Router) admin dashboard for managing customers, devices, modules, and dashboard versions. It talks to the API server through the generated @signapps/api-client.

  • Workspace: apps/web-admin  ·  package name: frontend
  • Output: Next.js standalone server (.next/standalone/.../server.js)

Tech stack

ConcernChoice
FrameworkNext.js 16 (App Router), React 19
UITamagui (@signapps/ui), react-native-web
State / dataRedux Toolkit + RTK Query (@signapps/api-client)
Config@signapps/next-config (createNextAppConfig)

Usage

Run in dev

pnpm dev:fe # next dev (port 3000)

A predev hook runs scripts/ensure-api-client.mjs, which makes sure the API client is generated from the API's OpenAPI spec before the dev server starts. The app expects the API at NEXT_PUBLIC_API_URL (default http://localhost:3001/api), so run pnpm dev:api alongside it.

Build

pnpm build:fe

Expands to:

node ./scripts/ensure-api-client.mjs \
&& next build \
&& node ./scripts/patch-standalone-deps.mjs

next.config.ts sets output: 'standalone' and transpilePackages for the @signapps/* workspace packages. The result is a self-contained server in .next/standalone/ plus .next/static/ and public/ assets.

Deploy

Built locally, then shipped over SSH (pnpm deploy:fescripts/deploy-fe.mjs): it rsyncs/scp's .next/standalone/, .next/static/, and public/ to the server and runs under PM2 (ecosystem.config.cjs, port 3010). Deploy env vars: DEPLOY_HOST, DEPLOY_USER, APP_ROOT, DEPLOY_FRONTEND_PATH, SSH_KEY_PATH, DEPLOY_PORT, and the build-time NEXT_PUBLIC_API_URL.

Build-time env

NEXT_PUBLIC_* variables are baked in at next build, so NEXT_PUBLIC_API_URL must be set before building for the target environment.

Structure

src/app/ App Router routes
/login public login
/dashboard/* protected: customers, devices, modules, versions, users, overview
src/features/ feature modules (customers, devices, modules, versions, users, overview)
src/middleware.ts cookie auth (admin_auth_token) → redirects to /login

Auth is cookie-based: login issues an admin_auth_token cookie; the middleware guards /dashboard/* and redirects unauthenticated users to /login?from=…. The API client attaches the token for authenticated requests.