feat: add standalone (frontend-only) mode via VITE_STANDALONE build flag

- App.tsx: bypass auth gate, swap canvas save/load to localStorage
- Sidebar.tsx: hide scan views and Scan Network button
- useStatusPolling.ts: skip WebSocket connection
- Dockerfile.frontend: accept VITE_STANDALONE build arg
- docker-publish.yml: build ghcr.io/pouzor/homelable-frontend-standalone image
- docker-compose.standalone.yml: frontend-only compose file
- install.sh: add --standalone flag

Usage:
  curl -fsSL .../install.sh | bash -s -- --standalone
  cd homelable && docker compose up -d
This commit is contained in:
Pouzor
2026-03-09 14:00:25 +01:00
parent 1cd93ed250
commit 7ba5e888b4
7 changed files with 91 additions and 24 deletions
+5 -2
View File
@@ -6,14 +6,17 @@ import { scanApi } from '@/api/client'
import { toast } from 'sonner'
import { PendingDeviceModal, type PendingDevice } from '@/components/modals/PendingDeviceModal'
const STANDALONE = import.meta.env.VITE_STANDALONE === 'true'
type SidebarView = 'canvas' | 'pending' | 'hidden' | 'history'
const VIEWS = [
const ALL_VIEWS = [
{ id: 'canvas' as SidebarView, icon: LayoutDashboard, label: 'Canvas' },
{ id: 'pending' as SidebarView, icon: ScanLine, label: 'Pending Devices' },
{ id: 'hidden' as SidebarView, icon: EyeOff, label: 'Hidden Devices' },
{ id: 'history' as SidebarView, icon: Clock, label: 'Scan History' },
]
const VIEWS = STANDALONE ? ALL_VIEWS.slice(0, 1) : ALL_VIEWS
interface ScanRun {
id: string
@@ -123,7 +126,7 @@ export function Sidebar({ onAddNode, onScan, onSave, onNodeApproved }: SidebarPr
{/* Actions */}
<div className="flex flex-col gap-0.5 p-2 border-t border-border">
<SidebarItem icon={Plus} label="Add Node" collapsed={collapsed} onClick={onAddNode} />
<SidebarItem icon={ScanLine} label="Scan Network" collapsed={collapsed} onClick={handleScan} />
{!STANDALONE && <SidebarItem icon={ScanLine} label="Scan Network" collapsed={collapsed} onClick={handleScan} />}
<SidebarItem
icon={Save}
label="Save Canvas"