Appearance
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:
qrcodepackage 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 templatesEntry Point
web/src/web.ts serves as the router:
- Checks if the user is logged in (JWT in
localStorage) - If logged in → loads
dashboard_page() - If not → loads
login_page() - Exports
web_version_get()for displaying version info
Embedding in Server
The web frontend is not served independently in production. The build pipeline:
web/build.tscompiles the TypeScript to a single JS bundlescripts/build/generators/embeds.tsembeds the built files (HTML, CSS, JS) into the server binary- 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 typecheckThe dev command uses concurrently to run the Bun builder (watching for changes) and live-server on port 8090.