feat: BL-07–BL-10 — notes search, weather refresh, vCard import/export, PWA offline page

- Notes: client-side full-text search bar (filters title + content)
- Dashboard: weather refresh button + 30-min auto-refresh interval
- Contacts: vCard 3.0 export per contact (GET /:id/vcard); vCard import
  via file input with client-side parser (FN, TEL, EMAIL, ADR, NOTE, CATEGORIES)
- PWA: /offline.html served when network unavailable; cached in app-shell (sw v20)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Ulas
2026-03-31 10:35:03 +02:00
parent 0defc3c589
commit 4fe4f6cb38
10 changed files with 374 additions and 10 deletions
+104
View File
@@ -0,0 +1,104 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Keine Verbindung Oikos</title>
<style>
:root {
--color-bg: #1a1a2e;
--color-surface: #16213e;
--color-accent: #4A90D9;
--color-text: #e8e8f0;
--color-text-secondary: #8888a4;
--color-border: rgba(255,255,255,0.08);
--radius: 12px;
}
@media (prefers-color-scheme: light) {
:root {
--color-bg: #f5f5f7;
--color-surface: #ffffff;
--color-text: #1c1c1e;
--color-text-secondary: #6e6e80;
--color-border: rgba(0,0,0,0.1);
}
}
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html, body {
height: 100%;
background: var(--color-bg);
color: var(--color-text);
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
}
body {
display: flex;
align-items: center;
justify-content: center;
padding: 24px;
}
.card {
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: var(--radius);
padding: 40px 32px;
max-width: 360px;
width: 100%;
text-align: center;
}
.icon {
width: 64px;
height: 64px;
margin: 0 auto 24px;
color: var(--color-text-secondary);
}
h1 {
font-size: 20px;
font-weight: 600;
margin-bottom: 8px;
}
p {
font-size: 14px;
color: var(--color-text-secondary);
line-height: 1.6;
margin-bottom: 28px;
}
button {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 10px 24px;
background: var(--color-accent);
color: #fff;
border: none;
border-radius: var(--radius);
font-size: 15px;
font-weight: 500;
cursor: pointer;
transition: opacity 0.15s;
}
button:hover { opacity: 0.85; }
</style>
</head>
<body>
<div class="card">
<svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true">
<line x1="1" y1="1" x2="23" y2="23"/>
<path d="M16.72 11.06A10.94 10.94 0 0 1 19 12.55"/>
<path d="M5 12.55a10.94 10.94 0 0 1 5.17-2.39"/>
<path d="M10.71 5.05A16 16 0 0 1 22.56 9"/>
<path d="M1.42 9a15.91 15.91 0 0 1 4.7-2.88"/>
<path d="M8.53 16.11a6 6 0 0 1 6.95 0"/>
<line x1="12" y1="20" x2="12.01" y2="20"/>
</svg>
<h1>Keine Verbindung</h1>
<p>Oikos ist gerade nicht erreichbar. Bitte prüfe deine Internetverbindung und versuche es erneut.</p>
<button onclick="location.reload()">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<polyline points="23 4 23 10 17 10"/>
<path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10"/>
</svg>
Erneut versuchen
</button>
</div>
</body>
</html>