import { useEffect, useState } from 'react' import { api } from '../api.js' import { useAuth } from '../context/AuthContext.jsx' const emptyForm = { canonical_label: '', entity_type: 'PERSON', aliases: '' } export default function AdminIdentitiesPage() { const { session } = useAuth() const [data, setData] = useState(null) const [form, setForm] = useState(emptyForm) const [error, setError] = useState('') const [notice, setNotice] = useState('') const load = () => api('/api/admin/identities', { token: session.token }) .then(setData) .catch((e) => setError(e.message)) useEffect(() => { load() }, [session.token]) const aliasesOf = (value) => value .split(',') .map((item) => item.trim()) .filter(Boolean) const create = async (e) => { e.preventDefault() setError('') setNotice('') try { await api('/api/admin/identities', { token: session.token, method: 'POST', body: { canonical_label: form.canonical_label, entity_type: form.entity_type, aliases: aliasesOf(form.aliases) } }) setForm(emptyForm) setNotice('Eintrag bestätigt und lokal gespeichert. Kein externer Aufruf.') await load() } catch (err) { setError(err.message) } } const patch = async (id, body) => { setError('') try { await api(`/api/admin/identities/${id}`, { token: session.token, method: 'PATCH', body }) await load() } catch (err) { setError(err.message) } } const remove = async (id) => { setError('') try { await api(`/api/admin/identities/${id}`, { token: session.token, method: 'DELETE' }) await load() } catch (err) { setError(err.message) } } const confirmProposal = async (id) => { setError('') try { await api(`/api/admin/identities/proposals/${id}/confirm`, { token: session.token, method: 'POST', body: {} }) await load() } catch (err) { setError(err.message) } } const dismissProposal = async (id) => { setError('') try { await api(`/api/admin/identities/proposals/${id}/dismiss`, { token: session.token, method: 'POST', body: {} }) await load() } catch (err) { setError(err.message) } } return (

Identitäten

Nur lokale bestätigte Registry. Detect-Treffer werden nicht automatisch aktiv. Unbestätigte Vorschläge gelten nicht als bekannte Identität. Kein externer Egress. Mehrdeutigkeit entsteht aus Dialog-Bestätigungen, nicht aus einer Wortlisten-Seite.

{error &&

{error}

} {notice &&

{notice}

} {data?.backup &&

{data.backup}

}
{(data?.registry || []).map((item) => { const sense = (data?.senses || []).find( (entry) => (entry.normalized_label || '').toLowerCase() === (item.canonical_label || '').toLowerCase() ) return ( ) })}
Bezeichnung Typ Status Aliase
{item.canonical_label} {sense?.ambiguous ? · mehrdeutig : null} {item.status} {(item.aliases || []).join(', ')} {item.status !== 'confirmed' && ( )} {item.status !== 'inactive' && ( )}

Identität bestätigen

Unbestätigte Detect-Vorschläge

Wirken nicht auf spätere Requests und ersetzen keine vollständige Detection.

) }