feat(dashboard): refine moment media experience

This commit is contained in:
2026-05-18 23:49:15 +02:00
parent b8a96e96ef
commit bc6e850afb
12 changed files with 624 additions and 158 deletions
+48 -24
View File
@@ -69,8 +69,21 @@ $summaryAlcohol = !empty($dayEntry['summary']['alcohol'] ?? $dayEntry['summary_a
<?php endif; ?>
<?php foreach ($dashboardTimeline as $item): ?>
<?php $sportType = ($item['type'] ?? '') === 'sport' ? find_sport_type($settings, (string) ($item['sport_type_id'] ?? '')) : null; ?>
<?php $eventType = (string) ($item['type'] ?? 'event'); ?>
<?php $sportType = $eventType === 'sport' ? find_sport_type($settings, (string) ($item['sport_type_id'] ?? '')) : null; ?>
<?php $eventTone = signal_value_class(normalize_signal_value($item['mood'] ?? 0)); ?>
<?php $eventValueText = (float) $item['value'] > 0 ? rtrim(rtrim(number_format((float) $item['value'], 2, ',', '.'), '0'), ',') . ' ' . (string) $item['unit'] : ''; ?>
<?php $eventTitle = match ($eventType) {
'sport' => (string) ($sportType['label'] ?? 'Sport'),
'walk' => 'Spaziergang',
'sleep' => 'Schlaf',
default => (string) ($item['comment'] !== '' ? $item['comment'] : day_event_type_label($eventType)),
}; ?>
<?php $eventDetail = match ($eventType) {
'sport' => trim($eventValueText),
'walk', 'sleep' => trim($eventValueText),
default => trim($eventValueText . ($sportType !== null ? ' · ' . (string) ($sportType['label'] ?? '') : '')),
}; ?>
<?php $eventPayload = encode_payload([
'id' => (string) ($item['id'] ?? ''),
'type' => (string) ($item['type'] ?? 'event'),
@@ -79,39 +92,35 @@ $summaryAlcohol = !empty($dayEntry['summary']['alcohol'] ?? $dayEntry['summary_a
'value' => (float) ($item['value'] ?? 0),
'unit' => (string) ($item['unit'] ?? ''),
'sport_type_id' => (string) ($item['sport_type_id'] ?? ''),
'image' => (string) ($item['image'] ?? ''),
'consumed' => !empty($item['consumed']),
'mood' => normalize_signal_value($item['mood'] ?? 0),
'energy' => normalize_signal_value($item['energy'] ?? 0),
'stress' => normalize_signal_value($item['stress'] ?? 0),
]); ?>
<article class="timeline-card timeline-card--event timeline-card--<?= e($eventTone) ?> glass-panel" data-event-editable data-event-payload="<?= e($eventPayload) ?>">
<?php $hasEventImage = is_string($item['image_url'] ?? null); ?>
<article class="timeline-card timeline-card--event timeline-card--<?= e($eventTone) ?><?= $hasEventImage ? ' timeline-card--with-image' : '' ?> glass-panel" data-event-editable data-event-payload="<?= e($eventPayload) ?>">
<?php if ($hasEventImage): ?>
<img class="timeline-card__image" src="<?= e((string) $item['image_url']) ?>" alt="">
<?php endif; ?>
<span class="timeline-card__time-chip"><?= e($item['time'] !== '' ? $item['time'] : '--:--') ?></span>
<div class="timeline-card__meta">
<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="">
</div>
<div>
<strong><?= e($item['time'] !== '' ? $item['time'] : '--:--') ?></strong>
<strong class="timeline-card__time"><?= e($item['time'] !== '' ? $item['time'] : '--:--') ?></strong>
</div>
</div>
<div class="timeline-card__body">
<h3>
<?php if ((string) ($item['type'] ?? '') === 'alcohol'): ?>
<?= !empty($item['consumed']) ? 'Heute getrunken' : 'Heute nicht getrunken' ?>
<?php else: ?>
<?= e($item['comment'] !== '' ? $item['comment'] : day_event_type_label((string) $item['type'])) ?>
<?php endif; ?>
</h3>
<?php if ((float) $item['value'] > 0): ?>
<h3><?= e($eventTitle) ?></h3>
<?php if ((string) ($item['type'] ?? '') === 'alcohol'): ?>
<p class="timeline-card__value">
<?= e(rtrim(rtrim(number_format((float) $item['value'], 2, ',', '.'), '0'), ',')) ?>
<?= e((string) $item['unit']) ?>
<?php if ($sportType !== null): ?>
· <?= e((string) ($sportType['label'] ?? '')) ?>
<?php endif; ?>
<?= !empty($item['consumed']) ? 'Heute getrunken' : 'Heute nicht getrunken' ?>
</p>
<?php elseif ($sportType !== null): ?>
<p class="timeline-card__value"><?= e((string) ($sportType['label'] ?? '')) ?></p>
<?php elseif ($eventDetail !== ''): ?>
<p class="timeline-card__value"><?= e($eventDetail) ?></p>
<?php endif; ?>
<?php if ((string) ($item['comment'] ?? '') !== '' && (string) ($item['type'] ?? '') === 'alcohol'): ?>
@@ -121,8 +130,10 @@ $summaryAlcohol = !empty($dayEntry['summary']['alcohol'] ?? $dayEntry['summary_a
<div class="signal-row">
<?php foreach (['mood' => 'Stimmung', 'energy' => 'Energie', 'stress' => 'Stress'] as $metric => $label): ?>
<?php $value = normalize_signal_value($item[$metric] ?? 0); ?>
<span class="signal-pill signal-pill--<?= e(signal_badge_tone($value, $metric)) ?>">
<?php $valueTone = signal_value_class($metric === 'stress' ? -$value : $value); ?>
<span class="signal-pill signal-pill--<?= e(signal_badge_tone($value, $metric)) ?> signal-pill--<?= e($valueTone) ?>">
<strong><?= e($label) ?></strong>
<img class="signal-pill__icon" src="<?= e(icon_path($metric === 'mood' ? 'signal-mood' : ($metric === 'energy' ? 'signal-energy' : 'signal-stress'))) ?>" alt="<?= e($label) ?>">
<span><?= $value >= 0 ? '+' : '' ?><?= e((string) $value) ?></span>
</span>
<?php endforeach; ?>
@@ -142,6 +153,15 @@ $summaryAlcohol = !empty($dayEntry['summary']['alcohol'] ?? $dayEntry['summary_a
</section>
<button class="dashboard-fab" type="button" data-moment-overlay-open aria-label="Neuen Moment hinzufügen">+</button>
<div class="dashboard-fab-menu glass-panel" data-fab-menu hidden>
<?php foreach ($dashboardEventTypes as $type => $meta): ?>
<?php if ($type === 'alcohol') { continue; } ?>
<button type="button" data-fab-moment-choice="<?= e($type) ?>">
<img src="<?= e((string) $meta['icon']) ?>" alt="">
<span><?= e((string) $meta['label']) ?></span>
</button>
<?php endforeach; ?>
</div>
</div>
<div class="dashboard-overlay" data-summary-overlay hidden>
@@ -240,7 +260,7 @@ $summaryAlcohol = !empty($dayEntry['summary']['alcohol'] ?? $dayEntry['summary_a
</div>
</div>
<form method="post" action="/" class="dashboard-modal__form" id="moment-form" data-moment-step="form" hidden>
<form method="post" action="/" enctype="multipart/form-data" class="dashboard-modal__form" id="moment-form" data-moment-step="form" hidden>
<?= csrf_field() ?>
<input type="hidden" name="form_name" value="add_event" data-moment-form-name>
<input type="hidden" name="date" value="<?= e((string) $dayEntry['date']) ?>">
@@ -261,6 +281,11 @@ $summaryAlcohol = !empty($dayEntry['summary']['alcohol'] ?? $dayEntry['summary_a
<textarea name="event_comment" rows="4" placeholder="Was hast du erlebt?" data-moment-comment></textarea>
</label>
<label>
<span>Momentbild</span>
<input type="file" name="event_image" accept="image/jpeg,image/png,image/webp">
</label>
<div class="field-grid field-grid--two">
<label>
<span>Erfasst um</span>
@@ -377,7 +402,7 @@ $summaryAlcohol = !empty($dayEntry['summary']['alcohol'] ?? $dayEntry['summary_a
<?php
$entry = is_array($day['entry'] ?? null) ? $day['entry'] : null;
$events = $entry !== null && is_array($entry['events'] ?? null) ? $entry['events'] : [];
$summaryText = $entry !== null ? trim((string) ($entry['summary']['comment'] ?? $entry['summary_comment'] ?? '')) : '';
$summaryText = $entry !== null ? trim((string) ($entry['summary']['comment'] ?? $entry['summary_comment'] ?? $entry['note'] ?? '')) : '';
$dayTone = (string) ($day['line_tone'] ?? 'empty');
$dayImage = $entry !== null && is_string($entry['background_image_url'] ?? null) ? (string) $entry['background_image_url'] : null;
?>
@@ -461,7 +486,7 @@ $summaryAlcohol = !empty($dayEntry['summary']['alcohol'] ?? $dayEntry['summary_a
<?php $monthDetailDays = array_values(array_filter($dashboardMonth['days'], static function (array $day): bool {
$entry = is_array($day['entry'] ?? null) ? $day['entry'] : null;
$summaryText = $entry !== null ? trim((string) ($entry['summary']['comment'] ?? $entry['summary_comment'] ?? '')) : '';
$summaryText = $entry !== null ? trim((string) ($entry['summary']['comment'] ?? $entry['summary_comment'] ?? $entry['note'] ?? '')) : '';
return !empty($day['has_content']) || $summaryText !== '';
})); ?>
@@ -470,7 +495,7 @@ $summaryAlcohol = !empty($dayEntry['summary']['alcohol'] ?? $dayEntry['summary_a
<?php foreach ($monthDetailDays as $day): ?>
<?php
$entry = is_array($day['entry'] ?? null) ? $day['entry'] : null;
$summaryText = $entry !== null ? trim((string) ($entry['summary']['comment'] ?? $entry['summary_comment'] ?? '')) : '';
$summaryText = $entry !== null ? trim((string) ($entry['summary']['comment'] ?? $entry['summary_comment'] ?? $entry['note'] ?? '')) : '';
$dayTone = (string) ($day['line_tone'] ?? 'empty');
?>
<a class="range-day-card range-day-card--summary-only range-day-card--<?= e($dayTone) ?> glass-panel" href="/?view=day&amp;date=<?= e(rawurlencode((string) $day['date'])) ?>">
@@ -495,7 +520,6 @@ $summaryAlcohol = !empty($dayEntry['summary']['alcohol'] ?? $dayEntry['summary_a
<h2 class="dashboard-modal__title">Einstellungen und Bereiche</h2>
<div class="settings-menu-grid">
<a class="options-menu-card" href="/options?panel=score"><strong>Score anpassen</strong><span>Multiplikatoren und Tageslogik</span></a>
<a class="options-menu-card" href="/options?panel=sports"><strong>Sportarten anpassen</strong><span>Eigene Sportarten und Bonuspunkte</span></a>
<a class="options-menu-card" href="/options?panel=walk"><strong>Spaziergang anpassen</strong><span>Zeit oder Schritte auswerten</span></a>
<a class="options-menu-card" href="/options?panel=reminders"><strong>Erinnerungen setzen</strong><span>Push und tägliche Erinnerung</span></a>