b2in/packages/flux-cms/components/resources/views/livewire/backend/navigation-manager.blade.php
2025-10-20 17:50:35 +02:00

229 lines
No EOL
9.7 KiB
PHP

<div class="space-y-6">
{{-- Header --}}
<div class="flex items-center justify-between">
<div>
<h1 class="text-2xl font-semibold text-gray-900">Navigation Manager</h1>
<p class="text-sm text-gray-500 mt-1">
Manage site navigation and menu structures
</p>
</div>
<div class="flex items-center space-x-3">
<flux:button wire:click="createNavigation" variant="primary">
Create Navigation
</flux:button>
</div>
</div>
{{-- Navigation Selector --}}
<flux:card>
<div class="flex items-center space-x-4">
<div class="flex-1">
<flux:select wire:model.live="selectedNavigationId" placeholder="Select Navigation">
@foreach($navigations as $nav)
<flux:option value="{{ $nav->id }}">{{ $nav->display_name }}</flux:option>
@endforeach
</flux:select>
</div>
@if($selectedNavigationId)
<flux:button wire:click="editNavigation({{ $selectedNavigationId }})" size="sm">
Edit Navigation
</flux:button>
<flux:button wire:click="deleteNavigation({{ $selectedNavigationId }})"
variant="danger" size="sm">
Delete
</flux:button>
@endif
</div>
</flux:card>
{{-- Navigation Items --}}
@if($selectedNavigationId && $navigationItems)
<flux:card>
<flux:card.header>
<div class="flex items-center justify-between">
<flux:heading size="lg">Navigation Items</flux:heading>
<flux:button wire:click="addNavigationItem" size="sm">
Add Item
</flux:button>
</div>
</flux:card.header>
<div class="space-y-2" wire:sortable="updateItemOrder">
@forelse($navigationItems as $item)
<div wire:sortable.item="{{ $item->id }}"
wire:key="nav-item-{{ $item->id }}"
class="nested-sortable-item">
@include('flux-cms-components::partials.navigation-item', ['item' => $item, 'level' => 0])
</div>
@empty
<div class="text-center py-8 text-gray-500">
<flux:icon.bars-3 class="w-12 h-12 mx-auto mb-3 text-gray-300" />
<p>No navigation items yet.</p>
<p class="text-sm">Click "Add Item" to create your first navigation item.</p>
</div>
@endforelse
</div>
</flux:card>
@endif
{{-- Navigation Form Modal --}}
<flux:modal name="navigation-form" class="md:w-2xl">
<div class="space-y-6">
<flux:heading size="lg">
{{ $editingNavigation ? 'Edit Navigation' : 'Create Navigation' }}
</flux:heading>
<div class="space-y-4">
<flux:field>
<flux:label>Name</flux:label>
<flux:input wire:model.live="navigationForm.name"
placeholder="main-menu" />
<flux:description>Unique identifier for this navigation (lowercase, no spaces)</flux:description>
<flux:error name="navigationForm.name" />
</flux:field>
<flux:field>
<flux:label>Display Name</flux:label>
<flux:input wire:model.live="navigationForm.display_name"
placeholder="Main Menu" />
<flux:description>Human-readable name for this navigation</flux:description>
<flux:error name="navigationForm.display_name" />
</flux:field>
<flux:field>
<flux:checkbox wire:model.live="navigationForm.is_active">
Active
</flux:checkbox>
<flux:description>Inactive navigations will not be displayed</flux:description>
</flux:field>
</div>
<div class="flex justify-end space-x-3">
<flux:button wire:click="$dispatch('close-modal')" variant="ghost">
Cancel
</flux:button>
<flux:button wire:click="saveNavigation" variant="primary">
{{ $editingNavigation ? 'Update' : 'Create' }}
</flux:button>
</div>
</div>
</flux:modal>
{{-- Navigation Item Form Modal --}}
<flux:modal name="navigation-item-form" class="md:w-2xl">
<div class="space-y-6">
<flux:heading size="lg">
{{ $editingItem ? 'Edit Navigation Item' : 'Add Navigation Item' }}
</flux:heading>
{{-- Language Tabs --}}
<div class="border-b border-gray-200">
<nav class="-mb-px flex space-x-8">
@foreach($availableLocales as $locale)
<button wire:click="setActiveLocale('{{ $locale }}')"
class="py-2 px-1 border-b-2 font-medium text-sm {{ $activeLocale === $locale ? 'border-blue-500 text-blue-600' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300' }}">
{{ strtoupper($locale) }}
</button>
@endforeach
</nav>
</div>
<div class="space-y-4">
{{-- Title (Translatable) --}}
<flux:field>
<flux:label>Title ({{ strtoupper($activeLocale) }})</flux:label>
<flux:input wire:model.live="itemForm.title.{{ $activeLocale }}"
placeholder="Navigation item title" />
<flux:error name="itemForm.title.{{ $activeLocale }}" />
</flux:field>
{{-- Link Type --}}
<flux:field>
<flux:label>Link Type</flux:label>
<flux:select wire:model.live="itemForm.link_type">
<flux:option value="page">Page</flux:option>
<flux:option value="url">Custom URL</flux:option>
<flux:option value="none">No Link</flux:option>
</flux:select>
</flux:field>
{{-- Page Selection --}}
@if($itemForm['link_type'] === 'page')
<flux:field>
<flux:label>Select Page</flux:label>
<flux:select wire:model.live="itemForm.page_id" placeholder="Choose a page">
@foreach($availablePages as $page)
<flux:option value="{{ $page->id }}">{{ $page->title }}</flux:option>
@endforeach
</flux:select>
<flux:error name="itemForm.page_id" />
</flux:field>
@endif
{{-- Custom URL --}}
@if($itemForm['link_type'] === 'url')
<flux:field>
<flux:label>URL</flux:label>
<flux:input wire:model.live="itemForm.url"
placeholder="https://example.com" />
<flux:error name="itemForm.url" />
</flux:field>
<flux:field>
<flux:label>Target</flux:label>
<flux:select wire:model.live="itemForm.target">
<flux:option value="_self">Same Window</flux:option>
<flux:option value="_blank">New Window</flux:option>
</flux:select>
</flux:field>
@endif
{{-- Parent Item --}}
<flux:field>
<flux:label>Parent Item</flux:label>
<flux:select wire:model.live="itemForm.parent_id" placeholder="No parent (top level)">
@foreach($this->getParentOptions() as $option)
<flux:option value="{{ $option['id'] }}">
{{ str_repeat('— ', $option['level']) }}{{ $option['title'] }}
</flux:option>
@endforeach
</flux:select>
<flux:description>Choose a parent to create a sub-menu item</flux:description>
</flux:field>
{{-- Settings --}}
<flux:field>
<flux:checkbox wire:model.live="itemForm.is_active">
Active
</flux:checkbox>
<flux:description>Inactive items will not be displayed</flux:description>
</flux:field>
</div>
<div class="flex justify-end space-x-3">
<flux:button wire:click="$dispatch('close-modal')" variant="ghost">
Cancel
</flux:button>
<flux:button wire:click="saveNavigationItem" variant="primary">
{{ $editingItem ? 'Update' : 'Add' }}
</flux:button>
</div>
</div>
</flux:modal>
</div>
@push('scripts')
<script>
document.addEventListener('DOMContentLoaded', function() {
// Initialize nested sortable
const initializeNestedSortable = () => {
// Implementation for nested drag & drop would go here
// You might want to use a library like SortableJS with nested support
};
initializeNestedSortable();
});
</script>
@endpush