import { useEffect, useState } from 'react'; import { api } from '../api/client'; import StatusBadge from '../components/StatusBadge'; interface Datapoint { id: number; name: string; label: string | null; value: string | null; unit: string | null; source_type: string; status: string; updated_at: string | null; } export default function Datapoints() { const [datapoints, setDatapoints] = useState([]); const [edits, setEdits] = useState>({}); const [error, setError] = useState(''); async function load() { try { const data = await api.get('/api/datapoints'); setDatapoints(data); const e: Record = {}; data.forEach((dp) => { e[dp.id] = { label: dp.label ?? '', unit: dp.unit ?? '' }; }); setEdits(e); } catch (e) { setError((e as Error).message); } } useEffect(() => { load(); const interval = setInterval(load, 10000); return () => clearInterval(interval); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); async function handleBlur(id: number, field: 'label' | 'unit') { try { await api.put(`/api/datapoints/${id}`, { [field]: edits[id]?.[field] || null }); } catch (e) { setError((e as Error).message); } } async function handleDelete(id: number) { if (!confirm('Datenpunkt wirklich loeschen?')) return; try { await api.del(`/api/datapoints/${id}`); load(); } catch (e) { setError((e as Error).message); } } return (

Datenpunkte

{error &&
{error}
}
{datapoints.length === 0 && ( )} {datapoints.map((dp) => ( ))}
Interner Name Bezeichnung Wert Einheit Quelle Status Aktion
Keine Datenpunkte vorhanden
{dp.name} setEdits({ ...edits, [dp.id]: { ...edits[dp.id], label: e.target.value } })} onBlur={() => handleBlur(dp.id, 'label')} /> {dp.value ?? '-'} setEdits({ ...edits, [dp.id]: { ...edits[dp.id], unit: e.target.value } })} onBlur={() => handleBlur(dp.id, 'unit')} /> {dp.source_type}
); }