*/ public array $slideBullets = []; public string $slideDisclaimer = ''; public string $slideQrUrl = ''; public string $slideQrTitle = ''; public string $slideContact = ''; public bool $slideShowBrandText = false; public string $slideBrandTagline = ''; public bool $slideIsActive = true; // Settings Modal public bool $showSettingsModal = false; public array $settings = []; /** @var array */ public array $availableVideos = []; public function mount(DisplayVersion $displayVersion): void { $this->version = $displayVersion; $this->versionName = $displayVersion->name; $this->settings = $displayVersion->settings ?? []; if ($this->version->type === DisplayVersionType::VideoDisplay) { $this->loadAvailableVideos(); } } public function loadAvailableVideos(): void { $assetsPath = public_path('_cabinet/assets'); if (File::exists($assetsPath)) { $this->availableVideos = collect(File::files($assetsPath)) ->map(fn ($file) => $file->getFilename()) ->filter(fn ($filename) => in_array(pathinfo($filename, PATHINFO_EXTENSION), ['mp4', 'webm', 'mov'])) ->values() ->toArray(); } } public function toggleTheme(): void { $settings = $this->version->settings ?? []; $settings['theme'] = ($settings['theme'] ?? 'dark') === 'dark' ? 'light' : 'dark'; $this->version->update(['settings' => $settings]); $this->settings = $settings; } public function saveName(): void { $this->validate([ 'versionName' => 'required|string|max:255', ]); $this->version->update(['name' => $this->versionName]); session()->flash('success', 'Name aktualisiert!'); } // ======================================== // SETTINGS // ======================================== public function openSettingsModal(): void { $this->settings = $this->version->settings ?? []; $this->showSettingsModal = true; } public function saveSettings(): void { $this->version->update(['settings' => $this->settings]); $this->showSettingsModal = false; session()->flash('success', 'Einstellungen gespeichert!'); } // ======================================== // ITEM CRUD // ======================================== public function openItemModal(?int $id = null, string $type = ''): void { $this->resetItemForm(); if ($id) { $item = DisplayVersionItem::findOrFail($id); $this->itemId = $item->id; $this->itemType = $item->item_type; $this->loadItemContent($item); } else { $this->itemType = $type ?: $this->defaultItemType(); } $this->showItemModal = true; } public function saveItem(): void { $content = $this->buildItemContent(); $isActive = $this->getActiveFlag(); if ($this->itemId) { $item = DisplayVersionItem::findOrFail($this->itemId); $item->update([ 'content' => $content, 'is_active' => $isActive, ]); session()->flash('success', 'Inhalt aktualisiert!'); } else { $maxSort = DisplayVersionItem::where('display_version_id', $this->version->id) ->where('item_type', $this->itemType) ->max('sort_order') ?? -1; DisplayVersionItem::create([ 'display_version_id' => $this->version->id, 'item_type' => $this->itemType, 'content' => $content, 'sort_order' => $maxSort + 1, 'is_active' => $isActive, ]); session()->flash('success', 'Inhalt hinzugefügt!'); } $this->closeItemModal(); } public function deleteItem(int $id): void { DisplayVersionItem::findOrFail($id)->delete(); session()->flash('success', 'Inhalt gelöscht!'); } public function toggleItemStatus(int $id): void { $item = DisplayVersionItem::findOrFail($id); $item->update(['is_active' => ! $item->is_active]); } public function moveItem(int $id, string $direction): void { $item = DisplayVersionItem::findOrFail($id); $currentOrder = $item->sort_order; $swapItem = DisplayVersionItem::where('display_version_id', $this->version->id) ->where('item_type', $item->item_type) ->where('sort_order', $direction === 'up' ? $currentOrder - 1 : $currentOrder + 1) ->first(); if ($swapItem) { $item->update(['sort_order' => $swapItem->sort_order]); $swapItem->update(['sort_order' => $currentOrder]); } } #[On('display-media-selected')] public function onDisplayMediaSelected(string $field, ?int $mediaId, ?string $url): void { if (! $url) { return; } match ($field) { 'videoFilename' => $this->videoFilename = $url, 'mediaUrl' => $this->mediaUrl = $url, 'slideImageUrl' => $this->slideImageUrl = $url, default => null, }; } public function addBullet(): void { $this->slideBullets[] = ''; } public function removeBullet(int $index): void { unset($this->slideBullets[$index]); $this->slideBullets = array_values($this->slideBullets); } public function closeItemModal(): void { $this->showItemModal = false; $this->resetItemForm(); } // ======================================== // HELPERS // ======================================== private function loadItemContent(DisplayVersionItem $item): void { $content = $item->content; match ($item->item_type) { 'video' => $this->loadVideoContent($content), 'footer' => $this->loadFooterContent($content), 'media' => $this->loadMediaContent($content), 'slide' => $this->loadSlideContent($content), default => null, }; } private function loadVideoContent(array $content): void { $this->videoFilename = $content['filename'] ?? ''; $this->videoTitle = $content['title'] ?? ''; $this->videoPosition = $content['position'] ?? 25; $this->videoIsActive = true; } private function loadFooterContent(array $content): void { $this->footerHeadline = $content['headline'] ?? ''; $this->footerSubline = $content['subline'] ?? ''; $this->footerUrl = $content['url'] ?? ''; $this->footerIsActive = true; } private function loadMediaContent(array $content): void { $this->mediaType = $content['media_type'] ?? 'image'; $this->mediaCategory = $content['category'] ?? 'immobilien'; $this->mediaUrl = $content['media_url'] ?? ''; $this->mediaHeadline = $content['headline'] ?? ''; $this->mediaSubline = $content['subline'] ?? ''; $this->mediaDuration = $content['duration_seconds'] ?? 10; $this->mediaIsActive = true; } private function loadSlideContent(array $content): void { $this->slideType = $content['type'] ?? 'product-hero'; $this->slideDuration = $content['duration'] ?? 8000; $this->slideImageUrl = $content['image_url'] ?? ''; $this->slideBadge = $content['badge_text'] ?? ''; $this->slideEyebrow = $content['eyebrow'] ?? ''; $this->slideTitle = $content['title'] ?? ''; $this->slideSubline = $content['subline'] ?? ''; $this->slidePrice = $content['price'] ?? ''; $this->slideOriginalPrice = $content['original_price'] ?? ''; $this->slideTagText = $content['tag_text'] ?? ''; $this->slideBullets = $content['bullets'] ?? []; $this->slideDisclaimer = $content['disclaimer'] ?? ''; $this->slideQrUrl = $content['qr_url'] ?? ''; $this->slideQrTitle = $content['qr_title'] ?? ''; $this->slideContact = $content['contact'] ?? ''; $this->slideShowBrandText = $content['show_brand_text'] ?? false; $this->slideBrandTagline = $content['brand_tagline'] ?? ''; $this->slideIsActive = true; } /** * @return array */ private function buildItemContent(): array { return match ($this->itemType) { 'video' => [ 'filename' => $this->videoFilename, 'title' => $this->videoTitle, 'position' => $this->videoPosition, ], 'footer' => [ 'headline' => $this->footerHeadline, 'subline' => $this->footerSubline, 'url' => $this->footerUrl ?: null, ], 'media' => [ 'media_type' => $this->mediaType, 'category' => $this->mediaCategory, 'media_url' => $this->mediaUrl, 'headline' => $this->mediaHeadline, 'subline' => $this->mediaSubline, 'duration_seconds' => $this->mediaDuration, ], 'slide' => [ 'type' => $this->slideType, 'duration' => $this->slideDuration, 'image_url' => $this->slideImageUrl, 'badge_text' => $this->slideBadge, 'eyebrow' => $this->slideEyebrow, 'title' => $this->slideTitle, 'subline' => $this->slideSubline, 'price' => $this->slidePrice, 'original_price' => $this->slideOriginalPrice, 'tag_text' => $this->slideTagText, 'bullets' => $this->slideBullets, 'disclaimer' => $this->slideDisclaimer, 'qr_url' => $this->slideQrUrl, 'qr_title' => $this->slideQrTitle, 'contact' => $this->slideContact, 'show_brand_text' => $this->slideShowBrandText, 'brand_tagline' => $this->slideBrandTagline, ], default => [], }; } private function getActiveFlag(): bool { return match ($this->itemType) { 'video' => $this->videoIsActive, 'footer' => $this->footerIsActive, 'media' => $this->mediaIsActive, 'slide' => $this->slideIsActive, default => true, }; } private function defaultItemType(): string { return match ($this->version->type) { DisplayVersionType::VideoDisplay => 'video', DisplayVersionType::B2in => 'media', DisplayVersionType::Offers => 'slide', }; } private function resetItemForm(): void { $this->itemId = null; $this->itemType = ''; $this->videoFilename = ''; $this->videoTitle = ''; $this->videoPosition = 25; $this->videoIsActive = true; $this->footerHeadline = ''; $this->footerSubline = ''; $this->footerUrl = ''; $this->footerIsActive = true; $this->mediaType = 'image'; $this->mediaCategory = 'immobilien'; $this->mediaUrl = ''; $this->mediaHeadline = ''; $this->mediaSubline = ''; $this->mediaDuration = 10; $this->mediaIsActive = true; $this->slideType = 'product-hero'; $this->slideDuration = 8000; $this->slideImageUrl = ''; $this->slideBadge = ''; $this->slideEyebrow = ''; $this->slideTitle = ''; $this->slideSubline = ''; $this->slidePrice = ''; $this->slideOriginalPrice = ''; $this->slideTagText = ''; $this->slideBullets = []; $this->slideDisclaimer = ''; $this->slideQrUrl = ''; $this->slideQrTitle = ''; $this->slideContact = ''; $this->slideShowBrandText = false; $this->slideBrandTagline = ''; $this->slideIsActive = true; } public function render() { $items = $this->version->items()->get()->groupBy('item_type'); return view('livewire.admin.cms.display-version-editor', [ 'items' => $items, ]); } }