Portal
The EsoCore Portal is a web application that provides the user-facing interface for device monitoring, fleet management, and data visualization. It connects to the Backend Server APIs and presents real-time dashboards, device management tools, and alerting interfaces.
Technology Stack
| Component | Technology | Version |
|---|---|---|
| Framework | Nuxt 4 | 4.2 |
| UI Library | Nuxt UI (Tailwind CSS 4) | 4.0 |
| State Management | Pinia | 2.3 |
| Charts | Chart.js + vue-chartjs | 4.4 / 5.3 |
| HTTP Client | ofetch ($fetch) + Axios | -- |
| Real-time | socket.io-client (planned) | 4.8 |
| Auth | Token auth (Pinia store) | -- |
| Utilities | VueUse | 12.0 |
| Node.js | 22+ | -- |
| Package Manager | pnpm | 10+ |
Features
Device Dashboard
The main dashboard provides an at-a-glance overview of the entire device fleet:
- Fleet health summary with device counts by status
- Recent telemetry data and trend indicators
- Active alerts and event notifications
- Quick navigation to individual device detail views
Device Management
- Browse, search, and filter the device registry
- View individual device details: configuration, firmware version, connectivity status
- Monitor real-time sensor readings and historical telemetry charts
- Track device health metrics and uptime
Asset Monitoring
- Associate devices with physical equipment and assets
- View per-asset dashboards combining data from multiple sensors
- Track maintenance history and upcoming schedules
Alerting
- View and acknowledge active alerts
- Filter events by severity, type, and time range
- Event detail views with full context and suggested actions
Application Structure
The portal code lives in the portal/ directory:
portal/
├── app/
│ ├── app.vue # Root application component
│ ├── layouts/
│ │ ├── default.vue # Public layout
│ │ └── authenticated.vue # Authenticated layout with sidebar
│ ├── pages/
│ │ ├── index.vue # Landing/login page
│ │ └── dashboard.vue # Main dashboard
│ ├── components/
│ │ └── ThemeToggle.vue # Dark/light mode toggle
│ ├── composables/
│ │ ├── useApi.ts # API client (ofetch wrapper with auth)
│ │ └── useBranding.ts # Dynamic branding configuration
│ ├── stores/
│ │ └── auth.ts # Authentication store (Pinia)
│ ├── config/
│ │ └── branding.ts # Brand name, colors, product name
│ ├── middleware/
│ │ └── auth.ts # Route guard for authenticated pages
│ └── plugins/
│ ├── auth.client.ts # Auth initialization (cookie restore)
│ └── force-dark.client.ts # Dark mode initialization
├── assets/css/main.css # Global styles
├── nuxt.config.ts # Nuxt configuration
└── package.json
Key Architecture Decisions
- SSR with SPA fallback: The portal uses server-side rendering by default, but authenticated routes
(
/dashboard,/devices/**,/assets/**,/alerts/**) are rendered client-side only for better interactivity. - Dark mode by default: The color mode defaults to dark, matching industrial control room environments.
- White-label ready: Branding (product name, company name, colors) is configurable via environment variables
and the
branding.tsconfig, allowing partners to customize the portal for their customers.
Local Development Setup
Prerequisites
- Node.js 22.19+ (or 24.11+)
- pnpm 10 or later
- The Backend Server running at
http://localhost:8000(see Backend Server)
Installation
cd portal
# Install dependencies
pnpm install
# Start the development server
pnpm dev
The portal will be available at http://localhost:3000.
Environment Variables
| Variable | Default | Description |
|---|---|---|
NUXT_PUBLIC_API_BASE_URL |
http://localhost:8000/api |
Backend API base URL |
NUXT_PUBLIC_WS_BASE_URL |
ws://localhost:8000/ws |
WebSocket URL for real-time updates |
NUXT_PUBLIC_AUTH_REDIRECT_URL |
/dashboard |
Redirect after login |
NUXT_PUBLIC_APP_NAME |
EsoCore |
Application display name |
NUXT_PUBLIC_BRAND |
Newmatik |
Brand name |
NUXT_PUBLIC_PRODUCT |
EsoCore |
Product name |
NUXT_PUBLIC_DISPLAY_BRAND |
true |
Show/hide brand name in UI |
Available Scripts
pnpm dev # Start development server with hot reload
pnpm build # Build for production
pnpm preview # Preview production build locally
pnpm lint # Run ESLint
pnpm lint:fix # Auto-fix lint issues
pnpm format # Format code with Prettier
pnpm format:check # Check formatting
pnpm typecheck # Run TypeScript type checking
Building for Production
pnpm build
The portal is configured with the node-server Nitro preset, producing a Node.js server bundle suitable for
deployment behind a reverse proxy (Nginx, Caddy, etc.).
Connecting to the Backend
The portal communicates with the Backend Server via REST APIs. In development, both services run locally:
| Service | URL | Purpose |
|---|---|---|
| Backend Server | http://localhost:8000 |
Django REST API |
| Portal | http://localhost:3000 |
Nuxt.js frontend |
CORS is configured on the backend to allow requests from the portal origin. In production, both services are typically served behind the same reverse proxy or domain to simplify CORS handling.
Related Documentation
- Backend Server -- The Django REST API that powers the portal
- API Specification -- Detailed API endpoint documentation
- Cloud Infrastructure -- Production deployment and hosting