React Resource Scheduler: Räume und Autos per Drag buchen

Ein React Resource Scheduler ist der Screen hinter Raumbuchung, Fuhrparkplanung und Schichtplänen: Ressourcen an der Seite, Stunden oben, Buchungen als Balken, die du ziehen kannst. Er wirkt einfach, bis jemand ein Meeting auf einen belegten Raum zieht, ein Auto während seiner Wartung bucht oder zwei Leute gleichzeitig den Hudson-Raum um 9 Uhr nehmen. Auf dem Handy wird das Raster über 12 Stunden dann zu einem Streifen, den niemand antippen kann. Dieser Artikel zeigt, was eine Resource Timeline braucht, welche Props im Scheduler von Wingo UI zählen, wie du Buchungen auf dem Server absicherst und was du auf dem Handy zeigst.
Was ist ein Resource Scheduler, und was unterscheidet ihn von einem Kalender?
Ein Kalender beantwortet „Was steht heute bei mir an?“. Ein Resource Scheduler beantwortet „Welcher Raum, welches Auto oder welche Person ist um 14 Uhr frei?“. Das ändert das Layout:
- Zeilen sind Ressourcen. Jeder Besprechungsraum, jedes Fahrzeug und jedes Teammitglied bekommt eine Spur. Spuren lassen sich gruppieren (Räume, Team, Autos) und einklappen.
- Spalten sind Zeitslots. Ein Tag in Slots von 15, 30 oder 60 Minuten oder eine Woche in Tagen.
- Verfügbarkeit gehört zur Zeile. Zeit außerhalb der Arbeitszeit ist schattiert, in Wartung oder Urlaub sind keine Buchungen möglich.
- Eine Buchung gehört zu genau einer Ressource. Ziehst du sie in eine andere Zeile, weist du sie neu zu.
Jedes Raumbuchungssystem braucht diese vier Punkte. Wenn deine Nutzer vor allem ihre eigenen Termine anschauen, passt ein Kalender mit Monats- und Wochenansicht wie Calendar View besser. Für die Verfügbarkeit vieler Dinge brauchst du eine React Resource Timeline.
Welche React Resource Scheduler gibt es 2026?
Die wichtigsten Optionen sind FullCalendar Premium, Bryntum Scheduler, Syncfusion, das Open-Source-Paket react-big-schedule und der Scheduler von Wingo UI. Das steht Stand Oktober 2026 auf ihren eigenen Seiten:
Nimm Bryntum oder Syncfusion, wenn ein großes Team eine komplette Planungssuite mit Support vom Hersteller braucht, FullCalendar Premium, wenn du FullCalendar schon für Monatsansichten nutzt, und react-big-schedule, wenn deine App auf Ant Design läuft. Der Scheduler von Wingo UI ist für eine Tailwind-App gedacht, in der die Timeline zum Rest der Oberfläche passen, auf dem Handy funktionieren und als bearbeitbarer Quellcode im Repository liegen soll.
Wie sieht eine Resource Timeline in der Praxis aus?
Sie ist ein einziges Raster, in dem die Tage aller Ressourcen nebeneinander liegen. Ein freier Slot ist also eine Lücke, die du sofort siehst. Die Demo zeigt neun Ressourcen in drei Gruppen an einem Donnerstag im September. Die rote Linie markiert die aktuelle Uhrzeit, der Balken unter jedem Namen zeigt, wie viel seiner Arbeitszeit gebucht ist, und der Potomac-Raum ist von 14 bis 16 Uhr in Wartung.
$ npx wingo-ui@latest add schedulerVorläufige Buchungen sind gestrichelt. Stornierte sind durchgestrichen und blockieren nie einen Slot.
Wie richtest du Ressourcen und Buchungen ein?
Du übergibst zwei Arrays, resources für die Zeilen und events für die Buchungen, dazu Callbacks, die speichern, was deine Nutzer ändern. Installier ihn mit npx wingo-ui@latest add scheduler. Eine Ressource ist { id, name } plus optional avatar, icon, description, group, capacity, tone, color, unavailable und workingHours. Eine Buchung ist ein Event aus Calendar View (id, title, start, end und optionale Extras) plus resourceId und optional status.
Die Props, die das Raster formen, sind slotMinutes (darauf rastet alles ein), dayStartHour und dayEndHour (standardmäßig 8 und 20), slotWidth, rowHeight und resourceWidth in Pixeln sowie height (640px). Ab dieser Höhe scrollt das Raster, Zeitleiste und Namen bleiben dabei fixiert.
Wie funktionieren Anlegen, Verschieben und Größenänderung per Drag?
React Scheduler Drag and Drop läuft auf drei Gesten hinaus:
- Über freie Slots ziehen, um zu buchen. Der Bereich rastet auf die Slots ein, stoppt an der nächsten Buchung und öffnet darunter ein Schnellformular, in dem der Titel schon fokussiert ist. Enter speichert, Escape bricht ab. Speichern ruft
onCreateEventmit{ start, end, resourceId, title }auf. - Eine Buchung ziehen, um sie zu verschieben. Sie folgt dem Zeiger zu einer anderen Zeit oder in eine andere Zeile. Eine Vorschau zeigt, wo sie landet, und wird rot, wenn die Zeit belegt ist. Beim Loslassen rastet sie in den Slot ein.
- Eine Kante ziehen, um die Größe zu ändern. Die Buchung stoppt an ihren Nachbarn, statt über sie hinwegzulaufen.
Das Raster scrollt von selbst, wenn du in die Nähe seiner Ränder kommst, und Escape bricht jedes Ziehen ab. Verschieben und Größenänderung rufen onEventChange(event, change) mit { start, end, resourceId } auf. Die Buchung bewegt sich sofort; gibst du false oder ein abgelehntes Promise zurück, springt sie zurück, und der Fehler wird angesagt.
Wenn du schon ein eigenes Buchungsformular hast, übergib onSlotSelect statt onCreateEvent: Ein Ziehen, ein Klick oder Enter auf einem freien Slot gibt dir { start, end, resourceId }. onEventClick ersetzt auf dieselbe Weise das Popover mit den Details.
Wie verhinderst du Doppelbuchungen?
Lehne Überschneidungen in der Oberfläche ab und mach sie in der Datenbank unmöglich. In der Oberfläche ist allowOverlap standardmäßig false. Ein Drop, eine Größenänderung, eine Auswahl oder ein gespeichertes Formular, das sich mit einer anderen Buchung derselben Ressource überschneidet, wird abgelehnt. Die Buchung wackelt und federt zurück, und Screenreader hören den Standardtext „Hudson room is already booked then“. Gesperrte Zeit lehnt Buchungen auch dann ab, wenn allowOverlap an ist. Schalte es für Personen ein, die doppelt gebucht werden dürfen; überlappende Balken stapeln sich dann in Spuren, und die Zeile wächst.
Die Prüfung in der Oberfläche reicht nicht: Zwei Personen können sich denselben freien Slot in derselben Sekunde schnappen. Die Datei exportiert findConflicts(events, { start, end, resourceId, id? }). Die Funktion gibt die Buchungen dieser Ressource zurück, die sich mit dem Kandidaten überschneiden, und überspringt stornierte. Nutz sie in deinen eigenen Formularen auf dem Client und übergib beim Prüfen einer Änderung die id der Buchung, sonst kollidiert die Buchung mit sich selbst:
scheduler.tsx ist ein Client-Modul ("use client"), also importier es nicht in eine Server Action oder einen Route Handler. Wiederhol dieselbe Regel stattdessen in der Datenbank. In Postgres macht ein Exclusion Constraint die Überschneidung unmöglich, egal was der Client schickt:
Ein Schreibvorgang, der den Constraint verletzt, scheitert mit exclusion_violation (SQLSTATE 23P01). Fang diesen Code ab und antworte mit einem 409. send wirft bei jedem Status außerhalb von 200 bis 299. Eine verschobene Buchung federt dann zurück, und das Schnellformular zeigt „Could not save“ plus den Titel (das Label failed), egal welchen Text der Server geschickt hat.
Wie sollte ein React Buchungskalender auf dem Handy funktionieren?
Auf dem Handy sollte er eine Liste der Buchungen des Tages mit einem Button zum Buchen sein, kein Raster. Ein Tag von 8 bis 20 Uhr in Slots von 30 Minuten ergibt 24 Spalten zu je 48px, also etwa 1.150px Raster, die du auf einem 390px breiten Handy seitlich scrollen müsstest. Deshalb wird der Scheduler zu einer Agenda, sobald seine eigene Breite unter 576px fällt. Das ist eine Container Query: Auch ein schmales Seitenpanel bekommt die Agenda, und schon das HTML vom Server ist richtig. Die Agenda zeigt:
- einen Streifen mit den Tagen der Woche, mit Punkten an den belegten Tagen,
- die Buchungen des Tages, gruppiert nach Ressource, mit ihren Zeiten,
- die Ressourcen, die den ganzen Tag frei sind, als Chips, mit denen du sie buchst,
- einen Buchen-Button über die volle Breite, der den nächsten freien Slot vorschlägt.
Buchungen und das Buchungsformular öffnen sich als Bottom Sheets. Probier es im erzwungenen Handy-Layout aus:
$ npx wingo-ui@latest add schedulerFür Tablets im Hochformat behält mobileView="day" das Tagesraster, das seitlich scrollt, während die Namen fixiert bleiben. Per Touch öffnet ein Tipp auf einen freien Slot das Buchungs-Sheet, und langes Drücken nimmt eine Buchung zum Verschieben auf, damit normales Wischen weiter scrollt. Unser Artikel über dnd kit auf Mobilgeräten erklärt denselben Kompromiss in einer sortierbaren Liste. Spuren sind auf Touchscreens mindestens 56px hoch, damit jede Buchung eine Touch-Fläche von 44px hat, und layout="mobile" oder "desktop" erzwingt eines der beiden Layouts. Warum Sheets auf dem Handy besser funktionieren als Popovers, liest du in Bottom Sheets fürs Web.
Wie machst du einen Resource Scheduler per Tastatur bedienbar?
Mach das ganze Raster zu einem einzigen Tab-Stopp und navigier darin mit den Pfeiltasten, damit niemand mit der Tastatur durch Hunderte Slots tabben muss. Im Scheduler von Wingo UI wandern Links und Rechts durch die freien Slots und Buchungen einer Zeile, Hoch und Runter zwischen den Ressourcen, Bild auf und Bild ab um einen Tag oder eine Woche. Umschalt mit den Pfeiltasten wählt Slots aus, und Enter bucht sie; Alt mit den Pfeiltasten verschiebt die fokussierte Buchung, und Alt mit Umschalt ändert ihre Größe. Verschieben, Größenänderungen, neue Buchungen und abgelehnte Drops werden über eine Live Region mit aria-live="polite" angesagt. Mit reduzierter Bewegung passieren Einrasten und Wackeln ohne Animation.
Was geht kaputt, wenn ein Resource Scheduler in Produktion geht?
Zeitzonen, die aktuelle Uhrzeit und Daten, die nicht zu den Zeilen passen, verursachen die meisten Fehler:
- Zeitzonen.
startundendsindDate-Objekte, und die Stunden werden in der Zeitzone der Umgebung formatiert, die gerade rendert. Ein Server auf UTC und ein Browser in New York schreiben unterschiedliche Stunden in dasselbe HTML, und React meldet einen Hydration Mismatch. Speicher Zeitpunkte (timestamptz), lass den Server mitTZauf der Zeitzone deiner Nutzer laufen, oder lad den Scheduler mitnext/dynamicundssr: falseaus einer Client-Komponente, wenn deine Nutzer in mehreren Zeitzonen sitzen. - Die aktuelle Uhrzeit. Ohne
defaultDaterendert der Server den Tag der ersten Buchung, und der Browser springt danach auf heute. So passt die Hydration. Setznowin Tests auf einen festen Wert. - Fehlende Ressourcen. Eine Buchung, deren
resourceIdnicht inresourcessteht, landet in einer Zeile „No resource“. Behandle diese Zeile wie einen Bug-Report. - Arbeitszeiten sind volle Stunden.
workingHours: { start: 9, end: 17 }schattiert den Rest des Tages und das Wochenende. Mittagspausen und einmalige Schließungen gehören inunavailable, mit einemlabel. - Labels. Jeder Text ist eine Prop.
labels={{ book: "Reservieren", newBooking: "Neue Reservierung" }}ändert die Texte,conflictnimmt eine Funktion des Ressourcennamens, undDEFAULT_SCHEDULER_LABELSenthält alle Texte, die du per Spread als Basis unter deine Übersetzung legst.
Wann ist ein normaler Terminkalender die bessere Wahl?
Ein normaler Kalender ist besser, wenn deine Nutzer vor allem ihre eigenen Meetings anschauen. Dafür nimmst du Calendar View: Monats-, Wochen-, Tages- und Agendaansicht mit Verschieben per Drag. Eine Buchung im Scheduler ist dessen Event plus resourceId, also speisen dieselben Daten beide Komponenten. Unser Guide zum React Kalender mit Terminen behandelt diesen Kalender genauer, und wenn die Zeilen Aufgaben mit Abhängigkeiten statt Buchungen sind, passt der Guide zum React Gantt Chart besser.
$ npx wingo-ui@latest add calendar-viewUm in einem Formular einen einzelnen Slot zu wählen, ist ein Time Picker neben einem Datumsfeld schlanker als beide. Der Guide zu React-Formularkomponenten zeigt, wie diese Felder zusammenpassen, und in der Kategorie Komponenten-Guides findest du weitere Deep Dives zu einzelnen Komponenten.
Wie fügst du den Scheduler in eine Next.js-App ein?
Führ npx wingo-ui@latest add scheduler aus. Der Befehl kopiert components/ui/scheduler.tsx und die 21 Wingo-UI-Items, die die Datei direkt importiert (plus deren eigene Abhängigkeiten), darunter Calendar View (für den Event-Typ), Popover, Select, Time Picker, Tooltip sowie die Helfer für Datum, Motion und Tones, und installiert lucide-react und motion. Der Scheduler gehört zu Wingo UI Pro, also melde dich vorher mit npx wingo-ui@latest login an.
Häufige Fragen
Was ist ein Resource Scheduler in React?
Eine Zeitleiste, in der jede Zeile eine Ressource ist, etwa ein Besprechungsraum, ein Fahrzeug oder ein Teammitglied, und die Zeit über die Spalten läuft. Buchungen sind Balken in diesen Zeilen. So siehst du die Verfügbarkeit jeder Ressource auf einen Blick statt in einem gemeinsamen Kalender.
Ist die Resource Timeline von FullCalendar kostenlos?
Nein. Stand Oktober 2026 führt die Preisseite von FullCalendar Timeline View und Vertical Resource View als Premium-Funktionen, und Premium beginnt bei $480 für 1 bis 10 Entwickler. Die Standard-Edition mit Monats-, Wochen- und Tagesansicht ist kostenlos.
Wie verhindere ich Doppelbuchungen in einem React Scheduler?
Lehne überlappende Drops in der Oberfläche ab und prüf auf dem Server noch einmal, denn zwei Personen können denselben Slot im selben Moment buchen. Im Scheduler von Wingo UI ist allowOverlap standardmäßig false, gesperrte Zeit lehnt Buchungen immer ab, und ein abgelehntes Promise aus onEventChange setzt die Buchung zurück.
Wie sollte ein Buchungskalender auf dem Handy funktionieren?
Zeig einen Tag als Liste von Buchungen, gruppiert nach Ressource, und einem Buchen-Button über die volle Breite, statt eines breiten Rasters, das du seitlich scrollen musst. Das Verschieben einer Buchung sollte per Touch erst nach langem Drücken starten, damit normales Wischen weiter die Seite scrollt.
Brauche ich einen Resource Scheduler oder einen normalen Kalender?
Nimm einen Resource Scheduler, wenn die Frage lautet, welcher Raum, welches Auto oder welche Person zu einer bestimmten Zeit frei ist. Nimm einen normalen Terminkalender mit Monats- und Wochenansicht, wenn jede Person vor allem ihre eigenen Termine anschaut.
- Scheduler
- Buchung
- Drag and Drop
- Mobile UI


