Files
fotospiel-app/database/seeders/TaskCollectionsSeeder.php
Codex Agent 1a4bdb1fe1 tenant admin startseite schicker gestaltet und super-admin und tenant admin (filament) aufgesplittet.
Es gibt nun task collections und vordefinierte tasks für alle. Onboarding verfeinert und webseite-carousel gefixt (logging später entfernen!)
2025-10-14 15:17:52 +02:00

295 lines
12 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace Database\Seeders;
use App\Models\Emotion;
use App\Models\EventType;
use App\Models\Task;
use App\Models\TaskCollection;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
class TaskCollectionsSeeder extends Seeder
{
public function run(): void
{
$collections = [
[
'slug' => 'wedding-classics',
'event_type' => [
'slug' => 'wedding',
'name' => [
'de' => 'Hochzeit',
'en' => 'Wedding',
],
'icon' => 'lucide-heart',
],
'name' => [
'de' => 'Hochzeitsklassiker',
'en' => 'Wedding Classics',
],
'description' => [
'de' => 'Kuratierte Aufgaben rund um Trauung, Emotionen und besondere Momente.',
'en' => 'Curated prompts for vows, emotions, and memorable wedding highlights.',
],
'is_default' => true,
'position' => 10,
'tasks' => [
[
'slug' => 'wedding-first-look',
'title' => [
'de' => 'Erster Blick des Brautpaares festhalten',
'en' => 'Capture the couples first look',
],
'description' => [
'de' => 'Halte den Moment fest, in dem sich Braut und Bräutigam zum ersten Mal sehen.',
'en' => 'Capture the moment when the bride and groom see each other for the first time.',
],
'example' => [
'de' => 'Fotografiere die Reaktionen aus verschiedenen Blickwinkeln.',
'en' => 'Photograph their reactions from different angles.',
],
'emotion' => [
'name' => [
'de' => 'Romantik',
'en' => 'Romance',
],
'icon' => 'lucide-heart',
'color' => '#ec4899',
'sort_order' => 10,
],
'difficulty' => 'easy',
'sort_order' => 10,
],
[
'slug' => 'wedding-family-hug',
'title' => [
'de' => 'Familienumarmung organisieren',
'en' => 'Organise a family group hug',
],
'description' => [
'de' => 'Bitte die wichtigsten Menschen, das Paar gleichzeitig zu umarmen.',
'en' => 'Ask the closest friends and family to hug the couple at the same time.',
],
'example' => [
'de' => 'Kombiniere die Umarmung mit einem Toast.',
'en' => 'Combine the hug with a heartfelt toast.',
],
'emotion' => [
'name' => [
'de' => 'Freude',
'en' => 'Joy',
],
'icon' => 'lucide-smile',
'color' => '#f59e0b',
'sort_order' => 20,
],
'difficulty' => 'medium',
'sort_order' => 20,
],
[
'slug' => 'wedding-midnight-sparkler',
'title' => [
'de' => 'Mitternachtsfunkeln mit Wunderkerzen',
'en' => 'Midnight sparkler moment',
],
'description' => [
'de' => 'Verteile Wunderkerzen und schafft ein leuchtendes Spalier für das Paar.',
'en' => 'Hand out sparklers and form a glowing aisle for the couple.',
],
'example' => [
'de' => 'Koordiniere die Musik und kündige den Countdown an.',
'en' => 'Coordinate music and announce a countdown.',
],
'emotion' => [
'name' => [
'de' => 'Ekstase',
'en' => 'Euphoria',
],
'icon' => 'lucide-stars',
'color' => '#6366f1',
'sort_order' => 30,
],
'difficulty' => 'medium',
'sort_order' => 30,
],
],
],
[
'slug' => 'birthday-celebration',
'event_type' => [
'slug' => 'birthday',
'name' => [
'de' => 'Geburtstag',
'en' => 'Birthday',
],
'icon' => 'lucide-cake',
],
'name' => [
'de' => 'Geburtstags-Highlights',
'en' => 'Birthday Highlights',
],
'description' => [
'de' => 'Aufgaben für Überraschungen, Gratulationen und gemeinsames Feiern.',
'en' => 'Prompts covering surprises, wishes, and shared celebrations.',
],
'is_default' => false,
'position' => 20,
'tasks' => [
[
'slug' => 'birthday-surprise-wall',
'title' => [
'de' => 'Überraschungswand mit Polaroids gestalten',
'en' => 'Create a surprise wall filled with instant photos',
],
'description' => [
'de' => 'Sammle Schnappschüsse der Gäste und befestige sie als Fotowand.',
'en' => 'Collect snapshots from guests and mount them on a photo wall.',
],
'example' => [
'de' => 'Schreibe zu jedem Bild einen kurzen Gruß.',
'en' => 'Add a short message to each picture.',
],
'emotion' => [
'name' => [
'de' => 'Nostalgie',
'en' => 'Nostalgia',
],
'icon' => 'lucide-images',
'color' => '#f97316',
'sort_order' => 40,
],
'difficulty' => 'easy',
'sort_order' => 10,
],
[
'slug' => 'birthday-toast-circle',
'title' => [
'de' => 'Gratulationskreis mit kurzen Toasts',
'en' => 'Circle of toasts',
],
'description' => [
'de' => 'Bildet einen Kreis und bittet jede Person um einen 10-Sekunden-Toast.',
'en' => 'Form a circle and ask everyone for a 10-second toast.',
],
'example' => [
'de' => 'Nimm die Reaktionen als Video auf.',
'en' => 'Record the reactions on video.',
],
'emotion' => [
'name' => [
'de' => 'Dankbarkeit',
'en' => 'Gratitude',
],
'icon' => 'lucide-hands',
'color' => '#22c55e',
'sort_order' => 50,
],
'difficulty' => 'easy',
'sort_order' => 20,
],
],
],
];
DB::transaction(function () use ($collections) {
foreach ($collections as $definition) {
$eventType = $this->ensureEventType($definition['event_type']);
$collection = TaskCollection::updateOrCreate(
['slug' => $definition['slug']],
[
'tenant_id' => null,
'event_type_id' => $eventType->id,
'name_translations' => $definition['name'],
'description_translations' => $definition['description'],
'is_default' => $definition['is_default'] ?? false,
'position' => $definition['position'] ?? 0,
]
);
$syncPayload = [];
foreach ($definition['tasks'] as $taskDefinition) {
$emotion = $this->ensureEmotion($taskDefinition['emotion'] ?? [], $eventType->id);
$task = Task::updateOrCreate(
['slug' => $taskDefinition['slug']],
[
'tenant_id' => null,
'event_type_id' => $eventType->id,
'collection_id' => $collection->id,
'emotion_id' => $emotion?->id,
'title' => $taskDefinition['title'],
'description' => $taskDefinition['description'] ?? null,
'example_text' => $taskDefinition['example'] ?? null,
'difficulty' => $taskDefinition['difficulty'] ?? 'easy',
'priority' => 'medium',
'sort_order' => $taskDefinition['sort_order'] ?? 0,
'is_active' => true,
'is_completed' => false,
]
);
$syncPayload[$task->id] = ['sort_order' => $taskDefinition['sort_order'] ?? 0];
}
if (! empty($syncPayload)) {
$collection->tasks()->sync($syncPayload);
}
}
});
}
protected function ensureEventType(array $definition): EventType
{
$payload = [
'name' => $definition['name'],
'icon' => $definition['icon'] ?? null,
];
return EventType::updateOrCreate(
['slug' => $definition['slug']],
$payload
);
}
protected function ensureEmotion(array $definition, ?int $eventTypeId): ?Emotion
{
if (empty($definition)) {
return null;
}
$query = Emotion::query();
$name = $definition['name'] ?? [];
if (isset($name['en'])) {
$query->orWhere('name->en', $name['en']);
}
if (isset($name['de'])) {
$query->orWhere('name->de', $name['de']);
}
$emotion = $query->first();
if (! $emotion) {
$emotion = Emotion::create([
'name' => $name,
'icon' => $definition['icon'] ?? 'lucide-smile',
'color' => $definition['color'] ?? '#6366f1',
'description' => $definition['description'] ?? null,
'sort_order' => $definition['sort_order'] ?? 0,
'is_active' => true,
]);
}
if ($eventTypeId && ! $emotion->eventTypes()->where('event_type_id', $eventTypeId)->exists()) {
$emotion->eventTypes()->attach($eventTypeId);
}
return $emotion;
}
}