Commit 77c43332 authored by Mahmoud Aglan's avatar Mahmoud Aglan

Improve sort UX: visible arrows, name sorting via join, better hover

- Sort header component: blue active arrow, hover-to-reveal for inactive,
  cursor-pointer, group-hover animation
- Participant list: name column now sortable (joins people table)
- Trainer list: name column sortable (joins employees→people)
Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
parent a961e76d
...@@ -46,8 +46,16 @@ public function updatedCompensationModel(): void ...@@ -46,8 +46,16 @@ public function updatedCompensationModel(): void
public function render() public function render()
{ {
$query = Trainer::with(['employee.person', 'employee.branch', 'person']) $query = Trainer::with(['employee.person', 'employee.branch', 'person']);
->orderBy($this->sortBy, $this->sortDir);
if ($this->sortBy === 'name_ar') {
$query->join('employees', 'trainers.employee_id', '=', 'employees.id')
->join('people', 'employees.person_id', '=', 'people.id')
->orderBy('people.name_ar', $this->sortDir)
->select('trainers.*');
} else {
$query->orderBy($this->sortBy, $this->sortDir);
}
$query = app(PermissionService::class)->applyScope($query, auth()->user(), 'trainers.list'); $query = app(PermissionService::class)->applyScope($query, auth()->user(), 'trainers.list');
......
...@@ -73,8 +73,15 @@ public function render() ...@@ -73,8 +73,15 @@ public function render()
}) })
->when($this->status, fn ($q) => $q->where('status', $this->status)) ->when($this->status, fn ($q) => $q->where('status', $this->status))
->when($this->activity, fn ($q) => $q->where('primary_activity_id', $this->activity)) ->when($this->activity, fn ($q) => $q->where('primary_activity_id', $this->activity))
->when($this->skillLevel, fn ($q) => $q->where('skill_level', $this->skillLevel)) ->when($this->skillLevel, fn ($q) => $q->where('skill_level', $this->skillLevel));
->orderBy($this->sortBy, $this->sortDir);
if ($this->sortBy === 'name_ar') {
$query->join('people', 'participants.person_id', '=', 'people.id')
->orderBy('people.name_ar', $this->sortDir)
->select('participants.*');
} else {
$query->orderBy($this->sortBy, $this->sortDir);
}
$this->applyRoleScope($query); $this->applyRoleScope($query);
......
...@@ -2,12 +2,12 @@ ...@@ -2,12 +2,12 @@
<th {{ $attributes->merge(['class' => "px-4 py-3 text-{$align} font-medium text-gray-600"]) }}> <th {{ $attributes->merge(['class' => "px-4 py-3 text-{$align} font-medium text-gray-600"]) }}>
<button type="button" wire:click="sortColumn('{{ $column }}')" <button type="button" wire:click="sortColumn('{{ $column }}')"
class="inline-flex items-center gap-1 hover:text-gray-900 transition-colors"> class="inline-flex items-center gap-1.5 cursor-pointer hover:text-blue-600 transition-colors group">
{{ $slot }} {{ $slot }}
@if($sortBy === $column) @if($sortBy === $column)
<svg class="w-3.5 h-3.5 {{ $sortDir === 'asc' ? '' : 'rotate-180' }}" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M5.293 7.707a1 1 0 010-1.414l4-4a1 1 0 011.414 0l4 4a1 1 0 01-1.414 1.414L10 4.414 6.707 7.707a1 1 0 01-1.414 0z" clip-rule="evenodd"/></svg> <svg class="w-4 h-4 text-blue-600 {{ $sortDir === 'asc' ? '' : 'rotate-180' }}" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M5.293 7.707a1 1 0 010-1.414l4-4a1 1 0 011.414 0l4 4a1 1 0 01-1.414 1.414L10 4.414 6.707 7.707a1 1 0 01-1.414 0z" clip-rule="evenodd"/></svg>
@else @else
<svg class="w-3.5 h-3.5 text-gray-300" fill="currentColor" viewBox="0 0 20 20"><path d="M7 7l3-3 3 3m0 6l-3 3-3-3"/></svg> <svg class="w-4 h-4 text-gray-400 opacity-0 group-hover:opacity-100 transition-opacity" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4"/></svg>
@endif @endif
</button> </button>
</th> </th>
...@@ -45,7 +45,7 @@ class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 f ...@@ -45,7 +45,7 @@ class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 f
<table class="w-full text-sm"> <table class="w-full text-sm">
<thead class="bg-gray-50 border-b border-gray-200"> <thead class="bg-gray-50 border-b border-gray-200">
<tr> <tr>
<x-ui.sort-header column="trainer_number" :sortBy="$sortBy" :sortDir="$sortDir">{{ __('المدرب') }}</x-ui.sort-header> <x-ui.sort-header column="name_ar" :sortBy="$sortBy" :sortDir="$sortDir">{{ __('المدرب') }}</x-ui.sort-header>
<th class="px-4 py-3 text-start font-semibold text-gray-600">{{ __('الأنشطة') }}</th> <th class="px-4 py-3 text-start font-semibold text-gray-600">{{ __('الأنشطة') }}</th>
<x-ui.sort-header column="compensation_model" :sortBy="$sortBy" :sortDir="$sortDir">{{ __('نموذج التعويض') }}</x-ui.sort-header> <x-ui.sort-header column="compensation_model" :sortBy="$sortBy" :sortDir="$sortDir">{{ __('نموذج التعويض') }}</x-ui.sort-header>
<th class="px-4 py-3 text-start font-semibold text-gray-600">{{ __('التقييم') }}</th> <th class="px-4 py-3 text-start font-semibold text-gray-600">{{ __('التقييم') }}</th>
......
...@@ -62,7 +62,7 @@ class="w-full px-3 sm:px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 f ...@@ -62,7 +62,7 @@ class="w-full px-3 sm:px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 f
<thead class="bg-gray-50 border-b border-gray-200"> <thead class="bg-gray-50 border-b border-gray-200">
<tr> <tr>
<x-ui.sort-header column="participant_number" :sortBy="$sortBy" :sortDir="$sortDir">{{ __('رقم المشترك') }}</x-ui.sort-header> <x-ui.sort-header column="participant_number" :sortBy="$sortBy" :sortDir="$sortDir">{{ __('رقم المشترك') }}</x-ui.sort-header>
<th class="px-4 py-3 text-start font-medium text-gray-600">{{ __('الاسم') }}</th> <x-ui.sort-header column="name_ar" :sortBy="$sortBy" :sortDir="$sortDir">{{ __('الاسم') }}</x-ui.sort-header>
<th class="px-4 py-3 text-start font-medium text-gray-600">{{ __('النشاط') }}</th> <th class="px-4 py-3 text-start font-medium text-gray-600">{{ __('النشاط') }}</th>
<th class="px-4 py-3 text-center font-medium text-gray-600">{{ __('العضوية') }}</th> <th class="px-4 py-3 text-center font-medium text-gray-600">{{ __('العضوية') }}</th>
<x-ui.sort-header column="status" :sortBy="$sortBy" :sortDir="$sortDir" align="center">{{ __('الحالة') }}</x-ui.sort-header> <x-ui.sort-header column="status" :sortBy="$sortBy" :sortDir="$sortDir" align="center">{{ __('الحالة') }}</x-ui.sort-header>
......
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