# Enhanced Schedule Maker - Dokumentatie ## Overzicht Het Schedule Maker systeem is uitgebreid met geavanceerde planning functies: ### ✅ Implemented Features #### 1. Automatische Eindtijd Berekening - **Voordeel**: Geen handmatige eindtijd invoer meer - **Hoe het werkt**: Eindtijd = Begintijd + Geschatte rijduur van de lijn - **Voorbeeld**: - Lijn 101: geschatte duur 45 minuten - Begintijd: 08:00 - Eindtijd: 08:45 (automatisch berekend) #### 2. Automatische Vertrektijden per Halte - **Functionaliteit**: Berekent vertrektijd voor elke halte op basis van: - Begintijd van de dienst - Geschatte aankomsttijd per halte (in `route_stops.estimated_arrival_minutes`) - **Weergave**: Uitklapbaar tabel in schedule card met: - Haltenummer - Haltename - Vertrektijd **Voorbeeld JSON response:** ```json { "schedule": { "id": 1, "busLineId": 101, "busId": 5, "driverId": 3, "startTime": "2026-05-06T08:00:00Z", "endTime": "2026-05-06T08:45:00Z", "weekdays": [1, 2, 3, 4, 5], "departureTimes": [ { "order": 1, "stopId": 10, "stopName": "Central Station", "estimatedArrivalMinutes": 0, "departureTime": "2026-05-06T08:00:00Z" }, { "order": 2, "stopId": 11, "stopName": "Market Square", "estimatedArrivalMinutes": 10, "departureTime": "2026-05-06T08:10:00Z" }, { "order": 3, "stopId": 12, "stopName": "Park Lane", "estimatedArrivalMinutes": 25, "departureTime": "2026-05-06T08:25:00Z" } ], "status": "planned" } } ``` #### 3. Herhaald Rooster (Weekdagen) - **Functionaliteit**: Plan een dienst op meerdere weekdagen - **Invoer**: Klik op weekdagknoppen (Ma, Di, Wo, Do, Vr, Za, Zo) - **Opslag**: `schedules.weekdays` array met dagwaarden (0-6, waarbij 0=Zondag, 1=Maandag, etc.) - **Weergave**: In schedule card getoond als "Maandag, Woensdag, Vrijdag" **Request voorbeeld:** ```json POST /admin/schedules { "busLineId": 101, "busId": 5, "driverId": 3, "startTime": "2026-05-06T08:00:00Z", "weekdays": [1, 3, 5] // Ma, Wo, Vr } ``` **Weergave in UI:** - "Eenmalig" - geen weekdays geselecteerd - "Maandag, Woensdag, Vrijdag" - specifieke weekdays - "Dagelijks" - alle 7 weekdays #### 4. Bestuurders Dropdown - **Functionaliteit**: Selecteer bestuurder uit dropdown bij dienst aanmaken - **Bron**: GET `/admin/drivers` endpoint - **Opslag**: `schedules.driver_id` veld - **Weergave**: - In schedule card: "Bestuurdernaam" - Optioneel veld (NULL als niet ingesteld) **Response voorbeeld:** ```json { "drivers": [ { "id": 1, "name": "Jan Peterse", "email": "jan@transit.local", "phone": "06-12345678" }, { "id": 2, "name": "Maria Kuijpers", "email": "maria@transit.local", "phone": "06-87654321" } ] } ``` --- ## API Endpoints ### GET /admin/drivers **Beschrijving**: Haalt lijst van beschikbare bestuurders op **Response (DEV_MOCK):** ```json { "drivers": [ { "id": 1, "name": "Jan Peterse", "email": "jan@transit.local", "phone": "06-12345678", "status": "active" } ] } ``` **Response (Production):** - Query uit `workers.employees` tabel - Filtert op `status = 'active'` --- ### POST /admin/schedules **Beschrijving**: Maakt nieuwe dienst aan met automatische eindtijd en vertrektijden **Request Body:** ```json { "busLineId": 101, "busId": 5, "driverId": 3, // optioneel "startTime": "2026-05-06T08:00:00Z", "weekdays": [1, 2, 3, 4, 5] // optioneel, array van daggetallen } ``` **Validatie:** - `busLineId`, `busId`, `startTime` zijn verplicht - `driverId` is optioneel (NULL als niet gegeven) - `weekdays` is optioneel (lege array = eenmalige dienst) **Response:** ```json { "schedule": { "id": 1, "busLineId": 101, "busId": 5, "driverId": 3, "startTime": "2026-05-06T08:00:00Z", "endTime": "2026-05-06T08:45:00Z", "weekdays": [1, 2, 3, 4, 5], "departureTimes": [ { "order": 1, "stopId": 10, "stopName": "Central Station", "departureTime": "2026-05-06T08:00:00Z" }, // ... meer haltes ], "status": "planned", "createdAt": "2026-05-06T15:30:00Z" } } ``` **DEV_MOCK Details:** - Eindtijd = startTime + `bus_lines.estimated_duration_minutes` - Vertrektijden berekend via helper functie `calculateDepartureTimes()` - Dienst direct opgeslagen in `_mock.schedules` array --- ### GET /admin/schedules **Beschrijving**: Haalt alle geplande diensten met details op **Response (bevat nu):** ```json { "schedules": [ { "id": 1, "busLineId": 101, "busId": 5, "driverId": 3, "driverName": "Jan Peterse", // NEW "startTime": "2026-05-06T08:00:00Z", "endTime": "2026-05-06T08:45:00Z", "weekdays": [1, 2, 3, 4, 5], // NEW "departureTimes": [ // NEW { "order": 1, "stopId": 10, "stopName": "Central Station", "departureTime": "2026-05-06T08:00:00Z" } ], "status": "planned", "lineNumber": 101, "busName": "Bus A5", "licensePlate": "AB-123-CD", "createdAt": "2026-05-06T15:30:00Z" } ] } ``` --- ## Frontend Componenten ### ScheduleMaker.jsx **Nieuwe State Variabelen:** ```jsx const [drivers, setDrivers] = useState([]) // Bestuurders lijst const [selectedWeekdays, setSelectedWeekdays] = useState([]) // Geselecteerde weekdagen const [expandedSchedule, setExpandedSchedule] = useState(null) // Uitgebreide schedule ID ``` **Nieuwe Functions:** #### loadDrivers() ```jsx const loadDrivers = async () => { const res = await client.get('/admin/drivers') setDrivers(res.data.drivers || []) } ``` #### toggleWeekday(dayValue) ```jsx const toggleWeekday = (dayValue) => { setSelectedWeekdays(prev => prev.includes(dayValue) ? prev.filter(d => d !== dayValue) : [...prev, dayValue] ) } ``` #### getWeekdayLabel(weekdayValues) ```jsx const getWeekdayLabel = (weekdayValues) => { if (!weekdayValues || weekdayValues.length === 0) return 'Eenmalig' if (weekdayValues.length === 7) return 'Dagelijks' const labels = weekdayValues .sort() .map(w => WEEKDAYS[WEEKDAY_VALUES.indexOf(w)]) return labels.join(', ') } ``` **Nieuwe Form Elements:** 1. **Bestuurders Dropdown:** ```jsx ``` 2. **Weekdagknoppen:** ```jsx
| {stop.order}. | {stop.stopName} | {formatTime(stop.departureTime)} |