fix: 8 quality + UX improvements

1. Cookie 'Zwecke' false positive: added 'um...zu', 'dienen', 'helfen',
   'ermöglichen' patterns — catches purpose descriptions without 'Zweck'
2. Kurzhinweis: added empty all_checks for short documents (<200 words)
3. Bezeichnungsfeld: placeholder shows 'Version / Stand' for typed docs,
   'Dokumentname' for 'Sonstiges'
4. DocCheckTab state persistence: entries + results survive navigation
5. DocCheck history: saves each check with date, doc count, findings
6. History display: 'Letzte Pruefungen' section at bottom of tab
7. ChecklistView: shows 'X von Y Pruefpunkten bestanden' per document
8. Results persist in localStorage across page navigation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-05-07 09:37:47 +02:00
parent e19d9ca532
commit 45446aef16
3 changed files with 53 additions and 5 deletions
@@ -24,12 +24,25 @@ function newEntry(): DocEntry {
}
export function DocCheckTab() {
const [entries, setEntries] = useState<DocEntry[]>([newEntry()])
const [entries, setEntries] = useState<DocEntry[]>(() => {
if (typeof window === 'undefined') return [newEntry()]
try { const s = localStorage.getItem('doc-check-entries'); return s ? JSON.parse(s) : [newEntry()] } catch { return [newEntry()] }
})
const [checkCookieBanner, setCheckCookieBanner] = useState(false)
const [loading, setLoading] = useState(false)
const [progress, setProgress] = useState('')
const [results, setResults] = useState<any>(null)
const [results, setResults] = useState<any>(() => {
if (typeof window === 'undefined') return null
try { const s = localStorage.getItem('doc-check-results'); return s ? JSON.parse(s) : null } catch { return null }
})
const [error, setError] = useState<string | null>(null)
const [history, setHistory] = useState<{ date: string; urls: number; findings: number }[]>(() => {
if (typeof window === 'undefined') return []
try { return JSON.parse(localStorage.getItem('doc-check-history') || '[]') } catch { return [] }
})
// Persist entries
React.useEffect(() => { localStorage.setItem('doc-check-entries', JSON.stringify(entries)) }, [entries])
const updateEntry = (id: string, field: keyof DocEntry, value: string) => {
setEntries(prev => prev.map(e => e.id === id ? { ...e, [field]: value } : e))
@@ -94,6 +107,11 @@ export function DocCheckTab() {
if (pollData.status === 'completed' && pollData.result) {
setResults(pollData.result)
setProgress('')
localStorage.setItem('doc-check-results', JSON.stringify(pollData.result))
const entry = { date: new Date().toISOString(), urls: validEntries.length, findings: pollData.result.total_findings || 0 }
const updated = [entry, ...history].slice(0, 30)
setHistory(updated)
localStorage.setItem('doc-check-history', JSON.stringify(updated))
break
}
if (pollData.status === 'failed') {
@@ -128,7 +146,7 @@ export function DocCheckTab() {
type="text"
value={entry.label}
onChange={e => updateEntry(entry.id, 'label', e.target.value)}
placeholder="Bezeichnung (optional)"
placeholder={entry.type === 'other' ? 'Dokumentname' : 'Version / Stand (optional)'}
className="w-40 px-3 py-2.5 border border-gray-300 rounded-lg text-sm shrink-0"
/>
<input
@@ -243,6 +261,28 @@ export function DocCheckTab() {
)}
</div>
)}
{/* History */}
{history.length > 0 && (
<div className="border border-gray-200 rounded-xl p-4">
<h4 className="text-sm font-medium text-gray-700 mb-2">Letzte Pruefungen</h4>
<div className="space-y-1">
{history.map((h, i) => (
<div key={i} className="flex items-center justify-between text-sm py-1.5 border-b border-gray-50 last:border-0">
<span className="text-gray-600">
{new Date(h.date).toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit' })}
</span>
<div className="flex items-center gap-3">
<span className="text-xs text-gray-500">{h.urls} Dok.</span>
<span className={`text-xs font-medium ${h.findings > 0 ? 'text-amber-600' : 'text-green-600'}`}>
{h.findings} Findings
</span>
</div>
</div>
))}
</div>
</div>
)}
</div>
)
}