feat: schema v1.7 + sections/shifts frontend

- Universeel festival/event model (parent_event_id, event_type)
- event_person_activations pivot tabel
- Event model: parent/children relaties + helper scopes
- DevSeeder: festival structuur met sub-events
- Sections & Shifts frontend (twee-kolom layout)
- BACKLOG.md aangemaakt met 22 gedocumenteerde wensen
This commit is contained in:
2026-04-08 07:23:56 +02:00
parent 6f69b30fb6
commit 6848bc2c49
19 changed files with 2560 additions and 87 deletions

View File

@@ -0,0 +1,64 @@
<?php
declare(strict_types=1);
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::table('events', function (Blueprint $table) {
$table->foreignUlid('parent_event_id')
->nullable()
->after('organisation_id')
->constrained('events')
->nullOnDelete();
$table->enum('event_type', ['event', 'festival', 'series'])
->default('event')
->after('status');
$table->string('event_type_label')
->nullable()
->after('event_type');
$table->string('sub_event_label')
->nullable()
->after('event_type_label');
$table->boolean('is_recurring')
->default(false)
->after('sub_event_label');
$table->string('recurrence_rule')
->nullable()
->after('is_recurring');
$table->json('recurrence_exceptions')
->nullable()
->after('recurrence_rule');
$table->index('parent_event_id');
});
}
public function down(): void
{
Schema::table('events', function (Blueprint $table) {
$table->dropForeign(['parent_event_id']);
$table->dropIndex(['parent_event_id']);
$table->dropColumn([
'parent_event_id',
'event_type',
'event_type_label',
'sub_event_label',
'is_recurring',
'recurrence_rule',
'recurrence_exceptions',
]);
});
}
};

View File

@@ -0,0 +1,28 @@
<?php
declare(strict_types=1);
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('event_person_activations', function (Blueprint $table) {
$table->id();
$table->foreignUlid('event_id')->constrained('events')->cascadeOnDelete();
$table->foreignUlid('person_id')->constrained('persons')->cascadeOnDelete();
$table->unique(['event_id', 'person_id']);
$table->index('person_id');
$table->index('event_id');
});
}
public function down(): void
{
Schema::dropIfExists('event_person_activations');
}
};

View File

@@ -5,6 +5,7 @@ declare(strict_types=1);
namespace Database\Seeders;
use App\Models\CrowdType;
use App\Models\Event;
use App\Models\Organisation;
use App\Models\User;
use Illuminate\Database\Seeder;
@@ -99,5 +100,59 @@ class DevSeeder extends Seeder
],
);
}
// 5. Flat event (backward compatible single event)
Event::firstOrCreate(
['organisation_id' => $org->id, 'slug' => 'test-event-01'],
[
'name' => 'Test Event 01',
'start_date' => '2026-08-15',
'end_date' => '2026-08-15',
'status' => 'draft',
'event_type' => 'event',
'parent_event_id' => null,
],
);
// 6. Festival with sub-events
$festival = Event::firstOrCreate(
['organisation_id' => $org->id, 'slug' => 'echt-zomer-feesten-2026'],
[
'name' => 'Echt Zomer Feesten 2026',
'start_date' => '2026-07-10',
'end_date' => '2026-07-11',
'status' => 'draft',
'event_type' => 'festival',
'event_type_label' => 'Festival',
'sub_event_label' => 'Programmaonderdeel',
'parent_event_id' => null,
],
);
// Sub-event 1: Dance Festival
Event::firstOrCreate(
['organisation_id' => $org->id, 'slug' => 'dance-festival-2026'],
[
'name' => 'Dance Festival',
'start_date' => '2026-07-10',
'end_date' => '2026-07-10',
'status' => 'draft',
'event_type' => 'event',
'parent_event_id' => $festival->id,
],
);
// Sub-event 2: Zomerfestival
Event::firstOrCreate(
['organisation_id' => $org->id, 'slug' => 'zomerfestival-2026'],
[
'name' => 'Zomerfestival',
'start_date' => '2026-07-11',
'end_date' => '2026-07-11',
'status' => 'draft',
'event_type' => 'event',
'parent_event_id' => $festival->id,
],
);
}
}