Kalender-Tageskacheln: Ampelfärbung nach Mindestanforderungen

Monatsansicht: Tageskacheln werden grün (bg-green-50) eingefärbt wenn
alle Mindestanforderungen für Training/Turnier/Heim-/Auswärtsspiel
erfüllt sind, rot (bg-red-50) wenn nicht. Status hat Vorrang vor
dem blauen Heute-Marker.

Jahresansicht: Mini-Dots zeigen ebenfalls grün/rot statt der
Event-Typ-Farbe, wenn Mindestanforderungen gesetzt sind.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Rhino
2026-03-03 09:05:45 +01:00
parent 06d6f82bf2
commit b9d158515f

View File

@@ -48,11 +48,7 @@
<div class="grid grid-cols-7">
<template x-for="(day, index) in calendarDays" :key="index">
<div
:class="{
'bg-gray-50 text-gray-400': !day.currentMonth,
'bg-blue-50': day.isToday,
'min-h-[80px] sm:min-h-[100px]': true
}"
:class="[dayCellClass(day), 'min-h-[80px] sm:min-h-[100px]']"
class="border-b border-r p-1 text-xs"
>
<div class="flex items-center justify-between mb-0.5">
@@ -111,7 +107,7 @@
<template x-if="d.dayNum">
<span
class="w-3.5 h-3.5 flex items-center justify-center rounded-full text-[8px] leading-none"
:class="d.isToday ? 'bg-blue-600 text-white font-bold' : (d.eventType ? eventDotClass(d.eventType) : 'text-gray-600')"
:class="miniDotClass(d)"
x-text="d.dayNum"
></span>
</template>
@@ -235,7 +231,7 @@
// Leere Zellen vor dem 1.
for (let i = 0; i < startWeekDay; i++) {
days.push({ dayNum: 0, eventType: null, isToday: false });
days.push({ dayNum: 0, eventType: null, minMet: null, isToday: false });
}
// Tage
@@ -246,6 +242,7 @@
days.push({
dayNum: d,
eventType: dayEvents ? dayEvents[0].type : null,
minMet: this.dayMinStatus(dayEvents || []),
isToday: this.isToday(date)
});
}
@@ -293,6 +290,37 @@
this.currentYear = today.getFullYear();
},
// Prüft ob ein Tag priorisierte Events hat (Training, Turnier, Heim-/Auswärtsspiel)
// und ob deren Mindestanforderungen erfüllt sind.
// Gibt true (alle erfüllt), false (nicht erfüllt) oder null (keine relevanten Events) zurück.
dayMinStatus(dayEvts) {
const priorityTypes = ['training', 'tournament', 'home_game', 'away_game'];
const relevant = dayEvts.filter(e => priorityTypes.includes(e.type));
if (!relevant.length) return null;
if (relevant.some(e => e.minMet === true)) return true;
if (relevant.some(e => e.minMet === false)) return false;
return null;
},
// CSS-Klasse für eine Tages-Kachel (Monatsansicht)
dayCellClass(day) {
if (!day.currentMonth) return 'bg-gray-50 text-gray-400';
const status = this.dayMinStatus(this.eventsForDate(day.dateStr));
if (status === true) return 'bg-green-50';
if (status === false) return 'bg-red-50';
if (day.isToday) return 'bg-blue-50';
return '';
},
// CSS-Klasse für Mini-Dots (Jahresansicht)
miniDotClass(d) {
if (d.isToday) return 'bg-blue-600 text-white font-bold';
if (d.minMet === true) return 'bg-green-500 text-white';
if (d.minMet === false) return 'bg-red-400 text-white';
if (d.eventType) return this.eventDotClass(d.eventType);
return 'text-gray-600';
},
// CSS-Klassen für Events in der Monatsansicht
eventBgClass(type) {
const map = {