Fix Kalender-Suche: Sync-Fehler sichtbar, force-sync beim Kalender-Refresh, Backdrop opak

This commit is contained in:
2026-06-05 16:45:47 +02:00
parent 197ea6fbff
commit ca55ecbf5f
3 changed files with 24 additions and 13 deletions

View File

@@ -71,12 +71,6 @@ router.post('/sync-calendar', authenticate, async (req, res) => {
} }
} }
const ins = db.prepare(`
INSERT INTO calendar_event_cache
(feed_id, user_id, summary, description, location, start_dt, end_dt, synced_at)
VALUES (?,?,?,?,?,?,?,datetime('now','localtime'))
`);
let totalSynced = 0; let totalSynced = 0;
const errors = []; const errors = [];
@@ -85,16 +79,27 @@ router.post('/sync-calendar', authenticate, async (req, res) => {
const raw = await fetchIcal(feed.url); const raw = await fetchIcal(feed.url);
if (!raw) { errors.push(`${feed.name}: kein gültiger iCal-Feed`); continue; } if (!raw) { errors.push(`${feed.name}: kein gültiger iCal-Feed`); continue; }
const events = parseIcal(raw); const events = parseIcal(raw);
if (!events.length) { errors.push(`${feed.name}: 0 Events geparst`); continue; }
// prepare INSIDE try-catch wirft wenn Tabelle nicht existiert
const ins = db.prepare(`
INSERT INTO calendar_event_cache
(feed_id, user_id, summary, description, location, start_dt, end_dt, synced_at)
VALUES (?,?,?,?,?,?,?,datetime('now','localtime'))
`);
db.transaction(() => { db.transaction(() => {
db.prepare('DELETE FROM calendar_event_cache WHERE feed_id=?').run(feed.id); db.prepare('DELETE FROM calendar_event_cache WHERE feed_id=?').run(feed.id);
events.slice(0, 300).forEach(ev => events.slice(0, 300).forEach(ev =>
ins.run(feed.id, uid, ev.summary, ev.description, ev.location, ev.start, ev.end) ins.run(feed.id, uid, ev.summary||'', ev.description||'', ev.location||'', ev.start||'', ev.end||'')
); );
})(); })();
totalSynced += events.length; totalSynced += events.length;
} catch(e) { errors.push(`${feed.name}: ${e.message}`); } } catch(e) {
console.error(`[CalendarSync] Feed "${feed.name}" (${feed.url}): ${e.message}`);
errors.push(`${feed.name}: ${e.message}`);
}
} }
console.log(`[CalendarSync] uid=${uid} synced=${totalSynced} feeds=${feeds.length} errors=${errors.length}`);
res.json({ ok: true, synced: totalSynced, feeds: feeds.length, errors }); res.json({ ok: true, synced: totalSynced, feeds: feeds.length, errors });
}); });

View File

@@ -1859,9 +1859,9 @@ function GlobalSearch({ setActive, setDevToolsNav, mobile }) {
</div> </div>
)} )}
{/* Backdrop zum Schließen */} {/* Backdrop zum Schließen leicht opak damit Dashboard nicht durchscheint */}
{showDropdown && ( {showDropdown && (
<div style={{position:'fixed',inset:0,zIndex:8999}} onClick={close}/> <div style={{position:'fixed',inset:0,zIndex:8999,background:'rgba(0,0,0,0.25)'}} onClick={close}/>
)} )}
</div> </div>
); );
@@ -1875,7 +1875,9 @@ function Dashboard({ toast, mobile, setActive, setDevToolsNav, unreadMsgs=0, unr
useEffect(() => { const t = setInterval(() => setNow(new Date()), 30000); return () => clearInterval(t); }, []); useEffect(() => { const t = setInterval(() => setNow(new Date()), 30000); return () => clearInterval(t); }, []);
// Kalender-Events im Hintergrund für die Suche cachen // Kalender-Events im Hintergrund für die Suche cachen
useEffect(() => { useEffect(() => {
api('/search/sync-calendar', { method:'POST', body:{} }).catch(()=>{}); api('/search/sync-calendar', { method:'POST', body:{} })
.then(r => { if (r.errors?.length) console.warn('[CalendarSync]', r); })
.catch(e => console.error('[CalendarSync] Fehler:', e));
}, []); }, []);
return ( return (
<div style={{ padding: mobile ? '14px 12px 90px' : '36px 44px', maxWidth:1100 }}> <div style={{ padding: mobile ? '14px 12px 90px' : '36px 44px', maxWidth:1100 }}>

View File

@@ -121,7 +121,11 @@ export default function CalendarWidget() {
setLoading(false); setLoading(false);
}; };
const refresh = () => { api('/calendar/feeds').then(f=>{ setFeeds(f); loadFeeds(f); }).catch(()=>{}); }; const refresh = () => {
api('/calendar/feeds').then(f=>{ setFeeds(f); loadFeeds(f); }).catch(()=>{});
// Kalender-Cache für Suche mitsynchronisieren
api('/search/sync-calendar', { method:'POST', body:{ force:true } }).catch(()=>{});
};
// Load on mount so next event shows without opening // Load on mount so next event shows without opening
useEffect(() => { refresh(); }, []); useEffect(() => { refresh(); }, []);
// Reload when opened // Reload when opened
@@ -172,7 +176,7 @@ export default function CalendarWidget() {
<span style={{ color:'rgba(255,255,255,0.35)', fontFamily:'monospace', fontSize:9, flexShrink:0 }}> <span style={{ color:'rgba(255,255,255,0.35)', fontFamily:'monospace', fontSize:9, flexShrink:0 }}>
{nextEvent.allDay {nextEvent.allDay
? nextEvent.dtstart.toLocaleDateString('de-DE',{day:'numeric',month:'short'}) ? nextEvent.dtstart.toLocaleDateString('de-DE',{day:'numeric',month:'short'})
: `${nextEvent.dtstart.toLocaleDateString('de-DE',{day:'2-digit',month:'2-digit'})} ${nextEvent.dtstart.toLocaleTimeString('de-DE',{hour:'2-digit',minute:'2-digit'})}` : nextEvent.dtstart.toLocaleTimeString('de-DE',{hour:'2-digit',minute:'2-digit'})
} }
</span> </span>
</div> </div>