Refactor member activity display to group participations by date

This commit updates the `MemberActivityStatsDialog` component to group member participations by date, enhancing the presentation of activity data. The logic is introduced to aggregate activities under their respective dates, ensuring a clearer and more organized display. Additionally, CSS styles are added to improve the visual hierarchy and user experience when viewing recent participations.
This commit is contained in:
Torsten Schulz (local)
2025-11-14 23:27:46 +01:00
parent 5dda346fd7
commit ce2bda37ac
2 changed files with 206 additions and 121 deletions

View File

@@ -10,10 +10,14 @@
<!-- Letzte 3 Teilnahmen -->
<div class="section">
<h3 class="section-title">Letzte 3 Teilnahmen</h3>
<div v-if="lastParticipations && lastParticipations.length" class="participations-list">
<div v-for="participation in lastParticipations" :key="participation.id" class="participation-item">
<div class="participation-name">{{ participation.activityName }}</div>
<div class="participation-date">{{ formatDate(participation.date) }}</div>
<div v-if="groupedParticipations && groupedParticipations.length" class="participations-list">
<div v-for="dateGroup in groupedParticipations" :key="dateGroup.date" class="participation-date-group">
<div class="participation-date-header">{{ formatDate(dateGroup.date) }}</div>
<div class="participation-activities">
<div v-for="(activity, index) in dateGroup.activities" :key="index" class="participation-item">
<div class="participation-name">{{ activity }}</div>
</div>
</div>
</div>
</div>
<div v-else class="no-data">
@@ -65,6 +69,39 @@ export default {
}
},
emits: ['update:modelValue', 'close'],
computed: {
groupedParticipations() {
if (!this.lastParticipations || this.lastParticipations.length === 0) {
return [];
}
// Gruppiere nach Datum
const grouped = new Map();
this.lastParticipations.forEach(participation => {
const date = participation.date;
if (!grouped.has(date)) {
grouped.set(date, {
date: date,
activities: []
});
}
const dateGroup = grouped.get(date);
// Füge Aktivität nur hinzu, wenn sie noch nicht vorhanden ist
if (!dateGroup.activities.includes(participation.activityName)) {
dateGroup.activities.push(participation.activityName);
}
});
// Sortiere nach Datum (neueste zuerst) und nehme die ersten 3
return Array.from(grouped.values())
.sort((a, b) => {
const dateA = new Date(a.date);
const dateB = new Date(b.date);
return dateB - dateA;
})
.slice(0, 3);
}
},
methods: {
handleClose() {
this.$emit('update:modelValue', false);
@@ -108,6 +145,26 @@ export default {
gap: 0.75rem;
}
.participation-date-group {
margin-bottom: 1rem;
}
.participation-date-header {
font-weight: 600;
color: var(--primary-color);
font-size: 0.95rem;
margin-bottom: 0.5rem;
padding-bottom: 0.25rem;
border-bottom: 1px solid var(--background-light);
}
.participation-activities {
display: flex;
flex-direction: column;
gap: 0.5rem;
margin-left: 0.5rem;
}
.participation-item,
.stat-item {
display: flex;