Feature: Welten-Onboarding, Wetter-Motivation, UX-Fixes (SW by-v715)
Welten (worlds.js): - Swipe-Hints beim ersten Öffnen (JETZT ← → WELT animiert, einmalig) - Kein-Hund-Onboarding: Feature-Preview-Grid statt leerer Karte - Hintergrund-Foto-Hint: Kamera-Karte wenn noch kein Tagebuchfoto - worlds-back: navigiert zu Welcome wenn kein User eingeloggt - Nach Logout: worlds-back Button sofort ausgeblendet Wetter (wetter.js): - Standort-Fehlerseite zu Motivations-Seite umgebaut - Feature-Preview: Gassi-Score, 7-Tage, Regenradar, Rekorde - CTA: Standort freigeben + Registrieren (nur für Gäste) Settings (settings.js): - Logo in Auth-Form: display:block + margin:0 auto zentriert - Header bleibt sichtbar (FAB/Zurück-Navigation funktioniert) Jobs (jobs.js): - 2-Spalten-Grid auf Mobile: auto-fit statt festes 1fr 1fr - Kein doppeltes Padding im Wrapper Backend: - weather.py, achievements.py: diary JOIN fix (d.user_id → dogs JOIN) - Neue Wetter-Badges: wetter_tapfer, jahreszeiten, schnee - Ernährungs-, Reise-, Ausgaben-Seite: diverse UX-Verbesserungen - Presse-Seite erweitert - Ban Yaro Foto-Assets (WebP + HIRES JPG)
This commit is contained in:
parent
aa4849d947
commit
55069d246b
28 changed files with 719 additions and 198 deletions
|
|
@ -112,22 +112,82 @@ window.Page_wetter = (() => {
|
|||
function _showLocationError() {
|
||||
const body = _container.querySelector('#wttr-body');
|
||||
if (!body) return;
|
||||
const isLoggedIn = !!_appState?.user;
|
||||
|
||||
body.innerHTML = `
|
||||
<div style="text-align:center;padding:var(--space-10) var(--space-4)">
|
||||
<div style="font-size:2.5rem;margin-bottom:var(--space-3)">📍</div>
|
||||
<h3 style="margin-bottom:var(--space-2)">Standort nicht verfügbar</h3>
|
||||
<p style="color:var(--c-text-secondary);margin-bottom:var(--space-5);max-width:300px;margin-inline:auto">
|
||||
Bitte erlaube den Zugriff auf deinen Standort, um die Wettervorhersage zu laden.
|
||||
</p>
|
||||
<button class="btn btn-primary" id="wttr-btn-retry">
|
||||
${UI.icon('map-pin')} Nochmal versuchen
|
||||
</button>
|
||||
<div style="max-width:420px;margin:0 auto;padding:var(--space-6) var(--space-4)">
|
||||
|
||||
<!-- Hero -->
|
||||
<div style="text-align:center;margin-bottom:var(--space-6)">
|
||||
<div style="font-size:4rem;line-height:1;margin-bottom:var(--space-2)">🌤️🐾</div>
|
||||
<h2 style="font-size:var(--text-xl);font-weight:800;margin:0 0 var(--space-2)">
|
||||
Das Gassi-Wetter wartet auf dich
|
||||
</h2>
|
||||
<p style="color:var(--c-text-secondary);font-size:var(--text-sm);margin:0">
|
||||
Erfahre sekundengenau, ob gerade der perfekte Moment für eine Runde ist —
|
||||
zugeschnitten auf dich und deinen Hund.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Feature-Liste -->
|
||||
<div style="display:flex;flex-direction:column;gap:var(--space-3);margin-bottom:var(--space-6)">
|
||||
${[
|
||||
['sun', '#F59E0B', 'Gassi-Score 1–10', 'Wetter bewertet nach Temperatur, Regen und Wind'],
|
||||
['thermometer', '#3B82F6', '7-Tage-Vorschau', 'Plane deine Runden für die ganze Woche voraus'],
|
||||
['drop', '#06B6D4', 'Regenradar stündlich', '24h-Niederschlagstimeline auf einen Blick'],
|
||||
['trophy', '#10B981', 'Wetter-Rekorde', 'Wärmster, nassester und stürmischster Gassi-Tag'],
|
||||
].map(([icon, color, title, sub]) => `
|
||||
<div style="display:flex;align-items:center;gap:var(--space-3);
|
||||
background:var(--c-bg-card);border:1px solid var(--c-border);
|
||||
border-radius:var(--radius-lg);padding:var(--space-3) var(--space-4)">
|
||||
<div style="width:38px;height:38px;border-radius:var(--radius-md);
|
||||
background:${color}18;display:flex;align-items:center;
|
||||
justify-content:center;flex-shrink:0">
|
||||
<svg class="ph-icon" style="width:1.1rem;height:1.1rem;color:${color}">
|
||||
<use href="/icons/phosphor.svg#${icon}"></use>
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<div style="font-weight:700;font-size:var(--text-sm)">${title}</div>
|
||||
<div style="color:var(--c-text-secondary);font-size:var(--text-xs)">${sub}</div>
|
||||
</div>
|
||||
</div>
|
||||
`).join('')}
|
||||
</div>
|
||||
|
||||
<!-- CTAs -->
|
||||
<div style="display:flex;flex-direction:column;gap:var(--space-3)">
|
||||
<button class="btn btn-primary" id="wttr-btn-retry"
|
||||
style="display:flex;align-items:center;justify-content:center;gap:var(--space-2)">
|
||||
<svg class="ph-icon" style="width:1rem;height:1rem">
|
||||
<use href="/icons/phosphor.svg#map-pin"></use>
|
||||
</svg>
|
||||
Standort freigeben & loslegen
|
||||
</button>
|
||||
${!isLoggedIn ? `
|
||||
<button class="btn btn-secondary" id="wttr-btn-login"
|
||||
style="display:flex;align-items:center;justify-content:center;gap:var(--space-2)">
|
||||
<svg class="ph-icon" style="width:1rem;height:1rem">
|
||||
<use href="/icons/phosphor.svg#user"></use>
|
||||
</svg>
|
||||
Kostenlos registrieren
|
||||
</button>
|
||||
<p style="text-align:center;font-size:var(--text-xs);color:var(--c-text-secondary);margin:0">
|
||||
Mit Account werden Rekorde & Gassi-Score für deinen Hund gespeichert.
|
||||
</p>
|
||||
` : ''}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
`;
|
||||
|
||||
body.querySelector('#wttr-btn-retry')?.addEventListener('click', () => {
|
||||
_renderShell();
|
||||
_tryAutoLocate();
|
||||
});
|
||||
body.querySelector('#wttr-btn-login')?.addEventListener('click', () => {
|
||||
if (window.App) App.navigate('settings');
|
||||
});
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------
|
||||
|
|
@ -1007,19 +1067,21 @@ window.Page_wetter = (() => {
|
|||
|
||||
function _recordCard(emoji, title, value, subtitle, color) {
|
||||
return `
|
||||
<div style="background:var(--c-bg-card);border:1px solid var(--c-border);
|
||||
border-radius:var(--radius);padding:var(--space-3) var(--space-3);
|
||||
display:flex;flex-direction:column;gap:2px">
|
||||
<div style="font-size:var(--text-xs);color:var(--c-text-secondary);
|
||||
display:flex;align-items:center;gap:4px;font-weight:600">
|
||||
<div style="background:${color}10;border:1px solid ${color}33;
|
||||
border-radius:var(--radius);padding:var(--space-3);
|
||||
display:flex;flex-direction:column;gap:3px">
|
||||
<div style="font-size:10px;color:var(--c-text-secondary);
|
||||
display:flex;align-items:center;gap:3px;font-weight:700;
|
||||
text-transform:uppercase;letter-spacing:.04em">
|
||||
<span>${emoji}</span>
|
||||
<span>${_esc(title)}</span>
|
||||
</div>
|
||||
<div style="font-size:var(--text-xl);font-weight:800;color:${color};line-height:1.1">
|
||||
<div style="font-size:var(--text-lg);font-weight:800;color:${color};line-height:1.1">
|
||||
${_esc(value)}
|
||||
</div>
|
||||
<div style="font-size:var(--text-xs);color:var(--c-text-secondary);
|
||||
white-space:nowrap;overflow:hidden;text-overflow:ellipsis">
|
||||
<div style="font-size:10px;color:var(--c-text-secondary);
|
||||
overflow:hidden;display:-webkit-box;
|
||||
-webkit-line-clamp:2;-webkit-box-orient:vertical;line-height:1.3">
|
||||
${_esc(subtitle)}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue