Commit db7f16c6 authored by Mahmoud Aglan's avatar Mahmoud Aglan

Redesign facility grids as unified playground surfaces

Replace floating card buttons with a single sport-surface container that
feels like one field/court/pool divided by painted lines. Type-based
theming (green turf for fields, aqua for pools, tan for courts, neutral
for gyms). CSS component system via @theme + @layer components.
Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
parent 623e07e4
...@@ -311,8 +311,11 @@ public function render() ...@@ -311,8 +311,11 @@ public function render()
->get(); ->get();
} }
$facilityType = collect($this->facilities)->firstWhere('id', $this->selectedFacilityId)['type'] ?? 'other';
return view('livewire.facilities.space-assignment-wizard', [ return view('livewire.facilities.space-assignment-wizard', [
'searchResults' => $searchResults, 'searchResults' => $searchResults,
'facilityType' => $facilityType,
]); ]);
} }
} }
@import 'tailwindcss'; @import 'tailwindcss';
@theme {
--color-surface-field: oklch(0.95 0.025 145);
--color-surface-pool: oklch(0.94 0.035 220);
--color-surface-court: oklch(0.94 0.02 65);
--color-surface-neutral: oklch(0.96 0.005 260);
--color-boundary-field: oklch(0.40 0.12 150);
--color-boundary-pool: oklch(0.40 0.14 230);
--color-boundary-court: oklch(0.45 0.08 55);
--color-boundary-neutral: oklch(0.50 0.02 260);
--color-line-field: oklch(0.82 0.04 145);
--color-line-pool: oklch(0.78 0.06 220);
--color-line-court: oklch(0.80 0.03 60);
--color-line-neutral: oklch(0.85 0.008 260);
}
@layer components {
.facility-surface {
display: grid;
gap: 0;
border-radius: 1rem;
overflow: hidden;
border: 3px solid var(--surface-boundary);
box-shadow: inset 0 2px 12px oklch(0 0 0 / 0.06);
background: var(--surface-bg);
--surface-line: var(--color-line-neutral);
--surface-bg: var(--color-surface-neutral);
--surface-boundary: var(--color-boundary-neutral);
}
.facility-surface > * {
border-color: var(--surface-line);
}
.facility-surface--field,
.facility-surface--outdoor,
.facility-surface--track {
--surface-bg: var(--color-surface-field);
--surface-boundary: var(--color-boundary-field);
--surface-line: var(--color-line-field);
}
.facility-surface--pool {
--surface-bg: var(--color-surface-pool);
--surface-boundary: var(--color-boundary-pool);
--surface-line: var(--color-line-pool);
}
.facility-surface--court {
--surface-bg: var(--color-surface-court);
--surface-boundary: var(--color-boundary-court);
--surface-line: var(--color-line-court);
}
.facility-surface--gym,
.facility-surface--hall,
.facility-surface--room,
.facility-surface--other {
--surface-bg: var(--color-surface-neutral);
--surface-boundary: var(--color-boundary-neutral);
--surface-line: var(--color-line-neutral);
}
.facility-surface--lanes {
display: flex;
flex-direction: column;
}
.facility-surface--lanes > *:not(:last-child) {
border-bottom: 2px dashed var(--surface-line);
}
.facility-cell--unavailable {
background-image: repeating-linear-gradient(
-45deg,
transparent,
transparent 5px,
oklch(0.5 0 0 / 0.08) 5px,
oklch(0.5 0 0 / 0.08) 6px
);
}
.facility-cell--occupied {
background-image: repeating-linear-gradient(
-45deg,
transparent,
transparent 6px,
oklch(0.6 0.15 25 / 0.08) 6px,
oklch(0.6 0.15 25 / 0.08) 7px
);
}
.facility-cell--selected {
background-color: oklch(0.65 0.2 250 / 0.2);
box-shadow: inset 0 0 0 2.5px oklch(0.55 0.2 250 / 0.7);
}
.facility-cell--drop-target {
background-color: oklch(0.7 0.15 155 / 0.2);
box-shadow: inset 0 0 0 2.5px oklch(0.55 0.15 155 / 0.6);
}
}
@layer base { @layer base {
html { html {
direction: rtl; direction: rtl;
......
...@@ -229,10 +229,10 @@ class="p-5 rounded-xl border-2 border-gray-200 hover:border-blue-300 hover:bg-bl ...@@ -229,10 +229,10 @@ class="p-5 rounded-xl border-2 border-gray-200 hover:border-blue-300 hover:bg-bl
</div> </div>
</div> </div>
<!-- Grid Layout --> <!-- Grid Layout — Unified Surface -->
@if($layoutType === 'grid') @if($layoutType === 'grid')
<div class="grid gap-3 select-none" <div class="facility-surface facility-surface--{{ $facilityType }} select-none"
style="grid-template-columns: repeat({{ $gridCols }}, 1fr); grid-template-rows: repeat({{ $gridRows }}, 1fr);"> style="grid-template-columns: repeat({{ $gridCols }}, 1fr);">
@foreach($segments as $segment) @foreach($segments as $segment)
@php @php
$isSelected = in_array($segment['id'], $selectedSegmentIds); $isSelected = in_array($segment['id'], $selectedSegmentIds);
...@@ -241,34 +241,34 @@ class="p-5 rounded-xl border-2 border-gray-200 hover:border-blue-300 hover:bg-bl ...@@ -241,34 +241,34 @@ class="p-5 rounded-xl border-2 border-gray-200 hover:border-blue-300 hover:bg-bl
@endphp @endphp
<button wire:click="toggleSegment({{ $segment['id'] }})" type="button" <button wire:click="toggleSegment({{ $segment['id'] }})" type="button"
@class([ @class([
'relative aspect-square rounded-xl border-2 flex flex-col items-center justify-center transition-all duration-200 p-2', 'relative aspect-square flex flex-col items-center justify-center p-2 border-e border-b transition-all duration-150',
'border-blue-500 bg-blue-500 text-white shadow-lg shadow-blue-200 scale-[1.02]' => $isSelected, 'facility-cell--selected text-blue-900' => $isSelected,
'border-red-300 bg-red-50 text-red-400 cursor-not-allowed opacity-75' => $isOccupied, 'facility-cell--occupied bg-red-500/10 text-red-600/80 cursor-not-allowed' => $isOccupied,
'border-gray-300 bg-gray-100 text-gray-400 cursor-not-allowed' => $isUnavailable && !$isOccupied, 'facility-cell--unavailable text-gray-400 cursor-not-allowed opacity-50' => $isUnavailable && !$isOccupied,
'border-gray-200 bg-white text-gray-700 hover:border-blue-300 hover:bg-blue-50 hover:shadow-md cursor-pointer' => !$isSelected && !$isOccupied && !$isUnavailable, 'text-gray-700 hover:bg-white/40 cursor-pointer' => !$isSelected && !$isOccupied && !$isUnavailable,
]) ])
@disabled($isOccupied || $isUnavailable) @disabled($isOccupied || $isUnavailable)
title="{{ $isOccupied ? ($occupiedSegments[$segment['id']]['title'] ?? __('محجوز')) : $segment['name_ar'] }}"> title="{{ $isOccupied ? ($occupiedSegments[$segment['id']]['title'] ?? __('محجوز')) : $segment['name_ar'] }}">
@if($isSelected) @if($isSelected)
<svg class="absolute top-1.5 end-1.5 w-4 h-4 text-white" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/></svg> <svg class="absolute top-1.5 end-1.5 w-4 h-4 text-blue-600" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/></svg>
@endif @endif
@if($isOccupied) @if($isOccupied)
<svg class="w-5 h-5 mb-1" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z" clip-rule="evenodd"/></svg> <svg class="w-5 h-5 mb-1 text-red-400" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z" clip-rule="evenodd"/></svg>
@endif @endif
<span class="text-xs font-bold">{{ $segment['code'] }}</span> <span class="text-xs font-bold">{{ $segment['code'] }}</span>
<span class="text-[10px] mt-0.5 opacity-75">{{ $segment['name_ar'] }}</span> <span class="text-[10px] mt-0.5 opacity-70">{{ $segment['name_ar'] }}</span>
@if($segment['capacity']) @if($segment['capacity'])
<span class="text-[9px] mt-0.5 opacity-60">{{ $segment['capacity'] }} {{ __('فرد') }}</span> <span class="text-[9px] mt-0.5 opacity-50">{{ $segment['capacity'] }} {{ __('فرد') }}</span>
@endif @endif
</button> </button>
@endforeach @endforeach
</div> </div>
<!-- Lanes Layout --> <!-- Lanes Layout — Pool-like Surface -->
@elseif($layoutType === 'lanes') @elseif($layoutType === 'lanes')
<div class="space-y-3 select-none"> <div class="facility-surface facility-surface--lanes facility-surface--pool select-none">
@foreach($segments as $segment) @foreach($segments as $segment)
@php @php
$isSelected = in_array($segment['id'], $selectedSegmentIds); $isSelected = in_array($segment['id'], $selectedSegmentIds);
...@@ -277,32 +277,39 @@ class="p-5 rounded-xl border-2 border-gray-200 hover:border-blue-300 hover:bg-bl ...@@ -277,32 +277,39 @@ class="p-5 rounded-xl border-2 border-gray-200 hover:border-blue-300 hover:bg-bl
@endphp @endphp
<button wire:click="toggleSegment({{ $segment['id'] }})" type="button" <button wire:click="toggleSegment({{ $segment['id'] }})" type="button"
@class([ @class([
'w-full flex items-center gap-4 p-4 rounded-xl border-2 transition-all duration-200', 'w-full flex items-center gap-4 px-5 py-4 transition-all duration-150',
'border-blue-500 bg-blue-50 shadow-md' => $isSelected, 'facility-cell--selected' => $isSelected,
'border-red-300 bg-red-50 cursor-not-allowed opacity-75' => $isOccupied, 'facility-cell--occupied bg-red-500/10 cursor-not-allowed' => $isOccupied,
'border-gray-300 bg-gray-100 cursor-not-allowed' => $isUnavailable && !$isOccupied, 'facility-cell--unavailable cursor-not-allowed opacity-50' => $isUnavailable && !$isOccupied,
'border-gray-200 hover:border-blue-300 hover:bg-blue-50/50 cursor-pointer' => !$isSelected && !$isOccupied && !$isUnavailable, 'hover:bg-white/30 cursor-pointer' => !$isSelected && !$isOccupied && !$isUnavailable,
]) ])
@disabled($isOccupied || $isUnavailable)> @disabled($isOccupied || $isUnavailable)>
<div @class([ <div @class([
'w-10 h-10 rounded-lg flex items-center justify-center font-bold text-sm', 'w-10 h-10 rounded-full flex items-center justify-center font-bold text-sm border-2',
'bg-blue-600 text-white' => $isSelected, 'bg-blue-600/20 border-blue-500 text-blue-800' => $isSelected,
'bg-red-200 text-red-600' => $isOccupied, 'bg-red-500/15 border-red-300 text-red-600' => $isOccupied,
'bg-gray-200 text-gray-500' => !$isSelected && !$isOccupied, 'bg-white/50 border-current text-gray-600' => !$isSelected && !$isOccupied,
])>{{ $segment['lane_number'] ?? $segment['code'] }}</div> ])>{{ $segment['lane_number'] ?? $segment['code'] }}</div>
<div class="flex-1 text-start"> <div class="flex-1 text-start">
<p class="font-medium text-gray-900">{{ $segment['name_ar'] }}</p> <p class="font-medium {{ $isSelected ? 'text-blue-900' : 'text-gray-800' }}">{{ $segment['name_ar'] }}</p>
@if($segment['capacity'])
<p class="text-[10px] {{ $isSelected ? 'text-blue-600' : 'text-gray-400' }}">{{ $segment['capacity'] }} {{ __('فرد') }}</p>
@endif
</div> </div>
@if($isSelected) @if($isSelected)
<svg class="w-6 h-6 text-blue-600" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/></svg> <svg class="w-5 h-5 text-blue-600" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/></svg>
@endif
@if($isOccupied)
<svg class="w-5 h-5 text-red-400" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z" clip-rule="evenodd"/></svg>
@endif @endif
</button> </button>
@endforeach @endforeach
</div> </div>
<!-- Zones/Custom Layout --> <!-- Zones/Custom Layout — Unified Surface -->
@else @else
<div class="grid grid-cols-2 sm:grid-cols-3 gap-3 select-none"> <div class="facility-surface facility-surface--{{ $facilityType }} select-none"
style="grid-template-columns: repeat({{ min(count($segments), 3) }}, 1fr);">
@foreach($segments as $segment) @foreach($segments as $segment)
@php @php
$isSelected = in_array($segment['id'], $selectedSegmentIds); $isSelected = in_array($segment['id'], $selectedSegmentIds);
...@@ -311,15 +318,18 @@ class="p-5 rounded-xl border-2 border-gray-200 hover:border-blue-300 hover:bg-bl ...@@ -311,15 +318,18 @@ class="p-5 rounded-xl border-2 border-gray-200 hover:border-blue-300 hover:bg-bl
@endphp @endphp
<button wire:click="toggleSegment({{ $segment['id'] }})" type="button" <button wire:click="toggleSegment({{ $segment['id'] }})" type="button"
@class([ @class([
'p-4 rounded-xl border-2 transition-all duration-200 text-center', 'p-5 border-e border-b transition-all duration-150 text-center',
'border-blue-500 bg-blue-50 shadow-md' => $isSelected, 'facility-cell--selected text-blue-900' => $isSelected,
'border-red-300 bg-red-50 cursor-not-allowed opacity-75' => $isOccupied, 'facility-cell--occupied bg-red-500/10 text-red-600/80 cursor-not-allowed' => $isOccupied,
'border-gray-300 bg-gray-100 cursor-not-allowed' => $isUnavailable && !$isOccupied, 'facility-cell--unavailable text-gray-400 cursor-not-allowed opacity-50' => $isUnavailable && !$isOccupied,
'border-gray-200 hover:border-blue-300 hover:bg-blue-50/50 cursor-pointer' => !$isSelected && !$isOccupied && !$isUnavailable, 'text-gray-700 hover:bg-white/40 cursor-pointer' => !$isSelected && !$isOccupied && !$isUnavailable,
]) ])
@disabled($isOccupied || $isUnavailable)> @disabled($isOccupied || $isUnavailable)>
<p class="font-bold text-sm">{{ $segment['code'] }}</p> <p class="font-bold text-sm">{{ $segment['code'] }}</p>
<p class="text-xs mt-1 text-gray-600">{{ $segment['name_ar'] }}</p> <p class="text-xs mt-1 opacity-70">{{ $segment['name_ar'] }}</p>
@if($segment['capacity'] ?? null)
<p class="text-[9px] mt-1 opacity-50">{{ $segment['capacity'] }} {{ __('فرد') }}</p>
@endif
</button> </button>
@endforeach @endforeach
</div> </div>
...@@ -328,19 +338,19 @@ class="p-5 rounded-xl border-2 border-gray-200 hover:border-blue-300 hover:bg-bl ...@@ -328,19 +338,19 @@ class="p-5 rounded-xl border-2 border-gray-200 hover:border-blue-300 hover:bg-bl
<!-- Legend --> <!-- Legend -->
<div class="mt-6 flex flex-wrap gap-4 pt-4 border-t border-gray-100"> <div class="mt-6 flex flex-wrap gap-4 pt-4 border-t border-gray-100">
<div class="flex items-center gap-2 text-xs text-gray-600"> <div class="flex items-center gap-2 text-xs text-gray-600">
<div class="w-4 h-4 rounded border-2 border-gray-200 bg-white"></div> <div class="w-4 h-4 rounded bg-surface-field/60 border border-line-field"></div>
{{ __('متاح') }} {{ __('متاح') }}
</div> </div>
<div class="flex items-center gap-2 text-xs text-gray-600"> <div class="flex items-center gap-2 text-xs text-gray-600">
<div class="w-4 h-4 rounded border-2 border-blue-500 bg-blue-500"></div> <div class="w-4 h-4 rounded facility-cell--selected"></div>
{{ __('محدد') }} {{ __('محدد') }}
</div> </div>
<div class="flex items-center gap-2 text-xs text-gray-600"> <div class="flex items-center gap-2 text-xs text-gray-600">
<div class="w-4 h-4 rounded border-2 border-red-300 bg-red-50"></div> <div class="w-4 h-4 rounded facility-cell--occupied bg-red-500/10 border border-red-300"></div>
{{ __('محجوز') }} {{ __('محجوز') }}
</div> </div>
<div class="flex items-center gap-2 text-xs text-gray-600"> <div class="flex items-center gap-2 text-xs text-gray-600">
<div class="w-4 h-4 rounded border-2 border-gray-300 bg-gray-100"></div> <div class="w-4 h-4 rounded facility-cell--unavailable border border-gray-300"></div>
{{ __('غير متاح') }} {{ __('غير متاح') }}
</div> </div>
</div> </div>
......
...@@ -301,11 +301,12 @@ class="relative border rounded-xl p-3 sm:p-4 text-start transition-all hover:sha ...@@ -301,11 +301,12 @@ class="relative border rounded-xl p-3 sm:p-4 text-start transition-all hover:sha
$isGrid = $maxRow > 0 || $maxCol > 0; $isGrid = $maxRow > 0 || $maxCol > 0;
$cols = $isGrid ? $maxCol + 1 : count($gridSegments); $cols = $isGrid ? $maxCol + 1 : count($gridSegments);
$rows = $isGrid ? $maxRow + 1 : 1; $rows = $isGrid ? $maxRow + 1 : 1;
$surfaceType = $facility->type->value ?? 'other';
@endphp @endphp
<div class="overflow-x-auto"> <div class="overflow-x-auto">
<div class="{{ $isGrid ? 'grid gap-3' : 'flex flex-wrap gap-3' }} min-w-[400px]" <div class="facility-surface facility-surface--{{ $surfaceType }} min-w-[400px]"
style="{{ $isGrid ? 'grid-template-columns: repeat(' . $cols . ', minmax(0, 1fr)); grid-template-rows: repeat(' . $rows . ', minmax(120px, 1fr))' : '' }}"> style="grid-template-columns: repeat({{ $cols }}, minmax(0, 1fr)); {{ $isGrid ? 'grid-template-rows: repeat(' . $rows . ', minmax(120px, 1fr))' : '' }}">
@foreach($gridSegments as $seg) @foreach($gridSegments as $seg)
@php @php
$segAssignment = collect($assignments)->first(fn($a) => in_array($seg['id'], $a['segment_ids'] ?? [])); $segAssignment = collect($assignments)->first(fn($a) => in_array($seg['id'], $a['segment_ids'] ?? []));
...@@ -320,37 +321,37 @@ class="relative border rounded-xl p-3 sm:p-4 text-start transition-all hover:sha ...@@ -320,37 +321,37 @@ class="relative border rounded-xl p-3 sm:p-4 text-start transition-all hover:sha
@drop.prevent="dropOnSegment({{ $seg['id'] }})" @drop.prevent="dropOnSegment({{ $seg['id'] }})"
@click="toggleSegmentSelection({{ $seg['id'] }})" @click="toggleSegmentSelection({{ $seg['id'] }})"
:class="{ :class="{
'ring-2 ring-blue-400 bg-blue-50': selectedSegments.includes({{ $seg['id'] }}), 'facility-cell--selected': selectedSegments.includes({{ $seg['id'] }}),
'ring-2 ring-green-400 bg-green-50': highlightedSegment === {{ $seg['id'] }}, 'facility-cell--drop-target': highlightedSegment === {{ $seg['id'] }},
}" }"
class="relative border-2 rounded-xl p-3 min-h-[120px] flex flex-col transition-all cursor-pointer class="relative border-e border-b p-3 min-h-[120px] flex flex-col transition-all duration-150 cursor-pointer
{{ !$seg['available'] ? 'border-gray-300 bg-gray-100 cursor-not-allowed opacity-60' : '' }} {{ !$seg['available'] ? 'facility-cell--unavailable cursor-not-allowed opacity-50' : '' }}
{{ $isExisting ? 'border-blue-300 bg-blue-50' : '' }} {{ $isExisting ? 'bg-blue-500/15' : '' }}
{{ $isNewGroup ? 'border-green-300 bg-green-50' : '' }} {{ $isNewGroup ? 'bg-emerald-500/15' : '' }}
{{ $isNewTrainer ? 'border-purple-300 bg-purple-50' : '' }} {{ $isNewTrainer ? 'bg-purple-500/15' : '' }}
{{ !$isOccupied && $seg['available'] ? 'border-dashed border-gray-300 hover:border-blue-300 hover:bg-blue-50/30' : '' }}" {{ !$isOccupied && $seg['available'] ? 'hover:bg-white/30' : '' }}"
@if($isGrid) style="grid-row: {{ ($seg['row'] ?? 0) + 1 }}; grid-column: {{ ($seg['col'] ?? 0) + 1 }}" @endif @if($isGrid) style="grid-row: {{ ($seg['row'] ?? 0) + 1 }}; grid-column: {{ ($seg['col'] ?? 0) + 1 }}" @endif
> >
{{-- Cell header --}} {{-- Cell header --}}
<div class="flex items-center justify-between mb-1"> <div class="flex items-center justify-between mb-1">
<span class="text-xs font-mono text-gray-400">{{ $seg['code'] }}</span> <span class="text-xs font-mono opacity-50">{{ $seg['code'] }}</span>
@if($seg['capacity']) @if($seg['capacity'])
<span class="text-[10px] text-gray-400" dir="ltr">{{ $seg['capacity'] }}p</span> <span class="text-[10px] opacity-40" dir="ltr">{{ $seg['capacity'] }}p</span>
@endif @endif
</div> </div>
{{-- Existing reservation --}} {{-- Existing reservation --}}
@if($isExisting) @if($isExisting)
<div class="flex-1 flex flex-col justify-center"> <div class="flex-1 flex flex-col justify-center">
<p class="text-sm font-semibold text-blue-800 truncate">{{ $segAssignment['title'] ?? '' }}</p> <p class="text-sm font-semibold text-blue-900 truncate">{{ $segAssignment['title'] ?? '' }}</p>
@if($segAssignment['trainer_name'] ?? null) @if($segAssignment['trainer_name'] ?? null)
<p class="text-[10px] text-blue-600 mt-0.5 truncate"> <p class="text-[10px] text-blue-700 mt-0.5 truncate">
<svg class="w-3 h-3 inline" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"/></svg> <svg class="w-3 h-3 inline" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"/></svg>
{{ $segAssignment['trainer_name'] }} {{ $segAssignment['trainer_name'] }}
</p> </p>
@endif @endif
@if($segAssignment['is_recurring'] ?? false) @if($segAssignment['is_recurring'] ?? false)
<span class="inline-flex items-center gap-1 mt-1 text-[10px] text-purple-600"> <span class="inline-flex items-center gap-1 mt-1 text-[10px] text-purple-700">
<svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/></svg> <svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/></svg>
{{ __('متكرر') }} {{ __('متكرر') }}
</span> </span>
...@@ -359,40 +360,40 @@ class="relative border-2 rounded-xl p-3 min-h-[120px] flex flex-col transition-a ...@@ -359,40 +360,40 @@ class="relative border-2 rounded-xl p-3 min-h-[120px] flex flex-col transition-a
<div class="flex gap-1 mt-2"> <div class="flex gap-1 mt-2">
<button wire:click="cancelReservation({{ $segAssignment['reservation_id'] }})" <button wire:click="cancelReservation({{ $segAssignment['reservation_id'] }})"
wire:confirm="{{ __('إلغاء هذا الحجز؟') }}" wire:confirm="{{ __('إلغاء هذا الحجز؟') }}"
class="text-[10px] text-red-500 hover:text-red-700 hover:underline">{{ __('إلغاء') }}</button> class="text-[10px] text-red-600 hover:text-red-800 hover:underline">{{ __('إلغاء') }}</button>
@if($segAssignment['is_recurring'] ?? false) @if($segAssignment['is_recurring'] ?? false)
<button wire:click="cancelSeries({{ $segAssignment['reservation_id'] }})" <button wire:click="cancelSeries({{ $segAssignment['reservation_id'] }})"
wire:confirm="{{ __('إلغاء كل حجوزات هذه السلسلة المستقبلية؟') }}" wire:confirm="{{ __('إلغاء كل حجوزات هذه السلسلة المستقبلية؟') }}"
class="text-[10px] text-red-500 hover:text-red-700 hover:underline">{{ __('إلغاء السلسلة') }}</button> class="text-[10px] text-red-600 hover:text-red-800 hover:underline">{{ __('إلغاء السلسلة') }}</button>
@endif @endif
</div> </div>
{{-- New group assignment (unsaved) --}} {{-- New group assignment (unsaved) --}}
@elseif($isNewGroup) @elseif($isNewGroup)
<div class="flex-1 flex flex-col justify-center"> <div class="flex-1 flex flex-col justify-center">
<p class="text-sm font-semibold text-green-800 truncate">{{ $segAssignment['group_name'] ?? '' }}</p> <p class="text-sm font-semibold text-emerald-900 truncate">{{ $segAssignment['group_name'] ?? '' }}</p>
@if($segAssignment['implied_trainer'] ?? null) @if($segAssignment['implied_trainer'] ?? null)
<p class="text-[10px] text-green-600 mt-0.5 truncate"> <p class="text-[10px] text-emerald-700 mt-0.5 truncate">
<svg class="w-3 h-3 inline" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"/></svg> <svg class="w-3 h-3 inline" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"/></svg>
{{ $segAssignment['implied_trainer'] }} ({{ __('تلقائي') }}) {{ $segAssignment['implied_trainer'] }} ({{ __('تلقائي') }})
</p> </p>
@endif @endif
<span class="inline-flex items-center mt-1 text-[10px] text-green-600">{{ __('جديد — لم يُحفظ بعد') }}</span> <span class="inline-flex items-center mt-1 text-[10px] text-emerald-600">{{ __('جديد — لم يُحفظ بعد') }}</span>
</div> </div>
@php $assignIdx = collect($assignments)->search(fn($a) => ($a['type'] ?? '') === 'group' && ($a['group_id'] ?? null) === ($segAssignment['group_id'] ?? -1)); @endphp @php $assignIdx = collect($assignments)->search(fn($a) => ($a['type'] ?? '') === 'group' && ($a['group_id'] ?? null) === ($segAssignment['group_id'] ?? -1)); @endphp
@if($assignIdx !== false) @if($assignIdx !== false)
<button wire:click="removeAssignment({{ $assignIdx }})" class="text-[10px] text-red-500 hover:text-red-700 hover:underline mt-1">{{ __('إزالة') }}</button> <button wire:click="removeAssignment({{ $assignIdx }})" class="text-[10px] text-red-600 hover:text-red-800 hover:underline mt-1">{{ __('إزالة') }}</button>
@endif @endif
{{-- New trainer assignment (unsaved) --}} {{-- New trainer assignment (unsaved) --}}
@elseif($isNewTrainer) @elseif($isNewTrainer)
<div class="flex-1 flex flex-col justify-center"> <div class="flex-1 flex flex-col justify-center">
<p class="text-sm font-semibold text-purple-800 truncate">{{ $segAssignment['trainer_name'] ?? '' }}</p> <p class="text-sm font-semibold text-purple-900 truncate">{{ $segAssignment['trainer_name'] ?? '' }}</p>
<span class="inline-flex items-center mt-1 text-[10px] text-purple-600">{{ __('مدرب — لم يُحفظ بعد') }}</span> <span class="inline-flex items-center mt-1 text-[10px] text-purple-700">{{ __('مدرب — لم يُحفظ بعد') }}</span>
</div> </div>
@php $assignIdx = collect($assignments)->search(fn($a) => ($a['type'] ?? '') === 'trainer' && ($a['trainer_id'] ?? null) === ($segAssignment['trainer_id'] ?? -1)); @endphp @php $assignIdx = collect($assignments)->search(fn($a) => ($a['type'] ?? '') === 'trainer' && ($a['trainer_id'] ?? null) === ($segAssignment['trainer_id'] ?? -1)); @endphp
@if($assignIdx !== false) @if($assignIdx !== false)
<button wire:click="removeAssignment({{ $assignIdx }})" class="text-[10px] text-red-500 hover:text-red-700 hover:underline mt-1">{{ __('إزالة') }}</button> <button wire:click="removeAssignment({{ $assignIdx }})" class="text-[10px] text-red-600 hover:text-red-800 hover:underline mt-1">{{ __('إزالة') }}</button>
@endif @endif
{{-- Unavailable --}} {{-- Unavailable --}}
...@@ -404,8 +405,8 @@ class="text-[10px] text-red-500 hover:text-red-700 hover:underline">{{ __('إل ...@@ -404,8 +405,8 @@ class="text-[10px] text-red-500 hover:text-red-700 hover:underline">{{ __('إل
{{-- Empty / available --}} {{-- Empty / available --}}
@else @else
<div class="flex-1 flex items-center justify-center"> <div class="flex-1 flex items-center justify-center">
<span class="text-xs text-gray-400" x-show="!selectedSegments.includes({{ $seg['id'] }})">{{ __('اسحب مجموعة هنا') }}</span> <span class="text-xs opacity-40" x-show="!selectedSegments.includes({{ $seg['id'] }})">{{ __('اسحب مجموعة هنا') }}</span>
<span class="text-xs text-blue-600 font-medium" x-show="selectedSegments.includes({{ $seg['id'] }})">{{ __('محدد') }} ✓</span> <span class="text-xs text-blue-700 font-medium" x-show="selectedSegments.includes({{ $seg['id'] }})">{{ __('محدد') }} ✓</span>
</div> </div>
@endif @endif
</div> </div>
...@@ -415,16 +416,16 @@ class="text-[10px] text-red-500 hover:text-red-700 hover:underline">{{ __('إل ...@@ -415,16 +416,16 @@ class="text-[10px] text-red-500 hover:text-red-700 hover:underline">{{ __('إل
{{-- Legend --}} {{-- Legend --}}
<div class="mt-4 flex flex-wrap items-center gap-3 sm:gap-4 text-xs text-gray-500"> <div class="mt-4 flex flex-wrap items-center gap-3 sm:gap-4 text-xs text-gray-500">
<span class="flex items-center gap-1"><span class="w-3 h-3 border-2 border-dashed border-gray-300 rounded"></span> {{ __('متاح') }}</span> <span class="flex items-center gap-1.5"><span class="w-3.5 h-3.5 rounded bg-surface-field/60 border border-line-field"></span> {{ __('متاح') }}</span>
<span class="flex items-center gap-1"><span class="w-3 h-3 bg-blue-100 border border-blue-300 rounded"></span> {{ __('محجوز') }}</span> <span class="flex items-center gap-1.5"><span class="w-3.5 h-3.5 rounded bg-blue-500/15 border border-blue-400/50"></span> {{ __('محجوز') }}</span>
<span class="flex items-center gap-1"><span class="w-3 h-3 bg-green-100 border border-green-300 rounded"></span> {{ __('جديد (لم يُحفظ)') }}</span> <span class="flex items-center gap-1.5"><span class="w-3.5 h-3.5 rounded bg-emerald-500/15 border border-emerald-400/50"></span> {{ __('جديد (لم يُحفظ)') }}</span>
<span class="flex items-center gap-1"><span class="w-3 h-3 bg-purple-100 border border-purple-300 rounded"></span> {{ __('مدرب') }}</span> <span class="flex items-center gap-1.5"><span class="w-3.5 h-3.5 rounded bg-purple-500/15 border border-purple-400/50"></span> {{ __('مدرب') }}</span>
<span class="flex items-center gap-1"><span class="w-3 h-3 bg-gray-100 border border-gray-300 rounded"></span> {{ __('غير متاح') }}</span> <span class="flex items-center gap-1.5"><span class="w-3.5 h-3.5 rounded facility-cell--unavailable border border-gray-300"></span> {{ __('غير متاح') }}</span>
<span class="flex items-center gap-1"><span class="w-3 h-3 border-2 border-blue-400 rounded ring-2 ring-blue-400/30"></span> {{ __('محدد') }}</span> <span class="flex items-center gap-1.5"><span class="w-3.5 h-3.5 rounded facility-cell--selected"></span> {{ __('محدد') }}</span>
</div> </div>
{{-- Multi-select helper --}} {{-- Multi-select helper --}}
<div x-show="selectedSegments.length > 0" x-transition class="mt-4 bg-blue-50 border border-blue-200 rounded-xl p-3 sm:p-4"> <div x-show="selectedSegments.length > 0" x-transition class="mt-4 bg-blue-50/80 border border-blue-200 rounded-xl p-3 sm:p-4">
<p class="text-sm font-medium text-blue-800 mb-2"> <p class="text-sm font-medium text-blue-800 mb-2">
{{ __('تم تحديد') }} <span x-text="selectedSegments.length" class="font-bold"></span> {{ __('خلية') }} {{ __('تم تحديد') }} <span x-text="selectedSegments.length" class="font-bold"></span> {{ __('خلية') }}
</p> </p>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment