Commit 13c77bfa authored by Mahmoud Aglan's avatar Mahmoud Aglan

Bulk transfer wizard: move multiple participants between groups

Rebuilt the transfer wizard to support selecting multiple participants
from a source group and moving them all to a destination group at once.
Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
parent 4a57a333
......@@ -2,7 +2,6 @@
namespace App\Livewire\Enrollments;
use App\Domain\Financial\Models\Invoice;
use App\Domain\Financial\Services\InvoiceService;
use App\Domain\Participant\Models\Participant;
use App\Domain\Pricing\Services\PricingService;
......@@ -16,38 +15,43 @@
use Livewire\Component;
#[Layout('layouts.app')]
#[Title('نقل مشترك')]
#[Title('نقل مشتركين')]
class TransferParticipantWizard extends Component
{
public int $currentStep = 1;
public int $totalSteps = 4;
public bool $completed = false;
// Step 1: Select Participant & Enrollment
// Mode: 'single' or 'bulk'
public string $mode = 'bulk';
// Step 1: Source selection
public ?int $sourceGroupId = null;
public ?array $sourceGroupInfo = null;
public string $participantSearch = '';
public ?int $participantId = null;
public ?int $enrollmentId = null;
// Selected participants (enrollment_id => participant info)
public array $selectedParticipants = [];
public bool $selectAll = false;
// Single mode
public ?int $singleParticipantId = null;
public ?int $singleEnrollmentId = null;
public ?array $singleParticipantInfo = null;
public array $singleEnrollments = [];
// Step 2: Destination
public ?int $destinationProgramId = null;
public ?int $destinationGroupId = null;
public ?array $destinationGroupInfo = null;
// Step 3: Impact & Reason
// Step 3: Reason
public string $reason = '';
// Price difference
public int $sourceProgramPrice = 0;
public int $destinationProgramPrice = 0;
public int $priceDifference = 0;
public bool $requiresPayment = false;
// Cached data for display
public ?array $selectedParticipant = null;
public array $activeEnrollments = [];
public ?array $selectedEnrollment = null;
public ?array $sourceGroup = null;
public ?array $destinationGroup = null;
public ?string $createdInvoiceUuid = null;
// Step 4: Results
public array $transferResults = [];
public int $successCount = 0;
public int $failCount = 0;
public function mount(): void
{
......@@ -57,137 +61,159 @@ public function mount(): void
public function getStepLabels(): array
{
return [
1 => 'اختيار المشترك',
1 => 'اختيار المشتركين',
2 => 'الوجهة',
3 => 'التأثير',
3 => 'السبب',
4 => 'تأكيد النقل',
];
}
public function selectParticipant(int $id): void
// --- Mode ---
public function setMode(string $mode): void
{
$participant = Participant::with('person')->findOrFail($id);
$this->participantId = $id;
$this->selectedParticipant = [
'id' => $participant->id,
'name' => $participant->person?->name_ar ?? $participant->person?->name ?? '-',
'participant_number' => $participant->participant_number,
];
$this->mode = $mode;
$this->reset(['sourceGroupId', 'sourceGroupInfo', 'participantSearch', 'selectedParticipants', 'selectAll', 'singleParticipantId', 'singleEnrollmentId', 'singleParticipantInfo', 'singleEnrollments']);
}
$this->loadActiveEnrollments();
// --- Bulk Mode: Source Group ---
public function selectSourceGroup(int $id): void
{
$group = TrainingGroup::with('program')->findOrFail($id);
$this->sourceGroupId = $id;
$this->sourceGroupInfo = [
'id' => $group->id,
'name_ar' => $group->name_ar,
'program_name' => $group->program?->name_ar ?? '-',
'current_count' => $group->current_count,
'max_capacity' => $group->max_capacity,
'program_id' => $group->training_program_id,
];
$this->selectedParticipants = [];
$this->selectAll = false;
}
public function updatedParticipantId(): void
public function toggleParticipant(int $enrollmentId): void
{
if ($this->participantId) {
$this->loadActiveEnrollments();
if (isset($this->selectedParticipants[$enrollmentId])) {
unset($this->selectedParticipants[$enrollmentId]);
$this->selectAll = false;
} else {
$this->activeEnrollments = [];
$enrollment = Enrollment::with('participant.person')->find($enrollmentId);
if ($enrollment) {
$this->selectedParticipants[$enrollmentId] = [
'enrollment_id' => $enrollmentId,
'participant_id' => $enrollment->participant_id,
'name' => $enrollment->participant?->person?->name_ar ?? $enrollment->participant?->person?->name ?? '-',
'participant_number' => $enrollment->participant?->participant_number,
];
}
}
$this->enrollmentId = null;
$this->selectedEnrollment = null;
$this->sourceGroup = null;
}
private function loadActiveEnrollments(): void
public function toggleSelectAll(): void
{
$enrollments = Enrollment::where('participant_id', $this->participantId)
if ($this->selectAll) {
$this->selectedParticipants = [];
$this->selectAll = false;
return;
}
$enrollments = Enrollment::where('training_group_id', $this->sourceGroupId)
->where('status', 'active')
->with(['group', 'program'])
->with('participant.person')
->get();
$this->activeEnrollments = $enrollments->map(fn ($e) => [
'id' => $e->id,
'group_name' => $e->group?->name_ar ?? '-',
'program_name' => $e->program?->name_ar ?? '-',
'enrollment_date' => $e->enrollment_date?->format('Y-m-d'),
'group_id' => $e->training_group_id,
'program_id' => $e->training_program_id,
])->toArray();
$this->selectedParticipants = [];
foreach ($enrollments as $enrollment) {
$this->selectedParticipants[$enrollment->id] = [
'enrollment_id' => $enrollment->id,
'participant_id' => $enrollment->participant_id,
'name' => $enrollment->participant?->person?->name_ar ?? $enrollment->participant?->person?->name ?? '-',
'participant_number' => $enrollment->participant?->participant_number,
];
}
$this->selectAll = true;
}
public function selectEnrollment(int $id): void
// --- Single Mode ---
public function selectSingleParticipant(int $id): void
{
$enrollment = Enrollment::with(['group', 'program'])->findOrFail($id);
$this->enrollmentId = $id;
$this->selectedEnrollment = [
'id' => $enrollment->id,
'group_name' => $enrollment->group?->name_ar ?? '-',
'program_name' => $enrollment->program?->name_ar ?? '-',
'group_id' => $enrollment->training_group_id,
'program_id' => $enrollment->training_program_id,
$participant = Participant::with('person')->findOrFail($id);
$this->singleParticipantId = $id;
$this->singleParticipantInfo = [
'id' => $participant->id,
'name' => $participant->person?->name_ar ?? $participant->person?->name ?? '-',
'participant_number' => $participant->participant_number,
];
$this->sourceGroup = [
$this->singleEnrollments = Enrollment::where('participant_id', $id)
->where('status', 'active')
->with(['group', 'program'])
->get()
->map(fn ($e) => [
'id' => $e->id,
'group_name' => $e->group?->name_ar ?? '-',
'program_name' => $e->program?->name_ar ?? '-',
'group_id' => $e->training_group_id,
'program_id' => $e->training_program_id,
])->toArray();
}
public function selectSingleEnrollment(int $enrollmentId): void
{
$enrollment = Enrollment::with(['participant.person', 'group'])->findOrFail($enrollmentId);
$this->singleEnrollmentId = $enrollmentId;
$this->sourceGroupId = $enrollment->training_group_id;
$this->sourceGroupInfo = [
'id' => $enrollment->group?->id,
'name_ar' => $enrollment->group?->name_ar,
'program_name' => $enrollment->program?->name_ar ?? '-',
'current_count' => $enrollment->group?->current_count,
'max_capacity' => $enrollment->group?->max_capacity,
'program_id' => $enrollment->training_program_id,
];
$this->selectedParticipants = [
$enrollmentId => [
'enrollment_id' => $enrollmentId,
'participant_id' => $enrollment->participant_id,
'name' => $enrollment->participant?->person?->name_ar ?? $enrollment->participant?->person?->name ?? '-',
'participant_number' => $enrollment->participant?->participant_number,
],
];
}
public function clearSingleParticipant(): void
{
$this->reset(['singleParticipantId', 'singleParticipantInfo', 'singleEnrollments', 'singleEnrollmentId', 'selectedParticipants', 'sourceGroupId', 'sourceGroupInfo']);
}
// --- Destination ---
public function selectDestinationProgram(?int $id): void
{
$this->destinationProgramId = $id;
$this->destinationGroupId = null;
$this->destinationGroup = null;
$this->priceDifference = 0;
$this->requiresPayment = false;
$this->destinationGroupInfo = null;
}
public function selectDestinationGroup(int $id): void
{
$group = TrainingGroup::with('program')->findOrFail($id);
$this->destinationGroupId = $id;
$this->destinationGroup = [
$this->destinationGroupInfo = [
'id' => $group->id,
'name_ar' => $group->name_ar,
'program_name' => $group->program?->name_ar ?? '-',
'current_count' => $group->current_count,
'max_capacity' => $group->max_capacity,
];
$this->calculatePriceDifference($group);
}
private function calculatePriceDifference(TrainingGroup $destGroup): void
{
$this->priceDifference = 0;
$this->requiresPayment = false;
if (!$this->selectedEnrollment || !$this->participantId) {
return;
}
$participant = Participant::find($this->participantId);
$sourceProgram = TrainingProgram::find($this->selectedEnrollment['program_id']);
$destProgram = $destGroup->program;
if (!$sourceProgram || !$destProgram || !$participant) {
return;
}
$pricingService = app(PricingService::class);
try {
$sourceResult = $pricingService->calculate($sourceProgram, $participant);
$this->sourceProgramPrice = $sourceResult->finalAmount;
} catch (DomainException) {
$this->sourceProgramPrice = 0;
}
try {
$destResult = $pricingService->calculate($destProgram, $participant);
$this->destinationProgramPrice = $destResult->finalAmount;
} catch (DomainException) {
$this->destinationProgramPrice = 0;
}
$diff = $this->destinationProgramPrice - $this->sourceProgramPrice;
if ($diff > 0) {
$this->priceDifference = $diff;
$this->requiresPayment = true;
}
}
// --- Navigation ---
public function nextStep(): void
{
......@@ -212,90 +238,144 @@ public function goToStep(int $step): void
}
}
// --- Confirm ---
public function confirm(): void
{
try {
$enrollment = Enrollment::findOrFail($this->enrollmentId);
$toGroup = TrainingGroup::findOrFail($this->destinationGroupId);
$newEnrollment = app(EnrollmentService::class)->transfer($enrollment, $toGroup, auth()->user());
// Create price difference invoice if destination is more expensive
if ($this->requiresPayment && $this->priceDifference > 0) {
$invoice = app(InvoiceService::class)->create([
'billable_type' => Participant::class,
'billable_id' => $this->participantId,
'branch_id' => $toGroup->branch_id ?? auth()->user()->branch_id,
'due_date' => now()->addDays(7)->toDateString(),
'notes' => 'فاتورة فرق سعر نقل — اشتراك #' . $newEnrollment->id,
], [[
'description' => 'فرق سعر نقل من ' . ($this->selectedEnrollment['program_name'] ?? '-') . ' إلى ' . ($this->destinationGroup['program_name'] ?? '-'),
'quantity' => 1,
'unit_price' => $this->priceDifference,
]], auth()->user());
$this->createdInvoiceUuid = $invoice->uuid;
$enrollmentService = app(EnrollmentService::class);
$toGroup = TrainingGroup::findOrFail($this->destinationGroupId);
$actor = auth()->user();
$this->transferResults = [];
$this->successCount = 0;
$this->failCount = 0;
foreach ($this->selectedParticipants as $enrollmentId => $info) {
try {
$enrollment = Enrollment::findOrFail($enrollmentId);
$enrollmentService->transfer($enrollment, $toGroup, $actor);
$this->transferResults[] = [
'name' => $info['name'],
'status' => 'success',
'message' => __('تم النقل بنجاح'),
];
$this->successCount++;
} catch (DomainException $e) {
$this->transferResults[] = [
'name' => $info['name'],
'status' => 'error',
'message' => $e->getMessage(),
];
$this->failCount++;
} catch (\Throwable $e) {
$this->transferResults[] = [
'name' => $info['name'],
'status' => 'error',
'message' => __('خطأ غير متوقع'),
];
$this->failCount++;
}
$this->completed = true;
} catch (DomainException $e) {
session()->flash('error', $e->getMessage());
}
$this->completed = true;
}
private function rulesForStep(int $step): array
{
return match ($step) {
1 => [
'participantId' => 'required|integer|exists:participants,id',
'enrollmentId' => 'required|integer|exists:enrollments,id',
'selectedParticipants' => 'required|array|min:1',
],
2 => [
'destinationGroupId' => 'required|integer|exists:training_groups,id',
],
3 => [
'reason' => 'required|string|min:5|max:500',
'reason' => 'required|string|min:3|max:500',
],
default => [],
};
}
public function messages(): array
{
return [
'selectedParticipants.required' => 'يجب اختيار مشترك واحد على الأقل',
'selectedParticipants.min' => 'يجب اختيار مشترك واحد على الأقل',
'destinationGroupId.required' => 'يجب اختيار المجموعة الوجهة',
'reason.required' => 'يجب كتابة سبب النقل',
'reason.min' => 'سبب النقل قصير جدًا',
];
}
public function render()
{
// Search results for single mode
$searchResults = collect();
if (strlen($this->participantSearch) >= 2) {
if ($this->mode === 'single' && strlen($this->participantSearch) >= 2 && !$this->singleParticipantInfo) {
$searchResults = Participant::with('person')
->whereHas('person', function ($q) {
$q->where('name_ar', 'ilike', "%{$this->participantSearch}%")
->orWhere('name', 'ilike', "%{$this->participantSearch}%")
->orWhere('phone', 'ilike', "%{$this->participantSearch}%")
->orWhere('national_id', 'ilike', "%{$this->participantSearch}%");
->orWhere('phone', 'ilike', "%{$this->participantSearch}%");
})
->orWhere('participant_number', 'ilike', "%{$this->participantSearch}%")
->where('status', 'active')
->limit(10)
->get();
}
// Source groups for bulk mode
$sourceGroups = collect();
if ($this->mode === 'bulk' && !$this->sourceGroupId) {
$sourceGroups = TrainingGroup::whereIn('status', ['active', 'forming'])
->where('current_count', '>', 0)
->with('program')
->orderBy('name_ar')
->get();
}
// Source group enrollments (for bulk selection)
$sourceEnrollments = collect();
if ($this->mode === 'bulk' && $this->sourceGroupId) {
$query = Enrollment::where('training_group_id', $this->sourceGroupId)
->where('status', 'active')
->with('participant.person');
if (strlen($this->participantSearch) >= 2) {
$search = $this->participantSearch;
$query->whereHas('participant.person', function ($q) use ($search) {
$q->where('name_ar', 'ilike', "%{$search}%")
->orWhere('name', 'ilike', "%{$search}%")
->orWhere('phone', 'ilike', "%{$search}%");
});
}
$sourceEnrollments = $query->get();
}
// Destination options
$availablePrograms = collect();
$availableGroups = collect();
if ($this->selectedEnrollment && $this->currentStep >= 2) {
if ($this->currentStep >= 2 && $this->sourceGroupId) {
$availablePrograms = TrainingProgram::where('status', 'active')
->orderBy('name_ar')
->get();
$targetProgramId = $this->destinationProgramId ?? $this->selectedEnrollment['program_id'];
$targetProgramId = $this->destinationProgramId ?? ($this->sourceGroupInfo['program_id'] ?? null);
$availableGroups = TrainingGroup::where('training_program_id', $targetProgramId)
->where('id', '!=', $this->selectedEnrollment['group_id'])
->whereIn('status', ['forming', 'active'])
->with('program')
->orderBy('name_ar')
->get();
if ($targetProgramId) {
$availableGroups = TrainingGroup::where('training_program_id', $targetProgramId)
->where('id', '!=', $this->sourceGroupId)
->whereIn('status', ['forming', 'active'])
->with('program')
->orderBy('name_ar')
->get();
}
}
return view('livewire.enrollments.transfer-participant-wizard', [
'searchResults' => $searchResults,
'sourceGroups' => $sourceGroups,
'sourceEnrollments' => $sourceEnrollments,
'availablePrograms' => $availablePrograms,
'availableGroups' => $availableGroups,
]);
......
......@@ -2,9 +2,12 @@
{{-- Header --}}
<div class="flex items-center justify-between mb-6">
<div>
<h1 class="text-xl sm:text-2xl font-bold text-gray-800">{{ __('نقل مشترك') }}</h1>
<p class="text-sm text-gray-500 mt-1">{{ __('نقل مشترك من مجموعة إلى أخرى (نفس البرنامج أو برنامج آخر)') }}</p>
<h1 class="text-xl sm:text-2xl font-bold text-gray-800">{{ __('نقل مشتركين') }}</h1>
<p class="text-sm text-gray-500 mt-1">{{ __('نقل مشترك أو مجموعة مشتركين من مجموعة إلى أخرى') }}</p>
</div>
<a href="{{ route('enrollments.list') }}" wire:navigate class="text-sm text-gray-500 hover:text-gray-700">
{{ __('العودة') }}
</a>
</div>
{{-- Flash Messages --}}
......@@ -16,29 +19,63 @@
{{-- Success State --}}
@if($completed)
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-8 text-center">
<div class="w-16 h-16 mx-auto mb-4 bg-green-100 rounded-full flex items-center justify-center">
<svg class="w-8 h-8 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
</svg>
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-6 sm:p-8">
<div class="text-center mb-6">
<div class="w-16 h-16 mx-auto mb-4 bg-green-100 rounded-full flex items-center justify-center">
<svg class="w-8 h-8 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
</svg>
</div>
<h2 class="text-xl font-bold text-gray-800 mb-2">{{ __('اكتملت عملية النقل') }}</h2>
<p class="text-gray-500">
{{ __('تم نقل') }} <span class="font-bold text-green-600">{{ $successCount }}</span>
@if($failCount > 0)
{{ __('— فشل') }} <span class="font-bold text-red-600">{{ $failCount }}</span>
@endif
</p>
</div>
<h2 class="text-xl font-bold text-gray-800 mb-2">{{ __('تم النقل بنجاح') }}</h2>
<p class="text-gray-500 mb-4">{{ __('تم نقل المشترك إلى المجموعة الجديدة بنجاح') }}</p>
@if($createdInvoiceUuid)
<div class="mb-6 p-4 bg-amber-50 border border-amber-200 rounded-xl text-amber-800 text-sm">
<p class="font-semibold mb-1">{{ __('تم إنشاء فاتورة فرق السعر') }}</p>
<p>{{ __('المبلغ:') }} {{ number_format($priceDifference / 100, 2) }} {{ __('ج.م') }}</p>
{{-- Results Table --}}
<div class="max-h-96 overflow-y-auto border border-gray-200 rounded-xl mb-6">
<table class="w-full text-sm">
<thead class="bg-gray-50 sticky top-0">
<tr>
<th class="px-4 py-3 text-start text-xs font-medium text-gray-500">{{ __('المشترك') }}</th>
<th class="px-4 py-3 text-start text-xs font-medium text-gray-500">{{ __('الحالة') }}</th>
<th class="px-4 py-3 text-start text-xs font-medium text-gray-500">{{ __('التفاصيل') }}</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-100">
@foreach($transferResults as $result)
<tr>
<td class="px-4 py-3 font-medium text-gray-800">{{ $result['name'] }}</td>
<td class="px-4 py-3">
@if($result['status'] === 'success')
<span class="inline-flex items-center gap-1 px-2 py-1 text-xs rounded-full bg-green-100 text-green-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="M5 13l4 4L19 7"/></svg>
{{ __('نجح') }}
</span>
@else
<span class="inline-flex items-center gap-1 px-2 py-1 text-xs rounded-full bg-red-100 text-red-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="M6 18L18 6M6 6l12 12"/></svg>
{{ __('فشل') }}
</span>
@endif
</td>
<td class="px-4 py-3 text-gray-500 text-xs">{{ $result['message'] }}</td>
</tr>
@endforeach
</tbody>
</table>
</div>
@endif
<div class="flex items-center justify-center gap-4">
@if($createdInvoiceUuid)
<a href="{{ route('invoices.show', $createdInvoiceUuid) }}" wire:navigate
class="inline-flex items-center gap-2 px-6 py-3 bg-amber-600 text-white rounded-lg hover:bg-amber-700 font-medium transition-colors">
{{ __('عرض الفاتورة') }}
<a href="{{ route('enrollments.transfer-wizard') }}" wire:navigate
class="inline-flex items-center gap-2 px-6 py-3 bg-emerald-600 text-white rounded-lg hover:bg-emerald-700 font-medium transition-colors">
{{ __('نقل آخر') }}
</a>
@endif
<a href="{{ route('enrollments.list') }}" wire:navigate
class="inline-flex items-center gap-2 px-6 py-3 bg-emerald-600 text-white rounded-lg hover:bg-emerald-700 font-medium transition-colors">
class="inline-flex items-center gap-2 px-6 py-3 bg-gray-100 text-gray-700 rounded-lg hover:bg-gray-200 font-medium transition-colors">
{{ __('العودة للتسجيلات') }}
</a>
</div>
......@@ -83,49 +120,157 @@ class="flex items-center gap-2 {{ $num < $currentStep ? 'cursor-pointer' : 'curs
{{-- Step Content --}}
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-4 sm:p-6">
{{-- Step 1: Select Participant & Enrollment --}}
{{-- Step 1: Select Participants --}}
@if($currentStep === 1)
<div>
<h2 class="text-lg font-semibold text-gray-800 mb-6">{{ __('اختيار المشترك والتسجيل') }}</h2>
{{-- Search --}}
<div class="mb-6">
<label class="block text-sm font-medium text-gray-700 mb-1">{{ __('بحث عن المشترك') }}</label>
<input type="text" wire:model.live.debounce.300ms="participantSearch"
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-emerald-500 focus:border-emerald-500 text-lg"
placeholder="{{ __('بحث بالاسم، الهاتف، الرقم القومي، أو رقم المشترك...') }}">
{{-- Mode Toggle --}}
<div class="flex items-center gap-3 mb-6">
<button wire:click="setMode('bulk')"
class="px-4 py-2 rounded-lg text-sm font-medium transition-colors
{{ $mode === 'bulk' ? 'bg-emerald-600 text-white' : 'bg-gray-100 text-gray-600 hover:bg-gray-200' }}">
{{ __('نقل من مجموعة (Bulk)') }}
</button>
<button wire:click="setMode('single')"
class="px-4 py-2 rounded-lg text-sm font-medium transition-colors
{{ $mode === 'single' ? 'bg-emerald-600 text-white' : 'bg-gray-100 text-gray-600 hover:bg-gray-200' }}">
{{ __('نقل فردي') }}
</button>
</div>
{{-- Selected Participant --}}
@if($selectedParticipant)
<div class="mb-4 p-4 bg-emerald-50 border border-emerald-200 rounded-xl flex items-center justify-between">
<div class="flex items-center gap-3">
<div class="w-10 h-10 rounded-full bg-emerald-200 flex items-center justify-center">
<svg class="w-5 h-5 text-emerald-700" 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>
</div>
{{-- BULK MODE --}}
@if($mode === 'bulk')
@if(!$sourceGroupId)
{{-- Select Source Group --}}
<h2 class="text-lg font-semibold text-gray-800 mb-4">{{ __('اختر المجموعة المصدر') }}</h2>
<div class="space-y-2 max-h-96 overflow-y-auto">
@foreach($sourceGroups as $group)
<button wire:click="selectSourceGroup({{ $group->id }})"
class="w-full text-start p-4 border border-gray-200 rounded-xl hover:border-emerald-300 hover:bg-emerald-50 transition-colors">
<div class="flex items-center justify-between">
<div>
<div class="font-medium text-gray-800">{{ $group->name_ar }}</div>
<div class="text-sm text-gray-500">{{ $group->program?->name_ar ?? '-' }}</div>
</div>
<span class="px-3 py-1 text-sm rounded-full bg-gray-100 text-gray-700 font-medium">
{{ $group->current_count }} {{ __('مشترك') }}
</span>
</div>
</button>
@endforeach
</div>
@else
{{-- Source Group Selected — Show Participants --}}
<div class="mb-4 p-3 bg-emerald-50 border border-emerald-200 rounded-xl flex items-center justify-between">
<div>
<span class="font-medium text-emerald-800">{{ $selectedParticipant['name'] }}</span>
@if($selectedParticipant['participant_number'])
<span class="text-xs text-emerald-600 ms-2">#{{ $selectedParticipant['participant_number'] }}</span>
@endif
<span class="text-xs text-emerald-600">{{ __('المجموعة المصدر') }}</span>
<div class="font-medium text-emerald-800">{{ $sourceGroupInfo['name_ar'] }}</div>
<div class="text-xs text-emerald-600">{{ $sourceGroupInfo['program_name'] }}</div>
</div>
<button wire:click="$set('sourceGroupId', null)" class="text-emerald-600 hover:text-emerald-800 text-sm">
{{ __('تغيير') }}
</button>
</div>
<button wire:click="$set('participantId', null)" class="text-emerald-600 hover:text-emerald-800 text-sm">
{{ __('تغيير') }}
</button>
</div>
{{-- Active Enrollments --}}
@if(count($activeEnrollments) > 0)
<div class="mb-4">
<h3 class="text-sm font-medium text-gray-700 mb-3">{{ __('التسجيلات النشطة') }}</h3>
{{-- Search within group --}}
<div class="mb-4">
<input type="text" wire:model.live.debounce.300ms="participantSearch"
class="w-full px-4 py-2.5 border border-gray-300 rounded-lg focus:ring-2 focus:ring-emerald-500 focus:border-emerald-500"
placeholder="{{ __('فلتر بالاسم...') }}">
</div>
{{-- Select All + Counter --}}
<div class="flex items-center justify-between mb-3">
<label class="flex items-center gap-2 cursor-pointer">
<input type="checkbox" wire:click="toggleSelectAll" {{ $selectAll ? 'checked' : '' }}
class="w-4 h-4 rounded border-gray-300 text-emerald-600 focus:ring-emerald-500">
<span class="text-sm font-medium text-gray-700">{{ __('تحديد الكل') }}</span>
</label>
<span class="text-sm font-medium {{ count($selectedParticipants) > 0 ? 'text-emerald-600' : 'text-gray-400' }}">
{{ __('محدد:') }} {{ count($selectedParticipants) }}
</span>
</div>
{{-- Participants List --}}
<div class="space-y-1 max-h-80 overflow-y-auto border border-gray-200 rounded-xl p-2">
@forelse($sourceEnrollments as $enrollment)
<label class="flex items-center gap-3 p-3 rounded-lg cursor-pointer hover:bg-gray-50 transition-colors
{{ isset($selectedParticipants[$enrollment->id]) ? 'bg-emerald-50 border border-emerald-200' : '' }}">
<input type="checkbox" wire:click="toggleParticipant({{ $enrollment->id }})"
{{ isset($selectedParticipants[$enrollment->id]) ? 'checked' : '' }}
class="w-4 h-4 rounded border-gray-300 text-emerald-600 focus:ring-emerald-500">
<div class="flex-1 min-w-0">
<div class="font-medium text-gray-800 text-sm truncate">
{{ $enrollment->participant?->person?->name_ar ?? $enrollment->participant?->person?->name ?? '-' }}
</div>
@if($enrollment->participant?->participant_number)
<div class="text-xs text-gray-400">#{{ $enrollment->participant->participant_number }}</div>
@endif
</div>
</label>
@empty
<div class="p-4 text-center text-gray-500 text-sm">
{{ __('لا توجد تسجيلات نشطة') }}
</div>
@endforelse
</div>
@endif
@endif
{{-- SINGLE MODE --}}
@if($mode === 'single')
@if(!$singleParticipantInfo)
<h2 class="text-lg font-semibold text-gray-800 mb-4">{{ __('بحث عن المشترك') }}</h2>
<input type="text" wire:model.live.debounce.300ms="participantSearch"
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-emerald-500 focus:border-emerald-500 text-lg mb-4"
placeholder="{{ __('بحث بالاسم أو الهاتف أو رقم المشترك...') }}">
@if(strlen($participantSearch) >= 2)
<div class="space-y-2">
@foreach($activeEnrollments as $enrollment)
@forelse($searchResults as $participant)
<button wire:click="selectSingleParticipant({{ $participant->id }})"
class="w-full text-start p-4 border border-gray-200 rounded-xl hover:border-emerald-300 hover:bg-emerald-50 transition-colors">
<div class="flex items-center justify-between">
<div>
<div class="font-medium text-gray-800">{{ $participant->person?->name_ar ?? $participant->person?->name ?? '-' }}</div>
<div class="text-sm text-gray-500">{{ $participant->participant_number }}</div>
</div>
<span class="px-2 py-1 text-xs rounded-full bg-green-100 text-green-700">{{ __('نشط') }}</span>
</div>
</button>
@empty
<div class="p-4 text-center text-gray-500 text-sm">{{ __('لا توجد نتائج') }}</div>
@endforelse
</div>
@endif
@else
{{-- Participant selected --}}
<div class="mb-4 p-4 bg-emerald-50 border border-emerald-200 rounded-xl flex items-center justify-between">
<div class="flex items-center gap-3">
<div class="w-10 h-10 rounded-full bg-emerald-200 flex items-center justify-center">
<svg class="w-5 h-5 text-emerald-700" 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>
</div>
<div>
<span class="font-medium text-emerald-800">{{ $singleParticipantInfo['name'] }}</span>
@if($singleParticipantInfo['participant_number'])
<span class="text-xs text-emerald-600 ms-2">#{{ $singleParticipantInfo['participant_number'] }}</span>
@endif
</div>
</div>
<button wire:click="clearSingleParticipant" class="text-emerald-600 hover:text-emerald-800 text-sm">
{{ __('تغيير') }}
</button>
</div>
{{-- Active Enrollments --}}
@if(count($singleEnrollments) > 0)
<h3 class="text-sm font-medium text-gray-700 mb-3">{{ __('اختر التسجيل المراد نقله') }}</h3>
<div class="space-y-2">
@foreach($singleEnrollments as $enrollment)
<label class="relative cursor-pointer block">
<input type="radio" wire:click="selectEnrollment({{ $enrollment['id'] }})" name="enrollment"
{{ $enrollmentId === $enrollment['id'] ? 'checked' : '' }} class="peer sr-only">
<input type="radio" wire:click="selectSingleEnrollment({{ $enrollment['id'] }})" name="enrollment"
{{ $singleEnrollmentId === $enrollment['id'] ? 'checked' : '' }} class="peer sr-only">
<div class="p-4 border-2 rounded-xl transition-all
peer-checked:border-emerald-500 peer-checked:bg-emerald-50
border-gray-200 hover:border-gray-300">
......@@ -134,47 +279,20 @@ class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:rin
<div class="font-medium text-gray-800">{{ $enrollment['group_name'] }}</div>
<div class="text-sm text-gray-500">{{ $enrollment['program_name'] }}</div>
</div>
<div class="text-xs text-gray-400">{{ $enrollment['enrollment_date'] }}</div>
</div>
</div>
</label>
@endforeach
</div>
</div>
@else
<div class="p-4 bg-amber-50 border border-amber-200 rounded-xl text-amber-700 text-sm">
{{ __('لا توجد تسجيلات نشطة لهذا المشترك') }}
</div>
@endif
@endif
{{-- Search Results --}}
@if(strlen($participantSearch) >= 2 && !$selectedParticipant)
<div class="space-y-2">
@forelse($searchResults as $participant)
<button wire:click="selectParticipant({{ $participant->id }})"
class="w-full text-start p-4 border border-gray-200 rounded-xl hover:border-emerald-300 hover:bg-emerald-50 transition-colors">
<div class="flex items-center justify-between">
<div>
<div class="font-medium text-gray-800">{{ $participant->person?->name_ar ?? $participant->person?->name ?? '-' }}</div>
<div class="text-sm text-gray-500">{{ $participant->participant_number }}</div>
</div>
<span class="px-2 py-1 text-xs rounded-full
{{ $participant->status->value === 'active' ? 'bg-green-100 text-green-700' : 'bg-gray-100 text-gray-600' }}">
{{ $participant->status->value === 'active' ? __('نشط') : $participant->status->value }}
</span>
</div>
</button>
@empty
<div class="p-4 text-center text-gray-500 text-sm">
{{ __('لا توجد نتائج') }}
@else
<div class="p-4 bg-amber-50 border border-amber-200 rounded-xl text-amber-700 text-sm">
{{ __('لا توجد تسجيلات نشطة لهذا المشترك') }}
</div>
@endforelse
</div>
@endif
@endif
@endif
@error('participantId') <p class="text-red-500 text-xs mt-2">{{ $message }}</p> @enderror
@error('enrollmentId') <p class="text-red-500 text-xs mt-2">{{ $message }}</p> @enderror
@error('selectedParticipants') <p class="text-red-500 text-xs mt-3">{{ $message }}</p> @enderror
</div>
@endif
......@@ -182,7 +300,9 @@ class="w-full text-start p-4 border border-gray-200 rounded-xl hover:border-emer
@if($currentStep === 2)
<div>
<h2 class="text-lg font-semibold text-gray-800 mb-2">{{ __('اختيار الوجهة') }}</h2>
<p class="text-sm text-gray-500 mb-6">{{ __('اختر البرنامج والمجموعة — يمكنك النقل لبرنامج آخر') }}</p>
<p class="text-sm text-gray-500 mb-6">
{{ __('نقل') }} <span class="font-bold text-emerald-600">{{ count($selectedParticipants) }}</span> {{ __('مشترك — اختر البرنامج والمجموعة') }}
</p>
{{-- Program Selector --}}
<div class="mb-5">
......@@ -190,9 +310,9 @@ class="w-full text-start p-4 border border-gray-200 rounded-xl hover:border-emer
<select wire:change="selectDestinationProgram($event.target.value)"
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-emerald-500 text-sm">
@foreach($availablePrograms as $program)
<option value="{{ $program->id }}" {{ ($destinationProgramId ?? $selectedEnrollment['program_id'] ?? '') == $program->id ? 'selected' : '' }}>
<option value="{{ $program->id }}" {{ ($destinationProgramId ?? ($sourceGroupInfo['program_id'] ?? '')) == $program->id ? 'selected' : '' }}>
{{ $program->name_ar }}
@if($program->id == ($selectedEnrollment['program_id'] ?? null))
@if($program->id == ($sourceGroupInfo['program_id'] ?? null))
({{ __('البرنامج الحالي') }})
@endif
</option>
......@@ -204,14 +324,16 @@ class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:rin
@if($availableGroups->count() > 0)
<div class="space-y-3">
@foreach($availableGroups as $group)
<label class="relative cursor-pointer block {{ $group->isFull() ? 'pointer-events-none' : '' }}">
@php
$spotsAfter = $group->max_capacity - $group->current_count - count($selectedParticipants);
$canFitAll = $spotsAfter >= 0;
@endphp
<label class="relative cursor-pointer block">
<input type="radio" wire:click="selectDestinationGroup({{ $group->id }})" name="destination"
{{ $destinationGroupId === $group->id ? 'checked' : '' }} class="peer sr-only"
{{ $group->isFull() ? 'disabled' : '' }}>
{{ $destinationGroupId === $group->id ? 'checked' : '' }} class="peer sr-only">
<div class="p-4 border-2 rounded-xl transition-all
peer-checked:border-emerald-500 peer-checked:bg-emerald-50
border-gray-200 hover:border-gray-300
{{ $group->isFull() ? 'opacity-50' : '' }}">
border-gray-200 hover:border-gray-300">
<div class="flex items-center justify-between">
<div>
<div class="font-medium text-gray-800">{{ $group->name_ar }}</div>
......@@ -219,13 +341,13 @@ class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:rin
</div>
<div class="flex items-center gap-3">
<span class="px-3 py-1 text-sm rounded-full font-medium
{{ $group->hasAvailableSpots() ? 'bg-green-100 text-green-700' : 'bg-red-100 text-red-700' }}">
{{ $canFitAll ? 'bg-green-100 text-green-700' : 'bg-amber-100 text-amber-700' }}">
{{ $group->current_count }}/{{ $group->max_capacity }}
</span>
@if($group->hasAvailableSpots())
@if($canFitAll)
<span class="text-xs text-green-600">{{ __('متاح') }}: {{ $group->max_capacity - $group->current_count }}</span>
@else
<span class="text-xs text-red-600">{{ __('ممتلئة') }}</span>
<span class="text-xs text-amber-600">{{ __('سعة غير كافية') }}</span>
@endif
</div>
</div>
......@@ -242,20 +364,17 @@ class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:rin
</div>
@endif
{{-- Price Difference Notice --}}
@if($requiresPayment && $priceDifference > 0)
<div class="mt-4 p-4 bg-blue-50 border border-blue-200 rounded-xl">
{{-- Capacity Warning --}}
@if($destinationGroupInfo && count($selectedParticipants) > ($destinationGroupInfo['max_capacity'] - $destinationGroupInfo['current_count']))
<div class="mt-4 p-4 bg-amber-50 border border-amber-200 rounded-xl">
<div class="flex items-start gap-3">
<svg class="w-5 h-5 text-blue-600 mt-0.5 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
<svg class="w-5 h-5 text-amber-600 mt-0.5 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z"/>
</svg>
<div>
<p class="text-sm font-semibold text-blue-800">{{ __('يوجد فرق سعر') }}</p>
<p class="text-sm text-blue-700 mt-1">
{{ __('البرنامج الجديد أغلى بمبلغ') }}
<span class="font-bold" dir="ltr">{{ number_format($priceDifference / 100, 2) }}</span>
{{ __('ج.م — سيتم إنشاء فاتورة بالفرق عند التأكيد.') }}
</p>
<div class="text-sm text-amber-700">
<p class="font-semibold">{{ __('تحذير: السعة غير كافية') }}</p>
<p>{{ __('المجموعة المختارة بها') }} {{ $destinationGroupInfo['max_capacity'] - $destinationGroupInfo['current_count'] }} {{ __('مكان متاح فقط، وتحاول نقل') }} {{ count($selectedParticipants) }} {{ __('مشترك.') }}</p>
<p class="mt-1">{{ __('سيتم نقل من يمكن نقله فقط وسيفشل الباقي.') }}</p>
</div>
</div>
</div>
......@@ -265,22 +384,17 @@ class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:rin
</div>
@endif
{{-- Step 3: Impact --}}
{{-- Step 3: Reason --}}
@if($currentStep === 3)
<div>
<h2 class="text-lg font-semibold text-gray-800 mb-6">{{ __('تأثير النقل') }}</h2>
<h2 class="text-lg font-semibold text-gray-800 mb-6">{{ __('سبب النقل') }}</h2>
{{-- Transfer Visual --}}
<div class="flex items-center justify-center gap-4 mb-6 p-6 bg-gray-50 rounded-xl">
<div class="text-center p-4 bg-white rounded-lg border border-gray-200 flex-1">
<div class="text-xs text-gray-500 mb-1">{{ __('من') }}</div>
<div class="font-medium text-gray-800">{{ $sourceGroup['name_ar'] ?? '-' }}</div>
<div class="text-sm text-gray-500 mt-1" dir="ltr">
{{ ($sourceGroup['current_count'] ?? 0) }}/{{ $sourceGroup['max_capacity'] ?? 0 }}
</div>
<div class="text-xs text-green-600 mt-1">
{{ __('بعد النقل:') }} {{ (($sourceGroup['current_count'] ?? 0) - 1) }}/{{ $sourceGroup['max_capacity'] ?? 0 }}
</div>
<div class="font-medium text-gray-800">{{ $sourceGroupInfo['name_ar'] ?? '-' }}</div>
<div class="text-sm text-gray-500 mt-1">{{ count($selectedParticipants) }} {{ __('مشترك') }}</div>
</div>
<div class="text-gray-400">
<svg class="w-8 h-8 rotate-180" fill="none" stroke="currentColor" viewBox="0 0 24 24">
......@@ -289,13 +403,8 @@ class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:rin
</div>
<div class="text-center p-4 bg-white rounded-lg border border-gray-200 flex-1">
<div class="text-xs text-gray-500 mb-1">{{ __('إلى') }}</div>
<div class="font-medium text-gray-800">{{ $destinationGroup['name_ar'] ?? '-' }}</div>
<div class="text-sm text-gray-500 mt-1" dir="ltr">
{{ ($destinationGroup['current_count'] ?? 0) }}/{{ $destinationGroup['max_capacity'] ?? 0 }}
</div>
<div class="text-xs text-amber-600 mt-1">
{{ __('بعد النقل:') }} {{ (($destinationGroup['current_count'] ?? 0) + 1) }}/{{ $destinationGroup['max_capacity'] ?? 0 }}
</div>
<div class="font-medium text-gray-800">{{ $destinationGroupInfo['name_ar'] ?? '-' }}</div>
<div class="text-sm text-gray-500 mt-1">{{ $destinationGroupInfo['program_name'] ?? '' }}</div>
</div>
</div>
......@@ -304,7 +413,7 @@ class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:rin
<label class="block text-sm font-medium text-gray-700 mb-1">{{ __('سبب النقل') }} <span class="text-red-500">*</span></label>
<textarea wire:model="reason" rows="3"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-emerald-500 focus:border-emerald-500"
placeholder="{{ __('اذكر سبب نقل المشترك...') }}"></textarea>
placeholder="{{ __('مثال: تغيير المستوى، تغيير الوقت، طلب ولي الأمر...') }}"></textarea>
@error('reason') <p class="text-red-500 text-xs mt-1">{{ $message }}</p> @enderror
</div>
</div>
......@@ -316,22 +425,15 @@ class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:rin
<h2 class="text-lg font-semibold text-gray-800 mb-6">{{ __('تأكيد النقل') }}</h2>
<div class="space-y-4">
{{-- Summary --}}
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div class="p-4 bg-gray-50 rounded-lg">
<div class="text-xs text-gray-500 mb-1">{{ __('المشترك') }}</div>
<div class="font-medium text-gray-800">{{ $selectedParticipant['name'] ?? '-' }}</div>
</div>
<div class="p-4 bg-gray-50 rounded-lg">
<div class="text-xs text-gray-500 mb-1">{{ __('البرنامج') }}</div>
<div class="font-medium text-gray-800">{{ $selectedEnrollment['program_name'] ?? '-' }}</div>
</div>
<div class="p-4 bg-gray-50 rounded-lg">
<div class="text-xs text-gray-500 mb-1">{{ __('المجموعة الحالية') }}</div>
<div class="font-medium text-gray-800">{{ $sourceGroup['name_ar'] ?? '-' }}</div>
<div class="text-xs text-gray-500 mb-1">{{ __('من مجموعة') }}</div>
<div class="font-medium text-gray-800">{{ $sourceGroupInfo['name_ar'] ?? '-' }}</div>
</div>
<div class="p-4 bg-gray-50 rounded-lg">
<div class="text-xs text-gray-500 mb-1">{{ __('المجموعة الجديدة') }}</div>
<div class="font-medium text-gray-800">{{ $destinationGroup['name_ar'] ?? '-' }}</div>
<div class="text-xs text-gray-500 mb-1">{{ __('إلى مجموعة') }}</div>
<div class="font-medium text-gray-800">{{ $destinationGroupInfo['name_ar'] ?? '-' }}</div>
</div>
</div>
......@@ -340,27 +442,24 @@ class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:rin
<div class="text-gray-800">{{ $reason }}</div>
</div>
@if($requiresPayment && $priceDifference > 0)
<div class="p-4 bg-blue-50 border border-blue-200 rounded-lg">
<div class="flex items-start gap-2">
<svg class="w-5 h-5 text-blue-600 mt-0.5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
<div class="text-sm text-blue-700">
{{ __('سيتم إنشاء فاتورة بفرق السعر:') }}
<span class="font-bold" dir="ltr">{{ number_format($priceDifference / 100, 2) }} {{ __('ج.م') }}</span>
</div>
{{-- Participants List --}}
<div class="p-4 bg-gray-50 rounded-lg">
<div class="text-xs text-gray-500 mb-2">{{ __('المشتركون') }} ({{ count($selectedParticipants) }})</div>
<div class="flex flex-wrap gap-2">
@foreach($selectedParticipants as $p)
<span class="px-3 py-1 bg-emerald-100 text-emerald-800 text-sm rounded-full">{{ $p['name'] }}</span>
@endforeach
</div>
</div>
@endif
{{-- Warning --}}
<div class="p-4 bg-amber-50 border border-amber-200 rounded-lg">
<div class="flex items-start gap-2">
<svg class="w-5 h-5 text-amber-600 mt-0.5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z"/>
</svg>
<div class="text-sm text-amber-700">
{{ __('سيتم إلغاء التسجيل الحالي وإنشاء تسجيل جديد في المجموعة الوجهة. هذا الإجراء لا يمكن التراجع عنه.') }}
{{ __('سيتم إلغاء التسجيلات الحالية وإنشاء تسجيلات جديدة. سيتم نقل الحضور المستقبلي تلقائيًا.') }}
</div>
</div>
</div>
......@@ -388,7 +487,7 @@ class="px-6 py-2.5 bg-emerald-600 text-white rounded-lg hover:bg-emerald-700 fon
@else
<button wire:click="confirm" wire:loading.attr="disabled" wire:target="confirm"
class="px-6 py-3 bg-emerald-600 text-white rounded-lg hover:bg-emerald-700 font-medium disabled:opacity-50">
<span wire:loading.remove wire:target="confirm">{{ __('تأكيد النقل') }}</span>
<span wire:loading.remove wire:target="confirm">{{ __('تأكيد نقل') }} {{ count($selectedParticipants) }} {{ __('مشترك') }}</span>
<span wire:loading wire:target="confirm">{{ __('جارٍ النقل...') }}</span>
</button>
@endif
......
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