mirror of
https://github.com/pacnpal/thrillwiki_laravel.git
synced 2025-12-20 11:31:09 -05:00
Add models, enums, and services for user roles, theme preferences, slug history, and ID generation
This commit is contained in:
127
resources/views/livewire/park-area-reorder-component.blade.php
Normal file
127
resources/views/livewire/park-area-reorder-component.blade.php
Normal file
@@ -0,0 +1,127 @@
|
||||
<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
|
||||
Reference in New Issue
Block a user