diff --git a/backend/src/routes/search.js b/backend/src/routes/search.js index 8567e6a..dc0c25c 100644 --- a/backend/src/routes/search.js +++ b/backend/src/routes/search.js @@ -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; const errors = []; @@ -85,16 +79,27 @@ router.post('/sync-calendar', authenticate, async (req, res) => { const raw = await fetchIcal(feed.url); if (!raw) { errors.push(`${feed.name}: kein gültiger iCal-Feed`); continue; } 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.prepare('DELETE FROM calendar_event_cache WHERE feed_id=?').run(feed.id); 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; - } 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 }); }); diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 260e887..c05e611 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -1859,9 +1859,9 @@ function GlobalSearch({ setActive, setDevToolsNav, mobile }) { )} - {/* Backdrop zum Schließen */} + {/* Backdrop zum Schließen – leicht opak damit Dashboard nicht durchscheint */} {showDropdown && ( -
+
)}
); @@ -1875,7 +1875,9 @@ function Dashboard({ toast, mobile, setActive, setDevToolsNav, unreadMsgs=0, unr useEffect(() => { const t = setInterval(() => setNow(new Date()), 30000); return () => clearInterval(t); }, []); // Kalender-Events im Hintergrund für die Suche cachen 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 (
diff --git a/frontend/src/calendar.jsx b/frontend/src/calendar.jsx index 9cfb011..2cd5064 100644 --- a/frontend/src/calendar.jsx +++ b/frontend/src/calendar.jsx @@ -121,7 +121,11 @@ export default function CalendarWidget() { 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 useEffect(() => { refresh(); }, []); // Reload when opened @@ -172,7 +176,7 @@ export default function CalendarWidget() { {nextEvent.allDay ? 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'}) }