Wie man einen kollaborativen Kalender mit Filtern erstellt
Der TAMSIV-Kalender begann als einfache Komponente: eine Liste von Ereignissen, ein Kalender, eine Tagesansicht. Und dann kamen die kollaborativen Gruppen. Plötzlich war ein Ereignis nicht mehr persönlich – es konnte Teilnehmer, Einladungen, Status haben. Und mit 15 Personen in einer aktiven Gruppe wurde der Kalender ohne Filter unleserlich.
Ich musste das Ganze neu überdenken: Teilnehmersystem mit Einladungen und Benachrichtigungen, erweiterte Filter zur Navigation im Feed, mehrtägige Ereignisse und ein privates Overlay, um persönliche Verpflichtungen im Kontext der Gruppe zu sehen. Der Kalender wurde zur komplexesten Komponente von TAMSIV – aber auch zur nützlichsten im Alltag.
Wichtige Punkte zum Merken:
- Ein kollaborativer Kalender erfordert ein Teilnehmersystem mit Status (eingeladen, angenommen, abgelehnt)
- Erweiterte Filter sind unerlässlich, sobald die Gruppenaktivität 10 Ereignisse/Woche übersteigt
- Mehrtägige Ereignisse erfordern eine Spannenberechnung mit Zeitzonenverwaltung
- Das private Overlay im Gruppenkalender wahrt die Vertraulichkeit und vermeidet Konflikte
- 5 Kalenderansichten (Tag, 3 Tage, Woche, Monat, Liste) decken alle Anwendungsfälle ab
Warum reicht ein persönlicher Kalender in einer kollaborativen App nicht aus?
Solange TAMSIV eine rein persönliche App war, war der Kalender einfach. Du erstellst ein Ereignis, siehst es in deinem Kalender, Punkt. Aber als ich die hierarchischen Gruppen hinzufügte, änderte sich alles.
In einer Gruppe (Familie, Team, Verein) werden Ereignisse geteilt. Ein Meeting, ein Familienessen, ein Sportspiel – jeder muss es sehen. Aber nicht jeder möchte alle Ereignisse sehen. Der Manager möchte die Meetings seines Teams sehen, nicht die Ausflüge der Bowlinggruppe. Der Elternteil möchte die Aktivitäten der Kinder sehen, nicht die beruflichen Meetings des Partners.
Hier werden Filter und das Teilnehmersystem unerlässlich. Ohne sie ist der kollaborative Kalender ein nutzloses Durcheinander.
Wie funktioniert das Teilnehmersystem in TAMSIV?
Jedes Ereignis in TAMSIV kann Teilnehmer haben, die aus den Gruppenmitgliedern eingeladen werden. Die Architektur basiert auf einer Verknüpfungstabelle im Schema collaborative:
-- Vereinfachte Tabelle
calendar_event_participants (
id UUID PRIMARY KEY,
event_id UUID REFERENCES privat.calendar_events,
user_id UUID REFERENCES auth.users,
status TEXT CHECK (status IN ('invited', 'accepted', 'declined')),
invited_at TIMESTAMPTZ,
responded_at TIMESTAMPTZ
)
Der Einladungsablauf ist wie folgt:
- Der Ersteller fügt Teilnehmer hinzu während der Erstellung oder Bearbeitung des Ereignisses. Er wählt aus den Gruppenmitgliedern über einen Picker aus.
- Push-Benachrichtigung: Jeder eingeladene Teilnehmer erhält eine FCM-Benachrichtigung mit dem Titel des Ereignisses, dem Datum und einem Button zum Annehmen oder Ablehnen.
- Antwort: Der Teilnehmer nimmt an oder lehnt ab. Sein Status wird in Echtzeit in der Datenbank aktualisiert.
- Sichtbarkeit: Das Ereignis erscheint im Kalender aller Teilnehmer (eingeladen, angenommen). Abgelehnte sehen es nicht mehr (es sei denn, sie ändern ihre Meinung).
Dies ist ein ähnlicher Ablauf wie bei Google Kalender, aber angepasst an den Kontext der hierarchischen Gruppen von TAMSIV. Der Hauptunterschied: Die Teilnehmer sind auf Gruppenmitglieder beschränkt, nicht auf beliebige E-Mail-Adressen.
Welche erweiterten Filter sind in einem Gruppenkalender unerlässlich?
Die FilterBar des Kalenders bietet drei Filtermodi:
- "Alle": Zeigt alle Ereignisse der Gruppe an. Nützlich für einen Überblick, aber in einer aktiven Gruppe schnell unübersichtlich.
- "Meine Erstellungen": Zeigt nur die Ereignisse an, die du erstellt hast. Nützlich, um zu überprüfen, ob deine eigenen Ereignisse richtig geplant sind.
- "Teilnehmend": Zeigt nur die Ereignisse an, an denen du teilnimmst (eingeladen oder angenommen). Dies ist der am häufigsten verwendete Modus – er beantwortet die Frage "Wo muss ich anwesend sein?".
Diese Filter werden in Echtzeit angewendet, ohne dass die Seite neu geladen werden muss. Der ContentCacheService speichert die Ereignisse im Cache, und die Filter arbeiten clientseitig mit den gecachten Daten. Das Ergebnis: Ein Filterwechsel ist sofort, selbst bei Hunderten von Ereignissen.
Zusätzlich zu den Filtern nach Teilnahme bietet die FilterBar die 3 klassischen TAMSIV-Kontexte:
- Privat: Nur deine persönlichen Ereignisse
- Geteilt: Ereignisse der Gruppen, denen du angehörst
- Alle: Zusammenführung beider Ansichten
Diese Filter sind konsistent mit denen des Feeds und der Aufgaben. Der Benutzer findet die gleichen Navigationsparadigmen überall in der App wieder.
Wie werden mehrtägige Ereignisse in einer Kalenderkomponente verwaltet?
Ein Ereignis "Konferenz Montag→Mittwoch" muss in der Kalenderansicht über 3 Tage angezeigt werden. Das scheint trivial, aber die Implementierung ist voller Fallstricke.
Die Komponente AgendaView berechnet die Spannen – die Dauer in Tagen jedes Ereignisses. Für jeden angezeigten Tag bestimmt sie, welche Ereignisse ihn abdecken, und positioniert sie visuell:
- Tagesansicht: Das mehrtägige Ereignis erscheint als Banner oben, über den stündlichen Ereignissen.
- Wochenansicht: Das Ereignis erstreckt sich horizontal über die Spalten, die den abgedeckten Tagen entsprechen.
- Monatsansicht: Gleiches Prinzip, mit einem Abschneidesystem, wenn zu viele Ereignisse überlappen.
- Listenansicht: Das Ereignis erscheint nur einmal, mit seinen Start- und Enddaten.
Die Hauptfalle: die Zeitzonen an den Tagesgrenzen. Ein Ereignis, das am Montag um 23 Uhr UTC+1 beginnt und am Dienstag um 2 Uhr endet, deckt es 1 oder 2 Tage ab? Die Antwort hängt von der Zeitzone des Benutzers ab. Ich habe mich für eine einfache Logik entschieden: Ein Ereignis deckt einen Tag ab, wenn es mindestens eine Stunde Präsenz an diesem Tag in der lokalen Zeitzone des Benutzers hat.
Was ist das private Overlay und warum ist es unerlässlich?
Hier ist das Szenario: Du bist im Kalender deiner professionellen Gruppe. Du möchtest am Dienstag um 14 Uhr ein Meeting planen. Aber am Dienstag um 14 Uhr hast du einen persönlichen Arzttermin. Wie kannst du das wissen, ohne den Gruppenkalender zu verlassen?
Das ist die Rolle des privaten Overlays. Im Gruppenkalender erscheinen deine persönlichen Ereignisse transparent, grau. Sie sind nicht anklickbar, keine Details sichtbar – nur ein Block, der anzeigt "du hast hier schon etwas".
Die Regeln des Overlays:
- Nur für dich sichtbar: Andere Gruppenmitglieder sehen deine privaten Ereignisse nicht.
- Nicht interaktiv: Kein Klick, keine Details, keine Änderung aus der Gruppenansicht.
- Diskret visuell: Reduzierte Deckkraft (30%), graue Farbe, kein sichtbarer Titel. Nur ein Indikator für "belegter Slot".
- Deaktivierbar: Ein Schalter in den Einstellungen ermöglicht es, das Overlay auszublenden, wenn du es nicht möchtest.
Dieses Overlay respektiert die Vertraulichkeit und vermeidet gleichzeitig Terminüberschneidungen. Es ist ein Muster, das ich von Google Kalender übernommen habe (der "Busy" für die Ereignisse anderer anzeigt), angepasst an den Kontext einer Gruppe, in der die Privatsphäre wichtig ist.
Wie decken die 5 Kalenderansichten alle Anwendungsfälle ab?
TAMSIV bietet 5 Kalenderansichten, jede auf einen anderen Bedarf zugeschnitten:
- Tagesansicht: Stundenweise Zeitleiste. Ideal, um einen vollen Tag zu planen, freie Zeitfenster zu sehen. Wird verwendet, wenn du suchst "Wann habe ich heute frei?".
- 3-Tages-Ansicht: Kompromiss zwischen Tagesdetail und Wochenübersicht. Mein Favorit für die kurzfristige Planung. Du siehst heute + die nächsten 2 Tage.
- Wochenansicht: Die klassische Geschäftsansicht. 7 Spalten, jeder Tag sichtbar. Nützlich für Teams, die wöchentlich planen.
- Monatsansicht: Überblick. Ereignisse sind farbige Punkte. Nützlich, um geschäftige Perioden und freie Tage zu erkennen. Konsistent mit der Produktivitätsvision der App.
- Listenansicht: Einfache chronologische Liste. Kein Raster, keine Positionierung. Nützlich auf Mobilgeräten, wenn die Wochenansicht zu klein ist, oder zum Exportieren/Teilen.
Jede Ansicht behält das aktuelle Datum beim Ansichtswechsel bei. Wenn du am Mittwoch, dem 15., in der Tagesansicht bist und zur Wochenansicht wechselst, siehst du die Woche des 15. Das horizontale Wischen ermöglicht die Navigation in der Zeit (vorheriger/nächster Tag, vorherige/nächste Woche).
Wie interagiert der Kalender mit der Sprachpipeline von TAMSIV?
Eine der Stärken von TAMSIV ist die Erstellung von Ereignissen per Sprache. Du sagst "Füge ein Meeting mit Marc nächsten Dienstag um 14 Uhr hinzu" und das Diktiergerät erstellt das Ereignis. Das Backend verwendet das Funktionswerkzeug create_calendar_event, um Datum, Uhrzeit, Titel und genannte Teilnehmer zu extrahieren.
Das System der PendingCreation gilt auch für Ereignisse: Die KI erstellt eine Vorschau, der Benutzer kann die Details bearbeiten (Teilnehmer hinzufügen, Uhrzeit ändern), bevor er bestätigt. Das vermeidet Transkriptionsfehler – "Dienstag" vs. "Mittwoch" ist ein klassischer STT-Fehler.
Sobald das Ereignis erstellt ist, verbreitet der Realtime-Cache die Änderung: Alle Teilnehmer sehen das Ereignis in ihrem Kalender erscheinen, ohne zu aktualisieren. Die Push-Benachrichtigung wird parallel gesendet. Der gesamte Ablauf – Sprache → KI → Erstellung → Benachrichtigung → Anzeige – dauert etwa 3 Sekunden.
Was waren die größten technischen Schwierigkeiten?
Der Kalender ist die komplexeste Komponente von TAMSIV. Hier sind die größten Herausforderungen, denen ich begegnet bin:
- Rendering-Performance: Die Wochenansicht mit über 50 Ereignissen und dem privaten Overlay muss flüssig bleiben. Ich musste
React.memoaggressiv einsetzen und die Ereignislisten in der Listenansicht virtualisieren. - Scroll-Verwaltung: Das horizontale Wischen zur Navigation zwischen Tagen/Wochen kollidiert mit dem vertikalen Scrollen der Zeitleiste. Ich habe einen
GestureDetectorvon react-native-gesture-handler mit Richtungsschwellen verwendet, um dies zu disambiguieren. - Gestapelte Ereignisse: Wenn sich 3 Ereignisse im selben Zeitfenster überlappen, müssen sie in der Zeitleiste nebeneinander angeordnet werden. Der Algorithmus für das Layout gestapelter Ereignisse ist nicht trivial – es ist ein Problem der Intervallplanung.
- RLS Supabase: Die Row Level Security-Richtlinien für Gruppenereignisse sind komplex. Ein Ereignis ist sichtbar, wenn: du es erstellt hast, ODER du Teilnehmer bist, ODER du Mitglied der Gruppe bist und das Ereignis öffentlich ist. Drei ODER-Bedingungen in einer einzigen RLS-Richtlinie.
Wie skaliert diese Architektur für zukünftige Anforderungen?
Die aktuelle Architektur ist so konzipiert, dass sie sich weiterentwickeln kann. Hier sind die geplanten Erweiterungen in der Roadmap:
- Wiederholung: Wiederkehrende Ereignisse (jeden Montag, am 1. jedes Monats). Das DB-Schema ist bereit, das Frontend noch nicht.
- Externe Kalendersynchronisation: iCal-Import/Export zur Synchronisation mit Google Kalender, Outlook, Apple Kalender.
- Geteilte Verfügbarkeit: Anzeige der Verfügbarkeitsfenster der Gruppenmitglieder zur Erleichterung der Planung.
- Personalisierte Erinnerungen: Jeder Teilnehmer kann seine eigenen Erinnerungen konfigurieren (5 Min. vorher, 1 Std. vorher, am Vortag).
FAQ
Kann man Teilnehmer außerhalb der Gruppe einladen?
Derzeit nicht. Die Teilnehmer sind auf die Mitglieder der Gruppe beschränkt, in der das Ereignis erstellt wird. Dies ist eine bewusste Entscheidung, um die Berechtigungsverwaltung zu vereinfachen. Die Einladung per E-Mail (wie bei Google Kalender) ist in einer zukünftigen Version geplant.
Wie funktionieren die Einladungsbenachrichtigungen?
Einladungen lösen eine Push-Benachrichtigung über Firebase Cloud Messaging aus. Der Teilnehmer erhält den Titel des Ereignisses, Datum/Uhrzeit und kann direkt aus der Benachrichtigung (FCM-Aktionsbuttons) annehmen oder ablehnen. Die Antwort wird in Echtzeit in Supabase gespeichert.
Funktioniert das private Overlay in allen Ansichten?
Ja, das private Overlay ist in allen 5 Ansichten (Tag, 3 Tage, Woche, Monat, Liste) aktiv. In der Monatsansicht erscheinen private Ereignisse als diskrete graue Punkte. In den Zeitansichten (Tag, Woche) erscheinen sie als transparente Blöcke.
Ersetzt der TAMSIV-Kalender Google Kalender?
Nein, er ergänzt ihn. Der TAMSIV-Kalender ist für die Verwaltung von Aufgaben und kollaborativen Projekten konzipiert, wobei die Sprache der primäre Interaktionsmodus ist. Google Kalender ist besser für die reine Kalenderverwaltung geeignet (komplexe Wiederholungen, Multi-Device-Synchronisation). Die Synchronisation zwischen beiden ist in der Roadmap.
Kann man ein Ereignis per Sprache mit Teilnehmern erstellen?
Ja. Du kannst sagen "Meeting mit Marc und Sophie Freitag um 10 Uhr" und die KI erkennt die genannten Teilnehmer, vorausgesetzt, sie sind Mitglieder der aktiven Gruppe. Das PendingCreation-System ermöglicht es dir, die Teilnehmer vor der Bestätigung zu überprüfen und anzupassen.