Skip to content

Web Frontend

The SafeCall web frontend is a single-page admin UI for managing and monitoring the entire SafeCall system. It is built with TypeScript and bundled with Bun.

Tech Stack

  • Language: TypeScript
  • CSS Framework: Bulma (^1.0.3)
  • Canvas: Pixi.js (^8.10.1) with pixi-viewport for pan/zoom
  • Validation: Valibot for API contract validation
  • Icons: Font Awesome
  • Search: Fuse.js for client-side fuzzy search
  • QR Codes: qrcode package for generating navigation QR codes
  • Auth: JWT via jose

Architecture

The web app is a vanilla TypeScript SPA (no framework). Pages are JavaScript functions that manipulate the DOM directly with HTML templates.

web/src/
├── web.ts                 # Entry point (router)
├── pages/                 # Page modules
│   ├── dashboard.ts       # Main dashboard
│   ├── login.ts           # Login form
│   ├── beacons.ts         # Beacon management
│   ├── gateways.ts        # Gateway management
│   ├── users.ts           # User management
│   ├── locations.ts       # Location management
│   ├── maps.ts            # Map management
│   ├── zones.ts           # Zone editor + live tracking
│   └── navigation.ts      # Navigation graph editor
├── lib/                   # Shared utilities
│   ├── contracts.ts       # Valibot API schemas
│   ├── util.ts            # DOM helpers, auth, notifications
│   ├── socket.ts          # WebSocket client
│   ├── canvas.ts          # Pixi.js zone/tracking canvas
│   └── image.ts           # Image loading utilities
└── templates/             # HTML templates
    ├── generic/           # Navbar, footer, modals
    ├── login/             # Login form templates
    ├── dashboard/         # Dashboard template
    ├── beacons/           # Beacon CRUD templates
    ├── gateways/          # Gateway CRUD templates
    ├── users/             # User management templates
    ├── locations/         # Location templates
    ├── maps/              # Map management templates
    ├── zones/             # Zone editor templates
    └── navigation/        # Navigation editor templates

Entry Point

web/src/web.ts serves as the router:

  1. Checks if the user is logged in (JWT in localStorage)
  2. If logged in → loads dashboard_page()
  3. If not → loads login_page()
  4. Exports web_version_get() for displaying version info

Embedding in Server

The web frontend is not served independently in production. The build pipeline:

  1. web/build.ts compiles the TypeScript to a single JS bundle
  2. scripts/build/generators/embeds.ts embeds the built files (HTML, CSS, JS) into the server binary
  3. The server serves them from server/src/static_embeds.ts

This means the entire application ships as a single binary with the web UI included.

Development

bash
cd web

# Install dependencies
bun install

# Dev server with hot reload
bun run dev

# Build for production
bun run build

# Type checking
bun run typecheck

The dev command uses concurrently to run the Bun builder (watching for changes) and live-server on port 8090.