feat: Placeholder farbig markieren in Freigabe-View und Pair-Modal

Objekt-Placeholder indigo, Wort-Placeholder grün, geleakte ⟦PHn⟧-Tokens rot.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-06-12 22:43:46 +02:00
parent 96c436e0e9
commit e78be430c7
4 changed files with 56 additions and 4 deletions

View File

@@ -1,6 +1,7 @@
import { useState } from 'react';
import { apiPost, apiPatch } from '../lib/api';
import { buildRows } from '../lib/pairRows';
import PlaceholderText from './PlaceholderText';
const LANGS = [
{ code: 'de', flag: '🇩🇪' },
@@ -130,7 +131,7 @@ function Row({ row }) {
const val = row.cell(l.code);
return (
<div key={l.code} className={`text-sm rounded-lg border px-2.5 py-1.5 ${val ? `bg-slate-50 border-slate-200 ${row.color}` : 'bg-red-50 border-red-200 text-red-400 italic'}`}>
{val || 'fehlt'}
{val ? <PlaceholderText text={val} /> : 'fehlt'}
</div>
);
})}

View File

@@ -0,0 +1,29 @@
import { parsePlaceholderSegments } from '../lib/pairRows';
// Rendert Satztext mit farbig markierten Placeholdern:
// {{label.o:id}} → indigo (Objekt-Verknüpfung, passend zu den 🔗-Buttons)
// {{label.w:id}} → emerald (Wort-Verknüpfung)
// ⟦PHn:label⟧ → rot (geleaktes Übersetzungs-Token, Datenfehler)
const KIND_STYLES = {
object: { className: 'bg-indigo-100 text-indigo-800 rounded px-0.5', title: 'Objekt-Placeholder' },
word: { className: 'bg-emerald-100 text-emerald-800 rounded px-0.5', title: 'Wort-Placeholder' },
broken: { className: 'bg-red-100 text-red-700 rounded px-0.5 line-through', title: 'Kaputtes Übersetzungs-Token — bitte reparieren' },
};
export default function PlaceholderText({ text }) {
const segs = parsePlaceholderSegments(text);
return (
<>
{segs.map((s, i) => {
const style = s.kind && KIND_STYLES[s.kind];
if (!style) return <span key={i}>{s.text}</span>;
return (
<mark key={i} className={style.className}
title={`${style.title}${s.id ? ` · ${s.id.slice(0, 8)}` : ''}`}>
{s.text}
</mark>
);
})}
</>
);
}