import React, { useState } from 'react'; import { Card, CardContent, Typography, Box, Switch, TextField, Slider, Button, FormControlLabel, Alert } from '@mui/material'; import { Save as SaveIcon } from '@mui/icons-material'; import type { ModerationConfig } from './api'; import { updateModerationConfig } from './api'; interface Props { config: ModerationConfig; onSaved: (next: ModerationConfig) => void; onError: (msg: string) => void; } export const TriageCard: React.FC = ({ config, onSaved, onError }) => { const [draft, setDraft] = useState(config); const [saving, setSaving] = useState(false); React.useEffect(() => { setDraft(config); }, [config]); const dirty = JSON.stringify(draft) !== JSON.stringify(config); const handleSave = async () => { setSaving(true); try { const res = await updateModerationConfig({ triage_enabled: draft.triage_enabled, confidence_low: Number(draft.confidence_low), risk_grey_min: Number(draft.risk_grey_min), risk_grey_max: Number(draft.risk_grey_max), queue_relax_at: draft.queue_relax_at, queue_strict_at: draft.queue_strict_at, auto_tune_enabled: draft.auto_tune_enabled, }); if (res.success && res.data) { onSaved(res.data); } else { onError(res.error ?? 'Update failed'); } } catch (e) { onError((e as Error).message); } finally { setSaving(false); } }; return ( Triage Decide which sessions enter the moderation queue. Edits sync to Redis on save. setDraft({ ...draft, triage_enabled: e.target.checked })} /> } label={draft.triage_enabled ? 'Enabled' : 'Disabled'} labelPlacement="start" /> {!draft.triage_enabled && ( Triage is OFF. No sessions will enter the moderation queue. )} Confidence threshold (low) setDraft({ ...draft, confidence_low: Number(v) })} /> Sessions with confidence < {draft.confidence_low} go to queue Risk grey zone setDraft({ ...draft, risk_grey_min: e.target.value })} /> setDraft({ ...draft, risk_grey_max: e.target.value })} /> Sensitive topics with risk in this band go to queue setDraft({ ...draft, queue_relax_at: parseInt(e.target.value, 10) || 0 })} /> setDraft({ ...draft, queue_strict_at: parseInt(e.target.value, 10) || 0 })} /> setDraft({ ...draft, auto_tune_enabled: e.target.checked })} /> } label="Auto-tune thresholds (cron)" /> ); };