Add PWA reminders and flexible walk scoring
This commit is contained in:
+32
-2
@@ -6,7 +6,7 @@ $brandSubtitle = match ($page) {
|
||||
'dashboard' => 'Statistiken und Verlauf',
|
||||
'track' => 'Tag erfassen und bewerten',
|
||||
'archive' => 'Rückblick auf vergangene Tage',
|
||||
'options' => 'Logik, Sicherheit und Accounts',
|
||||
'options' => 'Logik, Erinnerungen, Sicherheit und Accounts',
|
||||
'login' => 'Geschützter Zugang',
|
||||
'setup' => 'Erstkonfiguration',
|
||||
default => 'Stimmungstracker',
|
||||
@@ -19,13 +19,22 @@ $brandSubtitle = match ($page) {
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#0b1e2e">
|
||||
<meta name="robots" content="noindex, nofollow, noarchive, nosnippet">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||
<meta name="apple-mobile-web-app-title" content="Mood-Board">
|
||||
<meta name="csrf-token" content="<?= e(csrf_token()) ?>">
|
||||
<?php if (!empty($pushPublicKey)): ?>
|
||||
<meta name="mood-push-public-key" content="<?= e((string) $pushPublicKey) ?>">
|
||||
<?php endif; ?>
|
||||
<title><?= e($pageTitle) ?> · Mood</title>
|
||||
<link rel="icon" type="image/svg+xml" href="/assets/branding/favicon.svg">
|
||||
<link rel="shortcut icon" href="/assets/branding/favicon.svg">
|
||||
<link rel="apple-touch-icon" href="/assets/branding/apple-touch-icon.svg">
|
||||
<link rel="manifest" href="/manifest.webmanifest">
|
||||
<link rel="stylesheet" href="/assets/css/app.css">
|
||||
<script defer src="/assets/js/app.js"></script>
|
||||
</head>
|
||||
<body class="app-body page-<?= e($page) ?>"<?= isset($trackMood) ? ' data-track-mood="' . e($trackMood) . '"' : '' ?>>
|
||||
<body class="app-body page-<?= e($page) ?><?= $authUser !== null ? ' is-authenticated' : '' ?>" data-authenticated="<?= $authUser !== null ? '1' : '0' ?>"<?= isset($trackMood) ? ' data-track-mood="' . e($trackMood) . '"' : '' ?>>
|
||||
<div class="aurora aurora-one"></div>
|
||||
<div class="aurora aurora-two"></div>
|
||||
<div class="shell">
|
||||
@@ -101,6 +110,27 @@ $brandSubtitle = match ($page) {
|
||||
|
||||
<?= $content ?>
|
||||
</main>
|
||||
|
||||
<?php if ($authUser !== null): ?>
|
||||
<nav class="mobile-nav glass-panel" aria-label="Mobile Hauptnavigation">
|
||||
<a class="<?= is_active_path('/') ? 'active' : '' ?>" href="/">
|
||||
<img class="nav-icon" src="<?= e(icon_path('dashboard')) ?>" alt="">
|
||||
<span>Dashboard</span>
|
||||
</a>
|
||||
<a class="<?= is_active_path('/track') ? 'active' : '' ?>" href="/track">
|
||||
<img class="nav-icon" src="<?= e(icon_path('track')) ?>" alt="">
|
||||
<span>Tracken</span>
|
||||
</a>
|
||||
<a class="<?= is_active_path('/archive') ? 'active' : '' ?>" href="/archive">
|
||||
<img class="nav-icon" src="<?= e(icon_path('archive')) ?>" alt="">
|
||||
<span>Archiv</span>
|
||||
</a>
|
||||
<a class="<?= is_active_path('/options') ? 'active' : '' ?>" href="/options">
|
||||
<img class="nav-icon" src="<?= e(icon_path('options')) ?>" alt="">
|
||||
<span>Optionen</span>
|
||||
</a>
|
||||
</nav>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
</dd>
|
||||
</div>
|
||||
<div><dt>Sportbonus</dt><dd><?= e(format_points((float) ($selectedEntry['evaluation']['components']['sport_bonus'] ?? 0))) ?></dd></div>
|
||||
<div><dt>Spaziergang</dt><dd><?= e((string) $selectedEntry['walk_minutes']) ?> min</dd></div>
|
||||
<div><dt>Spaziergang</dt><dd><?= e(format_walk_value($selectedEntry)) ?></dd></div>
|
||||
</dl>
|
||||
|
||||
<div class="note-box">
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
<p class="eyebrow">Aktivität</p>
|
||||
<h3>Sport und Spaziergang</h3>
|
||||
</div>
|
||||
<span class="chart-chip chart-chip--cool">Minuten pro Tag</span>
|
||||
<span class="chart-chip chart-chip--cool">Aktivität pro Tag</span>
|
||||
</div>
|
||||
<div class="bar-chart" data-chart-type="bars" data-series="sport" data-payload="<?= e($chartPayload) ?>"></div>
|
||||
</article>
|
||||
|
||||
@@ -49,16 +49,39 @@
|
||||
</div>
|
||||
|
||||
<div class="settings-section">
|
||||
<h4>Spaziergang-Bänder</h4>
|
||||
<div class="band-grid">
|
||||
<?php foreach ($settings['scoring']['walk_bands'] as $index => $band): ?>
|
||||
<div class="band-card">
|
||||
<label><span>Min</span><input type="number" name="settings[scoring][walk_bands][<?= e((string) $index) ?>][min]" value="<?= e((string) $band['min']) ?>"></label>
|
||||
<label><span>Max</span><input type="number" name="settings[scoring][walk_bands][<?= e((string) $index) ?>][max]" value="<?= e((string) $band['max']) ?>"></label>
|
||||
<label><span>Punkte</span><input type="number" name="settings[scoring][walk_bands][<?= e((string) $index) ?>][points]" value="<?= e((string) $band['points']) ?>"></label>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<div class="section-head section-head--compact">
|
||||
<div>
|
||||
<h4>Spaziergang</h4>
|
||||
<p class="helper-text">Du kannst Spaziergänge pro Account entweder über Zeit oder über Schritte bewerten lassen.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label>
|
||||
<span>Spaziergang auswerten nach</span>
|
||||
<select name="settings[walk][mode]">
|
||||
<?php foreach ($walkModeOptions as $modeValue => $modeLabel): ?>
|
||||
<option value="<?= e($modeValue) ?>" <?= ($settings['walk']['mode'] ?? 'time') === $modeValue ? 'selected' : '' ?>><?= e($modeLabel) ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</label>
|
||||
|
||||
<?php if (($settings['walk']['mode'] ?? 'time') === 'steps'): ?>
|
||||
<div class="band-card">
|
||||
<h5>Schritte mit Bestwert bei 10.000</h5>
|
||||
<p class="helper-text">Bei Schritten liegt der beste Wert bei 10.000. Darunter steigt die Punktzahl schrittweise an, darüber fällt sie wieder sanft ab.</p>
|
||||
<p class="helper-text">Aktueller Verlauf: 0 / 3.000 / 5.000 / 7.500 / 10.000 / 12.500 / 15.000 / 20.000 Schritte</p>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="band-grid">
|
||||
<?php foreach ($settings['scoring']['walk_bands'] as $index => $band): ?>
|
||||
<div class="band-card">
|
||||
<label><span>Min</span><input type="number" name="settings[scoring][walk_bands][<?= e((string) $index) ?>][min]" value="<?= e((string) $band['min']) ?>"></label>
|
||||
<label><span>Max</span><input type="number" name="settings[scoring][walk_bands][<?= e((string) $index) ?>][max]" value="<?= e((string) $band['max']) ?>"></label>
|
||||
<label><span>Punkte</span><input type="number" name="settings[scoring][walk_bands][<?= e((string) $index) ?>][points]" value="<?= e((string) $band['points']) ?>"></label>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="settings-section">
|
||||
@@ -217,6 +240,55 @@
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<div class="settings-section">
|
||||
<div class="section-head section-head--compact">
|
||||
<div>
|
||||
<h4>Erinnerungen</h4>
|
||||
<p class="helper-text">Diese Erinnerungen gelten nur für deinen Account. Auf dem iPhone funktioniert Push nach dem Hinzufügen zum Home-Bildschirm.</p>
|
||||
</div>
|
||||
<span class="chart-chip"><?= e((string) $pushSubscriptionCount) ?> Gerät<?= $pushSubscriptionCount === 1 ? '' : 'e' ?></span>
|
||||
</div>
|
||||
|
||||
<div class="field-grid field-grid--two">
|
||||
<label class="checkbox-row checkbox-row--panel">
|
||||
<input type="checkbox" name="settings[notifications][enabled]" value="1" <?= !empty($settings['notifications']['enabled']) ? 'checked' : '' ?>>
|
||||
<span>Tägliche Push-Erinnerung aktivieren</span>
|
||||
</label>
|
||||
|
||||
<label>
|
||||
<span>Uhrzeit der Erinnerung</span>
|
||||
<input type="time" name="settings[notifications][time]" value="<?= e((string) ($settings['notifications']['time'] ?? '20:30')) ?>">
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="push-panel band-card"
|
||||
data-push-panel
|
||||
data-push-ready="<?= !empty($pushAvailable) && !empty($pushPublicKey) ? '1' : '0' ?>"
|
||||
>
|
||||
<div>
|
||||
<h5>Push auf diesem Gerät</h5>
|
||||
<p class="helper-text" data-push-status>
|
||||
<?php if (!empty($pushAvailable) && !empty($pushPublicKey)): ?>
|
||||
Installiere die App auf Wunsch als PWA und aktiviere dann Push direkt auf diesem Gerät.
|
||||
<?php else: ?>
|
||||
Push ist auf diesem Server gerade noch nicht verfügbar.
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="push-actions">
|
||||
<button class="ghost-button" type="button" data-push-enable <?= empty($pushAvailable) || empty($pushPublicKey) ? 'disabled' : '' ?>>Push aktivieren</button>
|
||||
<button class="ghost-button" type="button" data-push-disable <?= empty($pushAvailable) || empty($pushPublicKey) ? 'disabled' : '' ?>>Auf diesem Gerät entfernen</button>
|
||||
<button class="ghost-button" type="button" data-push-test <?= empty($pushAvailable) || empty($pushPublicKey) ? 'disabled' : '' ?>>Test senden</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section-actions">
|
||||
<button class="primary-button" type="submit">Erinnerungen speichern</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="settings-section">
|
||||
<h4>Bewertungsskala</h4>
|
||||
<p class="helper-text">Diese Score-Grenzen und Schutzregeln gelten ebenfalls nur für deinen eigenen Account.</p>
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
<form method="post" action="/track" class="tracker-form" id="tracker-form" autocomplete="off">
|
||||
<?= csrf_field() ?>
|
||||
<input type="hidden" name="date" value="<?= e($entry['date']) ?>">
|
||||
<?php $walkMode = ($entry['walk_mode'] ?? ($settings['walk']['mode'] ?? 'time')) === 'steps' ? 'steps' : 'time'; ?>
|
||||
<input type="hidden" name="walk_mode" value="<?= e($walkMode) ?>">
|
||||
|
||||
<div class="field-grid field-grid--three">
|
||||
<label class="range-card">
|
||||
@@ -60,8 +62,16 @@
|
||||
</label>
|
||||
|
||||
<label>
|
||||
<span>Spaziergang in Minuten</span>
|
||||
<input type="number" min="0" max="1440" step="1" name="walk_minutes" value="<?= e((string) $entry['walk_minutes']) ?>" required>
|
||||
<span><?= $walkMode === 'steps' ? 'Spaziergang in Schritten' : 'Spaziergang in Minuten' ?></span>
|
||||
<input
|
||||
type="number"
|
||||
min="0"
|
||||
max="<?= $walkMode === 'steps' ? '50000' : '1440' ?>"
|
||||
step="1"
|
||||
name="<?= $walkMode === 'steps' ? 'walk_steps' : 'walk_minutes' ?>"
|
||||
value="<?= e((string) ($walkMode === 'steps' ? ($entry['walk_steps'] ?? 0) : $entry['walk_minutes'])) ?>"
|
||||
required
|
||||
>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user