Refine mobile actions and Putzliga moments

This commit is contained in:
2026-05-22 10:13:09 +02:00
parent 5c4c977e23
commit 49914fcc9a
5 changed files with 40 additions and 17 deletions
+32 -11
View File
@@ -1345,7 +1345,9 @@ body.page-dashboard .content {
.dashboard-fab { .dashboard-fab {
position: fixed; position: fixed;
right: max(1rem, env(safe-area-inset-right)); right: max(1rem, env(safe-area-inset-right));
bottom: calc(1.2rem + env(safe-area-inset-bottom)); top: calc(0.95rem + env(safe-area-inset-top));
bottom: auto;
z-index: 124;
width: 4rem; width: 4rem;
height: 4rem; height: 4rem;
border: 0; border: 0;
@@ -1369,15 +1371,16 @@ body.page-dashboard .content {
.dashboard-fab-menu { .dashboard-fab-menu {
position: fixed; position: fixed;
right: max(1rem, env(safe-area-inset-right)); right: max(1rem, env(safe-area-inset-right));
bottom: calc(5.8rem + env(safe-area-inset-bottom)); top: calc(5.45rem + env(safe-area-inset-top));
z-index: 28; bottom: auto;
z-index: 123;
display: grid; display: grid;
gap: 0.55rem; gap: 0.55rem;
width: min(18rem, calc(100vw - 2rem)); width: min(18rem, calc(100vw - 2rem));
padding: 0.7rem; padding: 0.7rem;
border-radius: 1.6rem; border-radius: 1.6rem;
animation: fabMenuIn 180ms ease both; animation: fabMenuIn 180ms ease both;
transform-origin: right bottom; transform-origin: right top;
} }
.dashboard-fab-menu button { .dashboard-fab-menu button {
@@ -1399,7 +1402,7 @@ body.page-dashboard .content {
} }
@keyframes fabMenuIn { @keyframes fabMenuIn {
from { opacity: 0; transform: translateY(0.6rem) scale(0.94); } from { opacity: 0; transform: translateY(-0.4rem) scale(0.94); }
to { opacity: 1; transform: translateY(0) scale(1); } to { opacity: 1; transform: translateY(0) scale(1); }
} }
@@ -2243,6 +2246,17 @@ body.page-dashboard .content {
border-radius: var(--radius-xl); border-radius: var(--radius-xl);
} }
.options-menu-panel .section-head {
margin-bottom: 1.1rem;
padding: 1.15rem;
border-radius: 1.8rem;
background:
radial-gradient(circle at 20% 0%, rgba(255, 255, 255, 0.18), transparent 52%),
linear-gradient(180deg, rgba(68, 92, 118, 0.38), rgba(20, 38, 58, 0.28));
border: 1px solid rgba(180, 214, 246, 0.16);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12);
}
.options-menu-grid { .options-menu-grid {
display: grid; display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-columns: repeat(2, minmax(0, 1fr));
@@ -2261,15 +2275,18 @@ body.page-dashboard .content {
gap: 0.35rem; gap: 0.35rem;
align-items: flex-start; align-items: flex-start;
width: 100%; width: 100%;
padding: 1.15rem 1.25rem; min-height: 6.7rem;
border-radius: 1.55rem; padding: 1.2rem 1.25rem;
border: 1px solid rgba(152, 194, 232, 0.16); border-radius: 1.75rem;
border: 1px solid rgba(190, 222, 250, 0.18);
background: background:
linear-gradient(180deg, rgba(41, 59, 80, 0.72), rgba(25, 42, 63, 0.6)), radial-gradient(circle at 18% 0%, rgba(255, 255, 255, 0.18), transparent 42%),
radial-gradient(circle at top left, rgba(255, 255, 255, 0.08), transparent 48%); linear-gradient(180deg, rgba(60, 81, 105, 0.52), rgba(24, 41, 62, 0.34));
color: var(--text); color: var(--text);
text-decoration: none; text-decoration: none;
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06); box-shadow: 0 16px 42px rgba(0, 0, 0, 0.16), inset 0 1px 0 rgba(255, 255, 255, 0.12);
backdrop-filter: blur(24px) saturate(1.45);
-webkit-backdrop-filter: blur(24px) saturate(1.45);
} }
.options-menu-card strong { .options-menu-card strong {
@@ -2282,6 +2299,10 @@ body.page-dashboard .content {
text-align: left; text-align: left;
} }
.options-menu-card:active {
transform: scale(0.985);
}
.options-menu-card--danger { .options-menu-card--danger {
background: rgba(255, 130, 130, 0.08); background: rgba(255, 130, 130, 0.08);
border-color: rgba(255, 143, 143, 0.18); border-color: rgba(255, 143, 143, 0.18);
+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 672 672"><!--! Font Awesome Pro 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2025 Fonticons, Inc. --><path opacity=".4" fill="currentColor" d="M112 317.3C112 304.2 112.6 295.5 113.8 289.6C114.8 284.8 115.2 282.9 119.9 281.8C124.7 280.7 132.1 280 144 280L164 280C175.9 280 183.3 280.7 188.1 281.8C192.8 282.9 193.3 284.7 194.2 289.6C195.4 295.5 196 304.2 196 317.3L196 494.6C196 507.7 195.4 516.4 194.2 522.3C193.2 527.1 192.8 529 188.1 530.1C183.3 531.2 175.9 531.9 164 531.9L144 531.9C132.1 531.9 124.7 531.2 119.9 530.1C115.2 529 114.7 527.2 113.8 522.3C112.6 516.4 112 507.7 112 494.6L112 317.3z"/><path fill="currentColor" d="M144 224C120.1 224 92.7 225.7 74.6 245.3C65.5 255.2 61.1 267.1 58.8 278.7C56.5 290.1 55.9 303.2 55.9 317.3L56 494.7C56 508.8 56.6 521.9 58.9 533.3C61.2 544.9 65.6 556.8 74.7 566.7C92.7 586.3 120.2 588 144.1 588L164.1 588C188 588 215.4 586.3 233.5 566.7C242.6 556.8 247 544.9 249.3 533.3C251.6 521.9 252.2 508.8 252.2 494.7L252.2 317.4C252.2 303.3 251.6 290.2 249.3 278.8C247 267.2 242.6 255.3 233.5 245.4C215.5 225.8 188 224.1 164.1 224.1L144.1 224.1zM113.8 289.6C114.8 284.8 115.2 282.9 119.9 281.8C124.7 280.7 132.1 280 144 280L164 280C175.9 280 183.3 280.7 188.1 281.8C192.8 282.9 193.3 284.7 194.2 289.6C195.4 295.5 196 304.2 196 317.3L196 494.6C196 507.7 195.4 516.4 194.2 522.3C193.2 527.1 192.8 529 188.1 530.1C183.3 531.2 175.9 531.9 164 531.9L144 531.9C132.1 531.9 124.7 531.2 119.9 530.1C115.2 529 114.7 527.2 113.8 522.3C112.6 516.4 112 507.7 112 494.6L112 317.3C112 304.2 112.6 295.5 113.8 289.6zM398.6 135C402.2 120.4 413.9 112 423 112C433.5 112 441.4 121.4 439.7 131.7L420.4 247.4C419 255.5 421.3 263.8 426.7 270.1C432.1 276.4 439.8 280 448 280L525.2 280C533.8 280 545.9 282.2 549 291.6C554.3 307.8 560 335.2 560 378C560 432.1 540.8 471.5 526.5 493.4C521.8 500.6 512.8 505.8 500.8 506.6C445.1 510.2 384.7 508.4 330.9 491.4C316.2 486.6 300.4 494.5 295.5 509.1C290.6 523.8 298.5 539.6 313.2 544.5C373.5 564.4 441.9 566.5 504.5 562.5C530.5 560.8 557.3 548.8 573.5 524C592 495.7 616.1 445.8 616.1 378C616.1 330.3 609.8 296.9 602.3 274.1C590.1 237 554.2 224 525.3 224L481.1 224L494.9 140.9C502.3 96.4 468 56 422.9 56C382.3 56 352.4 88.1 344.1 121.7C337 150.6 321.3 192.3 286.4 234.1C276.5 246 278.1 263.6 290 273.5C301.9 283.4 319.5 281.8 329.4 269.9C370.8 220.2 389.8 170.4 398.5 135z"/></svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

+1 -1
View File
@@ -412,7 +412,7 @@ final class App
'id' => $importID, 'id' => $importID,
'type' => 'event', 'type' => 'event',
'time' => (string) ($payload['time'] ?? ''), 'time' => (string) ($payload['time'] ?? ''),
'comment' => 'Du warst fleißig', 'comment' => 'Putzliga',
'value' => 0, 'value' => 0,
'unit' => '', 'unit' => '',
'mood' => 0, 'mood' => 0,
+5 -4
View File
@@ -119,7 +119,7 @@ $formatBalanceValue = static function (?array $entry) use ($settings): string {
<?php $isImportedWalkSport = $isImportedHealth && $eventType === 'sport' && str_contains(strtolower((string) ($sportType['label'] ?? $eventComment)), 'spaziergang'); ?> <?php $isImportedWalkSport = $isImportedHealth && $eventType === 'sport' && str_contains(strtolower((string) ($sportType['label'] ?? $eventComment)), 'spaziergang'); ?>
<?php $eventTone = signal_value_class(normalize_signal_value($item['mood'] ?? 0)); ?> <?php $eventTone = signal_value_class(normalize_signal_value($item['mood'] ?? 0)); ?>
<?php $eventValueText = (float) $item['value'] > 0 ? ($eventType === 'sleep' ? format_duration_hours((float) $item['value']) : rtrim(rtrim(number_format((float) $item['value'], 2, ',', '.'), '0'), ',') . ' ' . (string) $item['unit']) : ''; ?> <?php $eventValueText = (float) $item['value'] > 0 ? ($eventType === 'sleep' ? format_duration_hours((float) $item['value']) : rtrim(rtrim(number_format((float) $item['value'], 2, ',', '.'), '0'), ',') . ' ' . (string) $item['unit']) : ''; ?>
<?php $eventTitle = match ($eventType) { <?php $eventTitle = $isPutzliga ? 'Putzliga' : match ($eventType) {
'sport' => $isImportedWalkSport ? 'Spaziergang' : (string) ($sportType['label'] ?? 'Sport'), 'sport' => $isImportedWalkSport ? 'Spaziergang' : (string) ($sportType['label'] ?? 'Sport'),
'walk' => 'Spaziergang', 'walk' => 'Spaziergang',
'sleep' => 'Schlaf', 'sleep' => 'Schlaf',
@@ -198,7 +198,7 @@ $formatBalanceValue = static function (?array $entry) use ($settings): string {
<span class="timeline-card__time-chip"><?= e($item['time'] !== '' ? $item['time'] : '--:--') ?></span> <span class="timeline-card__time-chip"><?= e($item['time'] !== '' ? $item['time'] : '--:--') ?></span>
<div class="timeline-card__meta"> <div class="timeline-card__meta">
<div class="timeline-card__icon-wrap" title="<?= e(day_event_type_label((string) $item['type'])) ?>"> <div class="timeline-card__icon-wrap" title="<?= e(day_event_type_label((string) $item['type'])) ?>">
<img class="timeline-card__icon" src="<?= e(day_event_type_icon((string) $item['type'])) ?>" alt=""> <img class="timeline-card__icon" src="<?= e($isPutzliga ? icon_path('putzliga') : day_event_type_icon((string) $item['type'])) ?>" alt="">
</div> </div>
<div> <div>
<strong class="timeline-card__time"><?= e($item['time'] !== '' ? $item['time'] : '--:--') ?></strong> <strong class="timeline-card__time"><?= e($item['time'] !== '' ? $item['time'] : '--:--') ?></strong>
@@ -591,11 +591,12 @@ $formatBalanceValue = static function (?array $entry) use ($settings): string {
$sportType = $eventType === 'sport' ? find_sport_type($settings, (string) ($event['sport_type_id'] ?? '')) : null; $sportType = $eventType === 'sport' ? find_sport_type($settings, (string) ($event['sport_type_id'] ?? '')) : null;
$eventValue = (float) ($event['value'] ?? 0); $eventValue = (float) ($event['value'] ?? 0);
$eventValueText = $eventValue > 0 ? ($eventType === 'sleep' ? format_duration_hours($eventValue) : rtrim(rtrim(number_format($eventValue, 2, ',', '.'), '0'), ',') . ' ' . (string) ($event['unit'] ?? '')) : ''; $eventValueText = $eventValue > 0 ? ($eventType === 'sleep' ? format_duration_hours($eventValue) : rtrim(rtrim(number_format($eventValue, 2, ',', '.'), '0'), ',') . ' ' . (string) ($event['unit'] ?? '')) : '';
$eventComment = trim((string) ($event['comment'] ?? '')); $isPutzligaEvent = (string) ($event['source'] ?? '') === 'putzliga';
$eventComment = $isPutzligaEvent ? '' : trim((string) ($event['comment'] ?? ''));
if (preg_match('/^\s*-\s*(?:Stimmung|Energie|Stress)\s*:\s*[+-]?\d+\s*$/u', $eventComment) === 1) { if (preg_match('/^\s*-\s*(?:Stimmung|Energie|Stress)\s*:\s*[+-]?\d+\s*$/u', $eventComment) === 1) {
$eventComment = ''; $eventComment = '';
} }
$eventTitle = day_event_type_label($eventType); $eventTitle = $isPutzligaEvent ? 'Putzliga' : day_event_type_label($eventType);
$eventDetails = array_values(array_filter([$eventValueText, $eventComment], static fn (string $value): bool => trim($value) !== '')); $eventDetails = array_values(array_filter([$eventValueText, $eventComment], static fn (string $value): bool => trim($value) !== ''));
if ($eventType === 'sport') { if ($eventType === 'sport') {
+1 -1
View File
@@ -171,7 +171,7 @@
<label><span>URL in Putzliga</span><input type="text" value="<?= e((string) $putzligaImportUrl) ?>" readonly></label> <label><span>URL in Putzliga</span><input type="text" value="<?= e((string) $putzligaImportUrl) ?>" readonly></label>
<label><span>HTTP-Header</span><input type="text" value="Authorization: Bearer <?= !empty($putzligaImportConfig['token_prefix']) ? e((string) $putzligaImportConfig['token_prefix']) . '…' : 'TOKEN' ?>" readonly></label> <label><span>HTTP-Header</span><input type="text" value="Authorization: Bearer <?= !empty($putzligaImportConfig['token_prefix']) ? e((string) $putzligaImportConfig['token_prefix']) . '…' : 'TOKEN' ?>" readonly></label>
</div> </div>
<p class="helper-text">Putzliga erstellt ab 3 erledigten Aufgaben pro Tag einen Moment „Du warst fleißig“ und aktualisiert ihn, wenn weitere Aufgaben dazukommen.</p> <p class="helper-text">Putzliga erstellt ab 3 erledigten Aufgaben pro Tag einen Moment mit den erledigten Aufgaben als Chips und aktualisiert ihn, wenn weitere Aufgaben dazukommen.</p>
<?php if (!empty($putzligaImportToken)): ?> <?php if (!empty($putzligaImportToken)): ?>
<label><span>Neuer Token, nur jetzt sichtbar</span><input type="text" value="<?= e((string) $putzligaImportToken) ?>" readonly></label> <label><span>Neuer Token, nur jetzt sichtbar</span><input type="text" value="<?= e((string) $putzligaImportToken) ?>" readonly></label>
<?php endif; ?> <?php endif; ?>