Code-Schnipsel: History-Button Fix, Tag-Split nur Komma, Tag-Vorschläge

This commit is contained in:
2026-05-29 13:34:22 +02:00
parent 449a0aa2f7
commit fa1562bdce

View File

@@ -258,7 +258,9 @@ function SnippetCard({ snippet, onEdit, onDelete, onShare, onHistory, toast }) {
</div> </div>
<div style={{display:'flex',gap:5,flexWrap:'wrap'}}> <div style={{display:'flex',gap:5,flexWrap:'wrap'}}>
<button onClick={()=>onHistory(snippet)} <button onClick={()=>onHistory(snippet)}
style={{...S.btn('rgba(255,255,255,0.3)',true),fontSize:10,padding:'4px 8px'}}>📜</button> style={{background:'rgba(255,255,255,0.07)',border:'1px solid rgba(255,255,255,0.12)',
borderRadius:6,color:'rgba(255,255,255,0.5)',cursor:'pointer',
fontSize:10,padding:'4px 8px'}}>📜</button>
{!snippet.is_shared && ( {!snippet.is_shared && (
<> <>
<button onClick={()=>onShare(snippet)} <button onClick={()=>onShare(snippet)}
@@ -278,29 +280,39 @@ function SnippetCard({ snippet, onEdit, onDelete, onShare, onHistory, toast }) {
} }
// ── Snippet Form ────────────────────────────────────────────────────────────── // ── Snippet Form ──────────────────────────────────────────────────────────────
function SnippetForm({ initial, onSave, onCancel, toast }) { function SnippetForm({ initial, onSave, onCancel, toast, existingTags=[] }) {
const ALL_LANGS = ['text',...LANG_PATTERNS.map(l=>l.lang)]; const ALL_LANGS = ['text',...LANG_PATTERNS.map(l=>l.lang)];
const [title, setTitle] = useState(initial?.title || ''); const [title, setTitle] = useState(initial?.title || '');
const [code, setCode] = useState(initial?.code || ''); const [code, setCode] = useState(initial?.code || '');
const [lang, setLang] = useState(initial?.language || 'text'); const [lang, setLang] = useState(initial?.language || 'text');
const [desc, setDesc] = useState(initial?.description || ''); const [desc, setDesc] = useState(initial?.description || '');
const [tags, setTags] = useState(initial?.tags?.join(', ') || ''); const [tags, setTags] = useState(initial?.tags?.filter(t=>t!==initial?.language).join(', ') || '');
const [busy, setBusy] = useState(false); const [busy, setBusy] = useState(false);
const [autoLang,setAutoLang]= useState(true); const [autoLang,setAutoLang]= useState(!initial?.id);
// Auto-detect language as user types code
useEffect(()=>{ useEffect(()=>{
if (!autoLang) return; if (!autoLang) return;
const detected = detectLanguage(code); const detected = detectLanguage(code);
setLang(detected); setLang(detected);
},[code, autoLang]); },[code, autoLang]);
// Nur Komma als Trennzeichen
const parseTags = () => { const parseTags = () => {
const langTag = lang !== 'text' ? [lang] : []; const langTag = lang !== 'text' ? [lang] : [];
const manual = tags.split(/[,\s]+/).map(t=>t.trim().toLowerCase()).filter(Boolean); const manual = tags.split(',').map(t=>t.trim().toLowerCase()).filter(Boolean);
return [...new Set([...langTag, ...manual])]; return [...new Set([...langTag, ...manual])];
}; };
const addSuggestedTag = tag => {
const cur = tags.split(',').map(t=>t.trim()).filter(Boolean);
if (cur.includes(tag)) return;
setTags(cur.length ? cur.join(', ') + ', ' + tag : tag);
};
// Tags die noch nicht eingetragen sind als Vorschläge
const currentParsed = parseTags();
const suggestions = existingTags.filter(t => t !== lang && !currentParsed.includes(t));
const save = async () => { const save = async () => {
if (!title.trim()) { toast('Titel erforderlich','error'); return; } if (!title.trim()) { toast('Titel erforderlich','error'); return; }
setBusy(true); setBusy(true);
@@ -348,6 +360,21 @@ function SnippetForm({ initial, onSave, onCancel, toast }) {
<label style={{...S.head,display:'block',marginBottom:4,fontSize:9}}>WEITERE TAGS (kommagetrennt)</label> <label style={{...S.head,display:'block',marginBottom:4,fontSize:9}}>WEITERE TAGS (kommagetrennt)</label>
<input value={tags} onChange={e=>setTags(e.target.value)} placeholder="z.B. api, auth, utils" <input value={tags} onChange={e=>setTags(e.target.value)} placeholder="z.B. api, auth, utils"
autoCapitalize="none" style={{...S.inp,fontSize:12}}/> autoCapitalize="none" style={{...S.inp,fontSize:12}}/>
{/* Vorhandene Tags als Vorschläge */}
{suggestions.length>0 && (
<div style={{marginTop:6}}>
<div style={{color:'rgba(255,255,255,0.25)',fontFamily:'monospace',fontSize:8,marginBottom:4}}>VORHANDENE TAGS HINZUFÜGEN:</div>
<div style={{display:'flex',gap:4,flexWrap:'wrap'}}>
{suggestions.map(t=>(
<button key={t} onClick={()=>addSuggestedTag(t)} style={{
fontSize:9,fontFamily:'monospace',padding:'2px 8px',borderRadius:12,cursor:'pointer',
background:'rgba(255,255,255,0.04)',border:'1px solid rgba(255,255,255,0.1)',
color:'rgba(255,255,255,0.4)',
}}>+ {t}</button>
))}
</div>
</div>
)}
{parseTags().length>0&&( {parseTags().length>0&&(
<div style={{display:'flex',gap:4,flexWrap:'wrap',marginTop:6}}> <div style={{display:'flex',gap:4,flexWrap:'wrap',marginTop:6}}>
{parseTags().map(t=>( {parseTags().map(t=>(
@@ -463,6 +490,7 @@ export default function CodeSchnipsel({ toast, mobile }) {
onSave={handleSave} onSave={handleSave}
onCancel={()=>{ setShowForm(false); setEditItem(null); }} onCancel={()=>{ setShowForm(false); setEditItem(null); }}
toast={toast} toast={toast}
existingTags={allTags}
/> />
)} )}