redirect(TenantOnboarding::getUrl()); return; } $firstEventId = $tenant->events()->orderBy('date')->value('id'); $this->selectedEventId = $firstEventId; $this->layouts = $this->buildLayouts(); if ($this->selectedEventId) { $this->loadEventContext(); } } public static function shouldRegisterNavigation(): bool { return TenantOnboardingState::completed(); } public function updatedSelectedEventId(): void { $this->loadEventContext(); } public function createInvite(EventJoinTokenService $service): void { $this->validate([ 'selectedEventId' => ['required', 'exists:events,id'], 'tokenLabel' => ['nullable', 'string', 'max:120'], ]); $tenant = TenantOnboardingState::tenant(); abort_if(! $tenant, 403); $event = $tenant->events()->whereKey($this->selectedEventId)->first(); if (! $event) { Notification::make() ->title('Event konnte nicht gefunden werden') ->danger() ->send(); return; } $label = $this->tokenLabel ?: 'Einladung ' . now()->format('d.m.'); $layoutPreference = Arr::get($tenant->settings ?? [], 'branding.preferred_invite_layout'); $service->createToken($event, [ 'label' => $label, 'metadata' => [ 'preferred_layout' => $layoutPreference, ], 'created_by' => auth()->id(), ]); $this->tokenLabel = ''; $this->loadEventContext(); Notification::make() ->title('Neuer Einladungslink erstellt') ->success() ->send(); } protected function loadEventContext(): void { $tenant = TenantOnboardingState::tenant(); if (! $tenant || ! $this->selectedEventId) { $this->tokens = []; return; } $event = $tenant->events()->whereKey($this->selectedEventId)->first(); if (! $event) { $this->tokens = []; return; } $this->tokens = $event->joinTokens() ->orderByDesc('created_at') ->get() ->map(fn (EventJoinToken $token) => $this->mapToken($event, $token)) ->toArray(); } protected function mapToken(Event $event, EventJoinToken $token): array { $downloadUrls = JoinTokenLayoutRegistry::toResponse(function (string $layoutId, string $format) use ($event, $token) { return route('tenant.events.join-tokens.layouts.download', [ 'event' => $event->slug, 'joinToken' => $token->getKey(), 'layout' => $layoutId, 'format' => $format, ]); }); return [ 'id' => $token->getKey(), 'label' => $token->label ?? 'Einladungslink', 'url' => URL::to('/e/' . $token->token), 'created_at' => optional($token->created_at)->format('d.m.Y H:i'), 'usage_count' => $token->usage_count, 'usage_limit' => $token->usage_limit, 'active' => $token->isActive(), 'downloads' => $downloadUrls, ]; } protected function buildLayouts(): array { return collect(JoinTokenLayoutRegistry::all()) ->map(fn (array $layout) => [ 'id' => $layout['id'], 'name' => $layout['name'], 'subtitle' => $layout['subtitle'] ?? '', 'description' => $layout['description'] ?? '', ]) ->toArray(); } public function getEventsProperty(): Collection { $tenant = TenantOnboardingState::tenant(); if (! $tenant) { return collect(); } return $tenant->events()->orderBy('date')->get(); } }