Devlog-Suche (FTS5) + öffentlicher RSS-Feed
- FTS5-Volltextindex mit Trigger-Sync und einmaligem Backfill bestehender Devlogs - /api/devlogs?q= — Präfix-Suche, injection-sicher (Phrasen-Quoting) - Suchfeld mit Entprellung und Treffer-Zähler auf der Devlog-Seite - /feed.xml — RSS 2.0 der letzten 20 Devlogs (escaped, deutsche Titel) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -44,11 +44,23 @@ export default function Devlogs({ me }) {
|
||||
const [data, setData] = useState(null);
|
||||
const [page, setPage] = useState(1);
|
||||
const [error, setError] = useState(false);
|
||||
const [qInput, setQInput] = useState('');
|
||||
const [q, setQ] = useState('');
|
||||
|
||||
// Sucheingabe entprellen (300 ms), bei neuer Suche zurück auf Seite 1
|
||||
useEffect(() => {
|
||||
const t = setTimeout(() => {
|
||||
setQ(qInput.trim());
|
||||
setPage(1);
|
||||
}, 300);
|
||||
return () => clearTimeout(t);
|
||||
}, [qInput]);
|
||||
|
||||
const load = useCallback(() => {
|
||||
setError(false);
|
||||
apiGet(`/api/devlogs?page=${page}`).then(setData).catch(() => setError(true));
|
||||
}, [page]);
|
||||
const search = q ? `&q=${encodeURIComponent(q)}` : '';
|
||||
apiGet(`/api/devlogs?page=${page}${search}`).then(setData).catch(() => setError(true));
|
||||
}, [page, q]);
|
||||
|
||||
useEffect(() => {
|
||||
load();
|
||||
@@ -86,9 +98,22 @@ export default function Devlogs({ me }) {
|
||||
</section>
|
||||
|
||||
<section className="content">
|
||||
<div className="search">
|
||||
<span className="search-icon">⌕</span>
|
||||
<input
|
||||
type="search"
|
||||
placeholder="Devlogs durchsuchen …"
|
||||
value={qInput}
|
||||
onChange={(e) => setQInput(e.target.value)}
|
||||
/>
|
||||
{q && data && <span className="search-count">{data.total} Treffer</span>}
|
||||
</div>
|
||||
|
||||
{error && <p className="notice">Devlogs konnten nicht geladen werden.</p>}
|
||||
{!error && !data && <p className="notice">Lade …</p>}
|
||||
{data?.total === 0 && <p className="notice">Noch keine Devlogs archiviert.</p>}
|
||||
{data?.total === 0 && (
|
||||
<p className="notice">{q ? `Keine Treffer für „${q}".` : 'Noch keine Devlogs archiviert.'}</p>
|
||||
)}
|
||||
|
||||
{data?.total > 0 && (
|
||||
<div className="timeline">
|
||||
|
||||
Reference in New Issue
Block a user