Sprint 13: WebCal-Abo / Kalender-Integration
- GET /api/webcal/token: erzeugt personl. Kalender-Token (einmalig)
- GET /api/webcal/{token}.ics: iCal-Feed mit Health-Erinnerungen,
eigenen Events, Gassi-Treffen (erstellt + beigetreten), angenommenen Sittings
- RRULE für wiederkehrende Health-Einträge (intervall_tage)
- Migration: users.calendar_token (TEXT UNIQUE)
- Settings: "Kalender abonnieren" öffnet webcal://-Link + Kopier-Button
- api.js: API.webcal.getToken() / resetToken()
- SW-Cache: by-v104, APP_VER: 80
This commit is contained in:
parent
b58789373c
commit
a4f74b6c64
8 changed files with 362 additions and 8 deletions
|
|
@ -78,6 +78,12 @@ window.Page_settings = (() => {
|
|||
<span>Push-Benachrichtigungen</span>
|
||||
<span style="margin-left:auto;color:var(--c-text-secondary)">›</span>
|
||||
</div>
|
||||
<div class="sidebar-item" id="settings-calendar-btn"
|
||||
style="padding:var(--space-4);border-radius:0;border-bottom:1px solid var(--c-border)">
|
||||
<svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#calendar-dots"></use></svg>
|
||||
<span>Kalender abonnieren</span>
|
||||
<span style="margin-left:auto;color:var(--c-text-secondary)">›</span>
|
||||
</div>
|
||||
<div class="sidebar-item" id="settings-logout-btn"
|
||||
style="padding:var(--space-4);border-radius:0;cursor:pointer;
|
||||
color:var(--c-danger)">
|
||||
|
|
@ -171,6 +177,52 @@ window.Page_settings = (() => {
|
|||
}
|
||||
});
|
||||
|
||||
document.getElementById('settings-calendar-btn')?.addEventListener('click', async () => {
|
||||
try {
|
||||
const { token } = await API.webcal.getToken();
|
||||
const url = `webcal://${location.host}/api/webcal/${token}.ics`;
|
||||
const httpsUrl = `https://${location.host}/api/webcal/${token}.ics`;
|
||||
UI.modal.open({
|
||||
title: `${UI.icon('calendar-dots')} Kalender abonnieren`,
|
||||
body: `
|
||||
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);margin-bottom:var(--space-4)">
|
||||
Abonniere deinen persönlichen Ban-Yaro-Kalender. Er enthält Impf-Erinnerungen,
|
||||
Läufigkeits-Termine, Events und Gassi-Treffen — immer aktuell.
|
||||
</p>
|
||||
<div style="background:var(--c-bg);border-radius:var(--radius-md);
|
||||
padding:var(--space-3) var(--space-4);
|
||||
font-size:var(--text-xs);color:var(--c-text-secondary);
|
||||
word-break:break-all;margin-bottom:var(--space-4)">
|
||||
${UI.escHtml(httpsUrl)}
|
||||
</div>
|
||||
<div style="display:flex;flex-direction:column;gap:var(--space-2)">
|
||||
<a href="${UI.escHtml(url)}"
|
||||
class="btn btn-primary"
|
||||
style="text-align:center">
|
||||
${UI.icon('calendar-dots')} In Kalender-App öffnen
|
||||
</a>
|
||||
<button class="btn btn-secondary" id="cal-copy-btn">
|
||||
${UI.icon('clipboard-text')} URL kopieren
|
||||
</button>
|
||||
</div>
|
||||
<p style="font-size:var(--text-xs);color:var(--c-text-muted);margin-top:var(--space-4)">
|
||||
Tipp: iOS → Einstellungen › Kalender › Accounts › Account hinzufügen › Andere › Kalenderabo
|
||||
</p>
|
||||
`,
|
||||
});
|
||||
document.getElementById('cal-copy-btn')?.addEventListener('click', async () => {
|
||||
try {
|
||||
await navigator.clipboard.writeText(httpsUrl);
|
||||
UI.toast.success('URL kopiert.');
|
||||
} catch {
|
||||
UI.toast.warning('Kopieren nicht möglich — URL oben manuell kopieren.');
|
||||
}
|
||||
});
|
||||
} catch {
|
||||
UI.toast.error('Kalender-Token konnte nicht geladen werden.');
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('toggle-pocket-mode')?.addEventListener('change', e => {
|
||||
localStorage.setItem('by_pocket_mode', String(e.target.checked));
|
||||
UI.toast.info(e.target.checked
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue