mirror of
https://github.com/pacnpal/thrillwiki_laravel.git
synced 2025-12-20 09:51:10 -05:00
127 lines
7.6 KiB
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 |