Files
thrillwiki_laravel/resources/views/livewire/park-area-reorder-component.blade.php

127 lines
7.6 KiB
PHP

<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<!-- Header -->
<div class="flex items-center justify-between mb-6">
<div>
<h2 class="text-xl font-semibold text-gray-900">
@if($parentArea)
Areas in {{ $parentArea->name }}
<a href="{{ route('parks.areas.reorder', ['park' => $park]) }}" class="text-sm text-indigo-600 hover:text-indigo-900">
(Back to Top Level)
</a>
@else
Areas in {{ $park->name }}
@endif
</h2>
<p class="mt-1 text-sm text-gray-500">Drag and drop to reorder areas or move them between levels.</p>
</div>
</div>
<!-- Areas List -->
<div class="bg-white shadow-sm ring-1 ring-gray-900/5 rounded-xl overflow-hidden">
@if(empty($areas))
<div class="text-center py-12">
<h3 class="text-lg font-medium text-gray-900">No areas found</h3>
<p class="mt-2 text-sm text-gray-500">
@if($parentArea)
This area doesn't have any sub-areas yet.
@else
This park doesn't have any areas yet.
@endif
</p>
</div>
@else
<ul id="sortable-areas" class="divide-y divide-gray-200" wire:sortable wire:end.stop="reorder($event.target.sortable.toArray())">
@foreach($areas as $area)
<li wire:key="area-{{ $area['id'] }}" wire:sortable.item="{{ $area['id'] }}" data-id="{{ $area['id'] }}"
class="group p-4 sm:p-6 hover:bg-gray-50 cursor-move">
<div class="flex items-center justify-between">
<div class="flex items-center space-x-3">
<!-- Drag Handle -->
<div wire:sortable.handle class="cursor-grab">
<svg class="h-5 w-5 text-gray-400 group-hover:text-gray-500" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16m-7 6h7" />
</svg>
</div>
<!-- Area Name -->
<div class="min-w-0 flex-1">
<h3 class="text-lg font-medium text-gray-900 truncate">
{{ $area['name'] }}
@if($area['is_closed'])
<span class="ml-2 inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-red-100 text-red-800">
Closed
</span>
@endif
</h3>
</div>
</div>
<div class="flex items-center space-x-3">
<!-- Sub-Areas Link -->
@if($area['has_children'])
<a href="{{ route('parks.areas.reorder', ['park' => $park, 'parentId' => $area['id']]) }}"
class="inline-flex items-center px-3 py-2 border border-gray-300 shadow-sm text-sm leading-4 font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
<svg class="-ml-0.5 mr-2 h-4 w-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
</svg>
Sub-Areas
</a>
@endif
<!-- Move Actions -->
<div class="relative" x-data="{ open: false }">
<button @click="open = !open" type="button"
class="inline-flex items-center px-3 py-2 border border-gray-300 shadow-sm text-sm leading-4 font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
Move To
<svg class="ml-2 -mr-0.5 h-4 w-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 9l4-4 4 4m0 6l-4 4-4-4" />
</svg>
</button>
<div x-show="open" @click.away="open = false"
class="origin-top-right absolute right-0 mt-2 w-48 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 divide-y divide-gray-100 focus:outline-none"
role="menu" aria-orientation="vertical" aria-labelledby="move-button-{{ $area['id'] }}">
<div class="py-1" role="none">
@if($parentArea)
<button wire:click="moveToParent({{ $area['id'] }}, null)" class="text-gray-700 group flex items-center px-4 py-2 text-sm w-full hover:bg-gray-100" role="menuitem">
Move to Top Level
</button>
@endif
@foreach($areas as $targetArea)
@if($targetArea['id'] !== $area['id'] && !$targetArea['is_closed'])
<button wire:click="moveToParent({{ $area['id'] }}, {{ $targetArea['id'] }})" class="text-gray-700 group flex items-center px-4 py-2 text-sm w-full hover:bg-gray-100" role="menuitem">
Move to {{ $targetArea['name'] }}
</button>
@endif
@endforeach
</div>
</div>
</div>
</div>
</div>
</li>
@endforeach
</ul>
@endif
</div>
</div>
@push('scripts')
<script src="https://cdn.jsdelivr.net/npm/sortablejs@1.15.0/Sortable.min.js"></script>
<script>
document.addEventListener('livewire:init', () => {
let sortable = new Sortable(document.getElementById('sortable-areas'), {
animation: 150,
handle: '[wire\\:sortable\\.handle]',
draggable: '[wire\\:sortable\\.item]',
onEnd: function(evt) {
const items = Array.from(evt.to.children).map(item => item.dataset.id);
evt.to.dispatchEvent(new CustomEvent('end.stop', {
detail: { items },
bubbles: true,
}));
},
});
});
</script>
@endpush