Initial fleet skill

This commit is contained in:
Azat
2026-02-03 00:46:40 +01:00
commit bc2f2e89ed
23 changed files with 777 additions and 0 deletions

47
ui/src/lib/api.ts Normal file
View File

@@ -0,0 +1,47 @@
const API_BASE = '/api'
export interface Machine {
id: string
name: string
url: string
version: string
skills: string[]
status: 'running' | 'stopped' | 'unknown'
lastSeen: number
}
export async function fetchMachines(): Promise<Machine[]> {
const res = await fetch(`${API_BASE}/machines`)
if (!res.ok) throw new Error('Failed to fetch machines')
return res.json()
}
export async function fetchMachine(id: string): Promise<Machine> {
const res = await fetch(`${API_BASE}/machines/${id}`)
if (!res.ok) throw new Error('Failed to fetch machine')
return res.json()
}
export async function deleteMachine(id: string): Promise<void> {
const res = await fetch(`${API_BASE}/machines/${id}`, { method: 'DELETE' })
if (!res.ok) throw new Error('Failed to delete machine')
}
export async function registerMachine(machine: Omit<Machine, 'lastSeen'>): Promise<Machine> {
const res = await fetch(`${API_BASE}/machines/register`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(machine),
})
if (!res.ok) throw new Error('Failed to register machine')
return res.json()
}
// Calculate time since last seen
export function timeSince(timestamp: number): string {
const seconds = Math.floor(Date.now() / 1000 - timestamp)
if (seconds < 60) return `${seconds}s ago`
if (seconds < 3600) return `${Math.floor(seconds / 60)}m ago`
if (seconds < 86400) return `${Math.floor(seconds / 3600)}h ago`
return `${Math.floor(seconds / 86400)}d ago`
}