feat: fix time slot hierarchy — seeder, API include_children, frontend dropdown, navigation
Restructure the festival hierarchy end-to-end: Seeder: Remove duplicate festival-level VOLUNTEER time slots, keep only CREW operational slots. Rename sub-events to "Dag 1/2/3 — ..." pattern. Change Nachtsecurity to Security (cross_event). EHBO/Security shifts now use sub-event time slots via cross_event exception. Add flat event "Braderie Dorpstown 2026". API: Add ?include_children=true to TimeSlotController for festivals, returning all sub-event time slots with source and event_name fields. Update StoreShiftRequest and UpdateShiftRequest to accept child time slots for cross_event sections. Frontend: Create useTimeSlotDropdown composable with 4-scenario dropdown logic. Replace AppSelect with VAutocomplete in CreateShiftDialog with grouped items, dimmed festival slots, and info tooltips. Add InfoTooltip reusable component. Show festival context labels on cross_event sections in sub-event section lists. Add read-only festival time slots on sub-event time-slots page. Add cross_event context banner with "Bekijk alle diensten" link. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -47,6 +47,7 @@ class DevSeeder extends Seeder
|
||||
|
||||
$this->seedOrganisation();
|
||||
$this->seedEchtFeesten();
|
||||
$this->seedBraderie();
|
||||
$this->seedIJsbaan();
|
||||
$this->seedKoningsdag();
|
||||
$this->seedNachtVanDeKaap();
|
||||
@@ -187,7 +188,7 @@ class DevSeeder extends Seeder
|
||||
$vrijdag = Event::create([
|
||||
'organisation_id' => $this->org->id,
|
||||
'parent_event_id' => $festival->id,
|
||||
'name' => 'Vrijdag',
|
||||
'name' => 'Dag 1 — Vrijdag',
|
||||
'slug' => 'echt-feesten-2026-vrijdag',
|
||||
'start_date' => '2026-07-10',
|
||||
'end_date' => '2026-07-10',
|
||||
@@ -199,7 +200,7 @@ class DevSeeder extends Seeder
|
||||
$zaterdag = Event::create([
|
||||
'organisation_id' => $this->org->id,
|
||||
'parent_event_id' => $festival->id,
|
||||
'name' => 'Zaterdag',
|
||||
'name' => 'Dag 2 — Zaterdag',
|
||||
'slug' => 'echt-feesten-2026-zaterdag',
|
||||
'start_date' => '2026-07-11',
|
||||
'end_date' => '2026-07-11',
|
||||
@@ -211,7 +212,7 @@ class DevSeeder extends Seeder
|
||||
$zondag = Event::create([
|
||||
'organisation_id' => $this->org->id,
|
||||
'parent_event_id' => $festival->id,
|
||||
'name' => 'Zondag',
|
||||
'name' => 'Dag 3 — Zondag',
|
||||
'slug' => 'echt-feesten-2026-zondag',
|
||||
'start_date' => '2026-07-12',
|
||||
'end_date' => '2026-07-12',
|
||||
@@ -257,8 +258,8 @@ class DevSeeder extends Seeder
|
||||
'show_in_registration' => false,
|
||||
]);
|
||||
|
||||
$nachtsecurity = FestivalSection::create([
|
||||
'event_id' => $festival->id, 'name' => 'Nachtsecurity', 'type' => 'standard',
|
||||
$security = FestivalSection::create([
|
||||
'event_id' => $festival->id, 'name' => 'Security', 'type' => 'cross_event',
|
||||
'category' => 'Veiligheid', 'icon' => 'tabler-shield', 'sort_order' => 2,
|
||||
'responder_self_checkin' => true, 'crew_auto_accepts' => false,
|
||||
'show_in_registration' => false,
|
||||
@@ -307,70 +308,85 @@ class DevSeeder extends Seeder
|
||||
}
|
||||
}
|
||||
|
||||
// ── Festival-level time slots ──
|
||||
// CREW slots for operational planning (opbouw, nachtbewaking, afbraak)
|
||||
// VOLUNTEER slots for cross_event sections (EHBO, Accreditatie) that span all days
|
||||
// ── Festival-level time slots (CREW only — operational planning) ──
|
||||
// No VOLUNTEER slots at festival level — cross_event sections use sub-event time slots
|
||||
|
||||
$fSlots = [];
|
||||
$fSlots['opbouw1'] = TimeSlot::create(['event_id' => $festival->id, 'name' => 'Opbouw Dag 1', 'person_type' => 'CREW', 'date' => '2026-07-09', 'start_time' => '08:00', 'end_time' => '18:00', 'duration_hours' => 10.00]);
|
||||
$fSlots['opbouw2'] = TimeSlot::create(['event_id' => $festival->id, 'name' => 'Opbouw Dag 2', 'person_type' => 'CREW', 'date' => '2026-07-10', 'start_time' => '08:00', 'end_time' => '14:00', 'duration_hours' => 6.00]);
|
||||
$fSlots['nacht_vr'] = TimeSlot::create(['event_id' => $festival->id, 'name' => 'Nachtbewaking Vr→Za', 'person_type' => 'CREW', 'date' => '2026-07-10', 'start_time' => '02:00', 'end_time' => '08:00', 'duration_hours' => 6.00]);
|
||||
$fSlots['nacht_za'] = TimeSlot::create(['event_id' => $festival->id, 'name' => 'Nachtbewaking Za→Zo', 'person_type' => 'CREW', 'date' => '2026-07-11', 'start_time' => '02:00', 'end_time' => '08:00', 'duration_hours' => 6.00]);
|
||||
$fSlots['opbouw1'] = TimeSlot::create(['event_id' => $festival->id, 'name' => 'Opbouw vrijdag', 'person_type' => 'CREW', 'date' => '2026-07-09', 'start_time' => '08:00', 'end_time' => '18:00', 'duration_hours' => 10.00]);
|
||||
$fSlots['opbouw2'] = TimeSlot::create(['event_id' => $festival->id, 'name' => 'Opbouw zaterdag', 'person_type' => 'CREW', 'date' => '2026-07-10', 'start_time' => '08:00', 'end_time' => '14:00', 'duration_hours' => 6.00]);
|
||||
$fSlots['nacht_vr'] = TimeSlot::create(['event_id' => $festival->id, 'name' => 'Nachtsecurity vr→za', 'person_type' => 'CREW', 'date' => '2026-07-10', 'start_time' => '23:00', 'end_time' => '07:00', 'duration_hours' => 8.00]);
|
||||
$fSlots['nacht_za'] = TimeSlot::create(['event_id' => $festival->id, 'name' => 'Nachtsecurity za→zo', 'person_type' => 'CREW', 'date' => '2026-07-11', 'start_time' => '23:00', 'end_time' => '07:00', 'duration_hours' => 8.00]);
|
||||
$fSlots['afbraak'] = TimeSlot::create(['event_id' => $festival->id, 'name' => 'Afbraak', 'person_type' => 'CREW', 'date' => '2026-07-13', 'start_time' => '08:00', 'end_time' => '18:00', 'duration_hours' => 10.00]);
|
||||
// Festival-level VOLUNTEER slots for cross_event sections (EHBO, Accreditatie)
|
||||
$fSlots['vr_early'] = TimeSlot::create(['event_id' => $festival->id, 'name' => 'Vrijdag Early (Festival)', 'person_type' => 'VOLUNTEER', 'date' => '2026-07-10', 'start_time' => '14:00', 'end_time' => '18:00', 'duration_hours' => 4.00]);
|
||||
$fSlots['vr_avond'] = TimeSlot::create(['event_id' => $festival->id, 'name' => 'Vrijdag Avond (Festival)', 'person_type' => 'VOLUNTEER', 'date' => '2026-07-10', 'start_time' => '18:00', 'end_time' => '02:00', 'duration_hours' => 8.00]);
|
||||
$fSlots['za_dag'] = TimeSlot::create(['event_id' => $festival->id, 'name' => 'Zaterdag Dag (Festival)', 'person_type' => 'VOLUNTEER', 'date' => '2026-07-11', 'start_time' => '10:00', 'end_time' => '18:00', 'duration_hours' => 8.00]);
|
||||
$fSlots['za_avond'] = TimeSlot::create(['event_id' => $festival->id, 'name' => 'Zaterdag Avond (Festival)', 'person_type' => 'VOLUNTEER', 'date' => '2026-07-11', 'start_time' => '18:00', 'end_time' => '02:00', 'duration_hours' => 8.00]);
|
||||
$fSlots['zo_dag'] = TimeSlot::create(['event_id' => $festival->id, 'name' => 'Zondag Dag (Festival)', 'person_type' => 'VOLUNTEER', 'date' => '2026-07-12', 'start_time' => '10:00', 'end_time' => '18:00', 'duration_hours' => 8.00]);
|
||||
$fSlots['zo_avond'] = TimeSlot::create(['event_id' => $festival->id, 'name' => 'Zondag Avond (Festival)', 'person_type' => 'VOLUNTEER', 'date' => '2026-07-12', 'start_time' => '18:00', 'end_time' => '22:00', 'duration_hours' => 4.00]);
|
||||
|
||||
// ── Sub-event time slots ──
|
||||
// ── Sub-event time slots (program-specific) ──
|
||||
|
||||
$ts = [];
|
||||
$ts['vr_early'] = TimeSlot::create(['event_id' => $vrijdag->id, 'name' => 'Vrijdag Early', 'person_type' => 'VOLUNTEER', 'date' => '2026-07-10', 'start_time' => '14:00', 'end_time' => '18:00', 'duration_hours' => 4.00]);
|
||||
$ts['vr_avond'] = TimeSlot::create(['event_id' => $vrijdag->id, 'name' => 'Vrijdag Avond', 'person_type' => 'VOLUNTEER', 'date' => '2026-07-10', 'start_time' => '18:00', 'end_time' => '02:00', 'duration_hours' => 8.00]);
|
||||
$ts['vr_pers'] = TimeSlot::create(['event_id' => $vrijdag->id, 'name' => 'Vrijdag Pers', 'person_type' => 'PRESS', 'date' => '2026-07-10', 'start_time' => '16:00', 'end_time' => '22:00', 'duration_hours' => 6.00]);
|
||||
$ts['za_dag'] = TimeSlot::create(['event_id' => $zaterdag->id, 'name' => 'Zaterdag Dag', 'person_type' => 'VOLUNTEER', 'date' => '2026-07-11', 'start_time' => '10:00', 'end_time' => '18:00', 'duration_hours' => 8.00]);
|
||||
$ts['za_avond'] = TimeSlot::create(['event_id' => $zaterdag->id, 'name' => 'Zaterdag Avond', 'person_type' => 'VOLUNTEER', 'date' => '2026-07-11', 'start_time' => '18:00', 'end_time' => '02:00', 'duration_hours' => 8.00]);
|
||||
$ts['za_crew'] = TimeSlot::create(['event_id' => $zaterdag->id, 'name' => 'Zaterdag Crew', 'person_type' => 'CREW', 'date' => '2026-07-11', 'start_time' => '08:00', 'end_time' => '20:00', 'duration_hours' => 12.00]);
|
||||
$ts['zo_dag'] = TimeSlot::create(['event_id' => $zondag->id, 'name' => 'Zondag Dag', 'person_type' => 'VOLUNTEER', 'date' => '2026-07-12', 'start_time' => '10:00', 'end_time' => '18:00', 'duration_hours' => 8.00]);
|
||||
$ts['zo_avond'] = TimeSlot::create(['event_id' => $zondag->id, 'name' => 'Zondag Avond', 'person_type' => 'VOLUNTEER', 'date' => '2026-07-12', 'start_time' => '18:00', 'end_time' => '22:00', 'duration_hours' => 4.00]);
|
||||
// Dag 1 — Vrijdag
|
||||
$ts['vr_middag'] = TimeSlot::create(['event_id' => $vrijdag->id, 'name' => 'Vrijdag middag — vrijwilliger', 'person_type' => 'VOLUNTEER', 'date' => '2026-07-10', 'start_time' => '12:00', 'end_time' => '18:00', 'duration_hours' => 6.00]);
|
||||
$ts['vr_avond'] = TimeSlot::create(['event_id' => $vrijdag->id, 'name' => 'Vrijdag avond — vrijwilliger', 'person_type' => 'VOLUNTEER', 'date' => '2026-07-10', 'start_time' => '18:00', 'end_time' => '02:00', 'duration_hours' => 8.00]);
|
||||
$ts['vr_crew'] = TimeSlot::create(['event_id' => $vrijdag->id, 'name' => 'Vrijdag avond — crew', 'person_type' => 'CREW', 'date' => '2026-07-10', 'start_time' => '17:00', 'end_time' => '03:00', 'duration_hours' => 10.00]);
|
||||
$ts['vr_pers'] = TimeSlot::create(['event_id' => $vrijdag->id, 'name' => 'Vrijdag pers', 'person_type' => 'PRESS', 'date' => '2026-07-10', 'start_time' => '16:00', 'end_time' => '22:00', 'duration_hours' => 6.00]);
|
||||
// Dag 2 — Zaterdag
|
||||
$ts['za_middag'] = TimeSlot::create(['event_id' => $zaterdag->id, 'name' => 'Zaterdag middag — vrijwilliger', 'person_type' => 'VOLUNTEER', 'date' => '2026-07-11', 'start_time' => '12:00', 'end_time' => '18:00', 'duration_hours' => 6.00]);
|
||||
$ts['za_avond'] = TimeSlot::create(['event_id' => $zaterdag->id, 'name' => 'Zaterdag avond — vrijwilliger', 'person_type' => 'VOLUNTEER', 'date' => '2026-07-11', 'start_time' => '18:00', 'end_time' => '02:00', 'duration_hours' => 8.00]);
|
||||
$ts['za_crew'] = TimeSlot::create(['event_id' => $zaterdag->id, 'name' => 'Zaterdag avond — crew', 'person_type' => 'CREW', 'date' => '2026-07-11', 'start_time' => '17:00', 'end_time' => '03:00', 'duration_hours' => 10.00]);
|
||||
// Dag 3 — Zondag
|
||||
$ts['zo_middag'] = TimeSlot::create(['event_id' => $zondag->id, 'name' => 'Zondag middag — vrijwilliger', 'person_type' => 'VOLUNTEER', 'date' => '2026-07-12', 'start_time' => '10:00', 'end_time' => '18:00', 'duration_hours' => 8.00]);
|
||||
$ts['zo_avond'] = TimeSlot::create(['event_id' => $zondag->id, 'name' => 'Zondag avond — vrijwilliger', 'person_type' => 'VOLUNTEER', 'date' => '2026-07-12', 'start_time' => '18:00', 'end_time' => '22:00', 'duration_hours' => 4.00]);
|
||||
|
||||
// ── Shifts (~55) ──
|
||||
|
||||
$allShifts = [];
|
||||
$s = []; // named shifts for explicit assignments
|
||||
|
||||
// EHBO: 6 shifts using festival-level volunteer time slots
|
||||
foreach (['vr_early', 'vr_avond', 'za_dag', 'za_avond', 'zo_dag', 'zo_avond'] as $key) {
|
||||
// EHBO (cross_event): shifts use sub-event time slots (cross_event exception)
|
||||
// + 1 festival-level shift for opbouw duties
|
||||
$s['ehbo_opbouw'] = Shift::create([
|
||||
'festival_section_id' => $ehbo->id, 'time_slot_id' => $fSlots['opbouw1']->id,
|
||||
'title' => 'EHBO Post', 'slots_total' => 2, 'slots_open_for_claiming' => 0, 'status' => 'open',
|
||||
]);
|
||||
$allShifts[] = $s['ehbo_opbouw'];
|
||||
foreach (['vr_middag', 'vr_avond', 'za_middag', 'za_avond', 'zo_middag'] as $key) {
|
||||
$shift = Shift::create([
|
||||
'festival_section_id' => $ehbo->id,
|
||||
'time_slot_id' => $fSlots[$key]->id,
|
||||
'time_slot_id' => $ts[$key]->id,
|
||||
'title' => 'EHBO Post',
|
||||
'slots_total' => $key === 'za_dag' ? 4 : 3,
|
||||
'slots_open_for_claiming' => $key === 'za_dag' ? 0 : 2,
|
||||
'slots_total' => $key === 'za_middag' ? 4 : 3,
|
||||
'slots_open_for_claiming' => $key === 'za_middag' ? 0 : 2,
|
||||
'status' => 'open',
|
||||
]);
|
||||
$allShifts[] = $shift;
|
||||
$s["ehbo_{$key}"] = $shift;
|
||||
}
|
||||
|
||||
// Nachtsecurity: 2 shifts
|
||||
// Security (cross_event): festival night shifts + sub-event crew shifts
|
||||
foreach (['nacht_vr', 'nacht_za'] as $key) {
|
||||
$shift = Shift::create([
|
||||
'festival_section_id' => $nachtsecurity->id,
|
||||
'festival_section_id' => $security->id,
|
||||
'time_slot_id' => $fSlots[$key]->id,
|
||||
'title' => 'Nachtbewaker',
|
||||
'title' => 'Beveiliger',
|
||||
'slots_total' => 6,
|
||||
'slots_open_for_claiming' => 0,
|
||||
'status' => 'open',
|
||||
]);
|
||||
$allShifts[] = $shift;
|
||||
$s["nacht_{$key}"] = $shift;
|
||||
$s["security_{$key}"] = $shift;
|
||||
}
|
||||
// Security shifts using sub-event CREW time slots (cross_event exception)
|
||||
foreach (['vr_crew', 'za_crew'] as $key) {
|
||||
$shift = Shift::create([
|
||||
'festival_section_id' => $security->id,
|
||||
'time_slot_id' => $ts[$key]->id,
|
||||
'title' => 'Beveiliger',
|
||||
'slots_total' => 4,
|
||||
'slots_open_for_claiming' => 0,
|
||||
'status' => 'open',
|
||||
]);
|
||||
$allShifts[] = $shift;
|
||||
$s["security_{$key}"] = $shift;
|
||||
}
|
||||
|
||||
// Terreinploeg: 3 shifts
|
||||
// Terreinploeg (standard on festival): shifts use festival time slots only
|
||||
foreach (['opbouw1', 'opbouw2', 'afbraak'] as $key) {
|
||||
$shift = Shift::create([
|
||||
'festival_section_id' => $terreinploeg->id,
|
||||
@@ -384,11 +400,11 @@ class DevSeeder extends Seeder
|
||||
$s["terrein_{$key}"] = $shift;
|
||||
}
|
||||
|
||||
// Accreditatiebalie: 4 shifts using festival-level volunteer time slots
|
||||
foreach (['vr_early', 'za_dag', 'zo_dag', 'za_avond'] as $key) {
|
||||
// Accreditatiebalie (cross_event): shifts use sub-event time slots
|
||||
foreach (['vr_middag', 'za_middag', 'zo_middag', 'za_avond'] as $key) {
|
||||
$shift = Shift::create([
|
||||
'festival_section_id' => $accreditatiebalie->id,
|
||||
'time_slot_id' => $fSlots[$key]->id,
|
||||
'time_slot_id' => $ts[$key]->id,
|
||||
'title' => 'Accreditatiemedewerker',
|
||||
'slots_total' => 3,
|
||||
'slots_open_for_claiming' => 2,
|
||||
@@ -400,9 +416,9 @@ class DevSeeder extends Seeder
|
||||
|
||||
// Sub-event shifts
|
||||
$slotMap = [
|
||||
'vrijdag' => ['vr_early', 'vr_avond'],
|
||||
'zaterdag' => ['za_dag', 'za_avond'],
|
||||
'zondag' => ['zo_dag', 'zo_avond'],
|
||||
'vrijdag' => ['vr_middag', 'vr_avond'],
|
||||
'zaterdag' => ['za_middag', 'za_avond'],
|
||||
'zondag' => ['zo_middag', 'zo_avond'],
|
||||
];
|
||||
|
||||
$locationMap = [
|
||||
@@ -579,17 +595,17 @@ class DevSeeder extends Seeder
|
||||
|
||||
$namedAssignments = [
|
||||
// Jan de Vries: 3 bar shifts
|
||||
['person' => $jan, 'shift' => 'hoofdbar_vr_early', 'status' => ShiftAssignmentStatus::APPROVED, 'auto' => true],
|
||||
['person' => $jan, 'shift' => 'hoofdbar_vr_middag', 'status' => ShiftAssignmentStatus::APPROVED, 'auto' => true],
|
||||
['person' => $jan, 'shift' => 'hoofdbar_vr_avond', 'status' => ShiftAssignmentStatus::APPROVED, 'auto' => false],
|
||||
['person' => $jan, 'shift' => 'hoofdbar_za_dag', 'status' => ShiftAssignmentStatus::APPROVED],
|
||||
['person' => $jan, 'shift' => 'hoofdbar_za_middag', 'status' => ShiftAssignmentStatus::APPROVED],
|
||||
// Lisa Bakker
|
||||
['person' => $lisaB, 'shift' => 'hoofdbar_vr_early', 'status' => ShiftAssignmentStatus::APPROVED, 'auto' => true],
|
||||
['person' => $lisaB, 'shift' => 'hoofdbar_za_dag', 'status' => ShiftAssignmentStatus::PENDING_APPROVAL],
|
||||
['person' => $lisaB, 'shift' => 'theaterbar_zo_dag', 'status' => ShiftAssignmentStatus::APPROVED, 'auto' => true],
|
||||
// Ahmed Hassan: 4 EHBO shifts
|
||||
['person' => $ahmedP, 'shift' => 'ehbo_vr_early', 'status' => ShiftAssignmentStatus::APPROVED],
|
||||
['person' => $lisaB, 'shift' => 'hoofdbar_vr_middag', 'status' => ShiftAssignmentStatus::APPROVED, 'auto' => true],
|
||||
['person' => $lisaB, 'shift' => 'hoofdbar_za_middag', 'status' => ShiftAssignmentStatus::PENDING_APPROVAL],
|
||||
['person' => $lisaB, 'shift' => 'theaterbar_zo_middag', 'status' => ShiftAssignmentStatus::APPROVED, 'auto' => true],
|
||||
// Ahmed Hassan: 4 EHBO shifts (cross_event section using sub-event time slots)
|
||||
['person' => $ahmedP, 'shift' => 'ehbo_vr_middag', 'status' => ShiftAssignmentStatus::APPROVED],
|
||||
['person' => $ahmedP, 'shift' => 'ehbo_vr_avond', 'status' => ShiftAssignmentStatus::APPROVED],
|
||||
['person' => $ahmedP, 'shift' => 'ehbo_za_dag', 'status' => ShiftAssignmentStatus::APPROVED],
|
||||
['person' => $ahmedP, 'shift' => 'ehbo_za_middag', 'status' => ShiftAssignmentStatus::APPROVED],
|
||||
['person' => $ahmedP, 'shift' => 'ehbo_za_avond', 'status' => ShiftAssignmentStatus::APPROVED],
|
||||
// Sara Jansen
|
||||
['person' => $saraJ, 'shift' => 'theaterbar_vr_avond', 'status' => ShiftAssignmentStatus::PENDING_APPROVAL],
|
||||
@@ -601,15 +617,15 @@ class DevSeeder extends Seeder
|
||||
['person' => $lotte, 'shift' => 'terrein_opbouw1', 'status' => ShiftAssignmentStatus::APPROVED, 'auto' => true],
|
||||
['person' => $lotte, 'shift' => 'terrein_afbraak', 'status' => ShiftAssignmentStatus::APPROVED, 'auto' => true],
|
||||
// Robin
|
||||
['person' => $robin, 'shift' => 'theaterbar_za_dag', 'status' => ShiftAssignmentStatus::APPROVED, 'auto' => true],
|
||||
// Klaas: nachtsecurity, assigned by Tom
|
||||
['person' => $klaas, 'shift' => 'nacht_nacht_vr', 'status' => ShiftAssignmentStatus::APPROVED, 'assigned_by' => $tom->id],
|
||||
// Dennis: nachtsecurity
|
||||
['person' => $dennis, 'shift' => 'nacht_nacht_za', 'status' => ShiftAssignmentStatus::APPROVED, 'assigned_by' => $tom->id],
|
||||
['person' => $robin, 'shift' => 'theaterbar_za_middag', 'status' => ShiftAssignmentStatus::APPROVED, 'auto' => true],
|
||||
// Klaas: security, assigned by Tom
|
||||
['person' => $klaas, 'shift' => 'security_nacht_vr', 'status' => ShiftAssignmentStatus::APPROVED, 'assigned_by' => $tom->id],
|
||||
// Dennis: security
|
||||
['person' => $dennis, 'shift' => 'security_nacht_za', 'status' => ShiftAssignmentStatus::APPROVED, 'assigned_by' => $tom->id],
|
||||
// Daan: rejected
|
||||
['person' => $daan, 'shift' => 'hoofdbar_vr_early', 'status' => ShiftAssignmentStatus::REJECTED, 'reason' => 'Nog niet goedgekeurd'],
|
||||
['person' => $daan, 'shift' => 'hoofdbar_vr_middag', 'status' => ShiftAssignmentStatus::REJECTED, 'reason' => 'Nog niet goedgekeurd'],
|
||||
// Emma: cancelled
|
||||
['person' => $emma, 'shift' => 'ingang_vr_early', 'status' => ShiftAssignmentStatus::CANCELLED],
|
||||
['person' => $emma, 'shift' => 'ingang_vr_middag', 'status' => ShiftAssignmentStatus::CANCELLED],
|
||||
// Pieter: podiumtechniek with overlap
|
||||
['person' => $pieter, 'shift' => 'podiumtechniek_vr_avond', 'status' => ShiftAssignmentStatus::APPROVED],
|
||||
['person' => $pieter, 'shift' => 'podiumtechniek_za_avond', 'status' => ShiftAssignmentStatus::APPROVED],
|
||||
@@ -642,10 +658,10 @@ class DevSeeder extends Seeder
|
||||
->limit(20)
|
||||
->get();
|
||||
|
||||
// EHBO Vrijdag Early: slots_total=3, target 4 approved (1 over)
|
||||
// EHBO Vrijdag Middag: slots_total=3, target 4 approved (1 over)
|
||||
// Already has 1 named approved (Ahmed). Add 3 more = 4 total.
|
||||
$ehboOverbookTarget = 3;
|
||||
$ehboShift = $s['ehbo_vr_early'];
|
||||
$ehboShift = $s['ehbo_vr_middag'];
|
||||
foreach ($overbookPersons->splice(0, $ehboOverbookTarget) as $person) {
|
||||
ShiftAssignment::create([
|
||||
'shift_id' => $ehboShift->id,
|
||||
@@ -768,7 +784,7 @@ class DevSeeder extends Seeder
|
||||
|
||||
// ── Volunteer availabilities (~70) ──
|
||||
|
||||
$volSlotKeys = ['vr_early', 'vr_avond', 'za_dag', 'za_avond', 'zo_dag', 'zo_avond'];
|
||||
$volSlotKeys = ['vr_middag', 'vr_avond', 'za_middag', 'za_avond', 'zo_middag', 'zo_avond'];
|
||||
$volSlots = collect($volSlotKeys)->map(fn (string $k) => $ts[$k]);
|
||||
|
||||
// Named availabilities
|
||||
@@ -777,7 +793,7 @@ class DevSeeder extends Seeder
|
||||
[$lisaB, $volSlots->random(5), fn () => rand(1, 5)],
|
||||
[$ahmedP, $volSlots, fn () => 5],
|
||||
[$saraJ, collect([$ts['vr_avond'], $ts['za_avond']]), fn () => rand(1, 5)],
|
||||
[$fatima, collect([$ts['za_dag'], $ts['za_avond'], $ts['zo_dag']]), fn () => rand(1, 5)],
|
||||
[$fatima, collect([$ts['za_middag'], $ts['za_avond'], $ts['zo_middag']]), fn () => rand(1, 5)],
|
||||
];
|
||||
|
||||
$usedAvails = [];
|
||||
@@ -904,7 +920,67 @@ class DevSeeder extends Seeder
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// Event 2: IJsbaan Winterpark (series, published, 60 persons)
|
||||
// Event 2: Braderie Dorpstown 2026 (flat event, registration_open)
|
||||
// =========================================================================
|
||||
|
||||
private function seedBraderie(): void
|
||||
{
|
||||
DB::transaction(function (): void {
|
||||
$this->command->info('Seeding Braderie Dorpstown 2026...');
|
||||
|
||||
$braderie = Event::create([
|
||||
'organisation_id' => $this->org->id,
|
||||
'name' => 'Braderie Dorpstown 2026',
|
||||
'slug' => 'braderie-dorpstown-2026',
|
||||
'start_date' => '2026-06-14',
|
||||
'end_date' => '2026-06-14',
|
||||
'timezone' => 'Europe/Amsterdam',
|
||||
'status' => 'registration_open',
|
||||
'event_type' => 'event',
|
||||
]);
|
||||
|
||||
// ── Time Slots (3) ──
|
||||
|
||||
$tsOchtend = TimeSlot::create(['event_id' => $braderie->id, 'name' => 'Zondag ochtend — vrijwilliger', 'person_type' => 'VOLUNTEER', 'date' => '2026-06-14', 'start_time' => '07:00', 'end_time' => '13:00', 'duration_hours' => 6.00]);
|
||||
$tsMiddag = TimeSlot::create(['event_id' => $braderie->id, 'name' => 'Zondag middag — vrijwilliger', 'person_type' => 'VOLUNTEER', 'date' => '2026-06-14', 'start_time' => '13:00', 'end_time' => '18:00', 'duration_hours' => 5.00]);
|
||||
$tsCrew = TimeSlot::create(['event_id' => $braderie->id, 'name' => 'Zondag — crew', 'person_type' => 'CREW', 'date' => '2026-06-14', 'start_time' => '06:00', 'end_time' => '20:00', 'duration_hours' => 14.00]);
|
||||
|
||||
// ── Sections (2) ──
|
||||
|
||||
$verkeersregelaars = FestivalSection::create([
|
||||
'event_id' => $braderie->id, 'name' => 'Verkeersregelaars', 'type' => 'standard',
|
||||
'category' => 'Veiligheid', 'icon' => 'tabler-traffic-cone', 'sort_order' => 1,
|
||||
'responder_self_checkin' => true, 'crew_auto_accepts' => false,
|
||||
'show_in_registration' => true, 'registration_description' => 'Verkeersregelaar bij de braderie',
|
||||
]);
|
||||
|
||||
$centraleBar = FestivalSection::create([
|
||||
'event_id' => $braderie->id, 'name' => 'Centrale bar', 'type' => 'standard',
|
||||
'category' => 'Bar', 'icon' => 'tabler-beer', 'sort_order' => 2,
|
||||
'responder_self_checkin' => true, 'crew_auto_accepts' => true,
|
||||
'show_in_registration' => true, 'registration_description' => 'Tappen en serveren bij de centrale bar',
|
||||
]);
|
||||
|
||||
// ── Shifts (4) ──
|
||||
|
||||
Shift::create(['festival_section_id' => $verkeersregelaars->id, 'time_slot_id' => $tsOchtend->id, 'title' => 'Verkeersregelaar', 'slots_total' => 4, 'slots_open_for_claiming' => 4, 'status' => 'open']);
|
||||
Shift::create(['festival_section_id' => $verkeersregelaars->id, 'time_slot_id' => $tsMiddag->id, 'title' => 'Verkeersregelaar', 'slots_total' => 4, 'slots_open_for_claiming' => 4, 'status' => 'open']);
|
||||
Shift::create(['festival_section_id' => $centraleBar->id, 'time_slot_id' => $tsOchtend->id, 'title' => 'Tapper', 'slots_total' => 6, 'slots_open_for_claiming' => 6, 'status' => 'open']);
|
||||
Shift::create(['festival_section_id' => $centraleBar->id, 'time_slot_id' => $tsMiddag->id, 'title' => 'Tapper', 'slots_total' => 6, 'slots_open_for_claiming' => 6, 'status' => 'open']);
|
||||
|
||||
// ── Persons (15) ──
|
||||
|
||||
$vol = $this->crowdTypes['VOLUNTEER']->id;
|
||||
Person::factory()->count(10)->approved()->create(['event_id' => $braderie->id, 'crowd_type_id' => $vol]);
|
||||
Person::factory()->count(3)->create(['event_id' => $braderie->id, 'crowd_type_id' => $vol, 'status' => 'pending']);
|
||||
Person::factory()->count(2)->create(['event_id' => $braderie->id, 'crowd_type_id' => $vol, 'status' => 'applied']);
|
||||
|
||||
$this->command->info(' Braderie Dorpstown 2026 complete');
|
||||
});
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// Event 3: IJsbaan Winterpark (series, published, 60 persons)
|
||||
// =========================================================================
|
||||
|
||||
private function seedIJsbaan(): void
|
||||
|
||||
Reference in New Issue
Block a user