224 lines
9.4 KiB
PHP
224 lines
9.4 KiB
PHP
<div class="mt-10">
|
||
<div class="p-4 bg-white shadow-md">
|
||
|
||
<div class="flex justify-between items-center mb-4">
|
||
@if ($hasSearch ?? true)
|
||
<!-- Search bar -->
|
||
<input
|
||
type="text"
|
||
wire:model="search"
|
||
placeholder="Search..."
|
||
class="border rounded px-3 py-2" />
|
||
@else
|
||
<!-- Start Date and End Date filters -->
|
||
<div class="flex items-center gap-4">
|
||
<div class="flex items-center gap-2">
|
||
<label class="font-medium">Start</label>
|
||
<input
|
||
type="date"
|
||
wire:model="startDate"
|
||
class="border rounded px-3 py-2" />
|
||
</div>
|
||
|
||
<div class="flex items-center gap-2">
|
||
<label class="font-medium">End</label>
|
||
<input
|
||
type="date"
|
||
wire:model="endDate"
|
||
class="border rounded px-3 py-2" />
|
||
</div>
|
||
</div>
|
||
|
||
@endif
|
||
|
||
@if ($hasAddButton ?? true)
|
||
<!-- Add button -->
|
||
<a href="{{ $addRoute }}" class="bg-orange-600 text-white px-4 py-2 rounded">
|
||
+ Add
|
||
</a>
|
||
@else
|
||
<!-- Export button -->
|
||
<button
|
||
wire:click="export"
|
||
class="bg-orange-600 text-white px-4 py-2 rounded flex items-center gap-2">
|
||
Export CSV
|
||
</button>
|
||
@endif
|
||
</div>
|
||
|
||
<!-- Table Header -->
|
||
<table class="table-auto w-full">
|
||
<thead class="bg-gray-100">
|
||
<tr>
|
||
<!-- Checkbox for selecting rows (if enabled) -->
|
||
@if ($hasCheckbox)
|
||
<th class="px-4 py-2 text-left">
|
||
<input type="checkbox" wire:model="selectAll" wire:change="selectAllRows" class="cursor-pointer">
|
||
</th>
|
||
@endif
|
||
|
||
<!-- Dynamic Columns (sortable) -->
|
||
@foreach ($columns as $column)
|
||
<th class="px-4 py-2 text-left cursor-pointer" wire:click="sortBy('{{ $column['field'] }}')">
|
||
{{ $column['label'] }}
|
||
@if ($sortField === $column['field'])
|
||
@if ($sortDirection === 'asc')
|
||
<span class="ml-2">↑</span>
|
||
@else
|
||
<span class="ml-2">↓</span>
|
||
@endif
|
||
@else
|
||
<span class="ml-2">↕</span>
|
||
@endif
|
||
</th>
|
||
@endforeach
|
||
|
||
<!-- Actions Column (if enabled) -->
|
||
@if ($hasActions)
|
||
<th class="px-4 py-2 text-left">Actions</th>
|
||
@endif
|
||
</tr>
|
||
</thead>
|
||
|
||
<!-- Table Body -->
|
||
<tbody>
|
||
@php
|
||
\Illuminate\Support\Facades\Log::info("Blade rows count: " . count($rows) . ", First Username: " . ($rows[0]['username'] ?? 'N/A'));
|
||
@endphp
|
||
@forelse ($rows as $index => $row)
|
||
<tr class="hover:bg-gray-50 border-b" wire:key="row-{{ $row['id'] }}-{{ $index }}-{{ $renderKey }}">
|
||
<!-- Checkbox for row selection (if enabled) -->
|
||
@if ($hasCheckbox)
|
||
<td class="px-4 py-2">
|
||
<input type="checkbox" wire:click="selectRow('{{ $row['id'] }}')"
|
||
@if(in_array($row['id'], $selected)) checked @endif class="cursor-pointer">
|
||
</td>
|
||
@endif
|
||
|
||
<!-- Display Data for each column -->
|
||
@foreach ($columns as $column)
|
||
<td class="px-4 py-2">
|
||
{{ $row[$column['field']] ?? '' }}
|
||
</td>
|
||
@endforeach
|
||
|
||
<!-- Action Buttons (if enabled) -->
|
||
@if ($hasActions)
|
||
<td class="px-4 py-2 gap-2 flex">
|
||
@if($isViewPage)
|
||
<button wire:click="viewRow({{ $row['id'] }})" class="text-gray-500 hover:text-gray-700">
|
||
<i class="fas fa-eye"></i>
|
||
</button>
|
||
@else
|
||
<button wire:click="editRow({{ $row['id'] }})" class="text-blue-500 hover:text-blue-700">
|
||
<i class="fas fa-edit"></i>
|
||
</button>
|
||
<button wire:click="viewRow({{ $row['id'] }})" class="text-gray-500 hover:text-gray-700">
|
||
<i class="fas fa-eye"></i>
|
||
</button>
|
||
<button wire:click="deleteRow({{ $row['id'] }})" class="text-red-500 hover:text-red-700">
|
||
<i class="fas fa-trash-alt"></i>
|
||
</button>
|
||
@endif
|
||
</td>
|
||
@endif
|
||
</tr>
|
||
@empty
|
||
<tr>
|
||
<td colspan="{{ count($columns) + 1 }}" class="text-center p-4">No data available</td>
|
||
</tr>
|
||
@endforelse
|
||
</tbody>
|
||
</table>
|
||
|
||
<!-- Delete Button, Pagination, and Entries in a Single Row -->
|
||
<div class="mt-4 flex items-center justify-between gap-4">
|
||
<!-- Delete Button -->
|
||
@if($hasDelete)
|
||
<button wire:click="deleteSelected"
|
||
class="px-4 py-2 bg-red-500 text-white rounded-md hover:bg-red-600 cursor-pointer"
|
||
@if (empty($selected)) disabled @endif>
|
||
Delete
|
||
</button>
|
||
@else
|
||
<div></div> <!-- Placeholder to maintain layout -->
|
||
@endif
|
||
|
||
<!-- Pagination -->
|
||
<div class="flex items-center gap-2">
|
||
<!-- Previous Button -->
|
||
<button
|
||
wire:click="gotoPage({{ $currentPage - 1 }})"
|
||
class="px-3 py-1 border rounded {{ $currentPage <= 1 ? 'bg-gray-200 cursor-not-allowed' : 'bg-white hover:bg-gray-100' }}"
|
||
{{ $currentPage <= 1 ? 'disabled' : '' }}>
|
||
Prev
|
||
</button>
|
||
|
||
<!-- Page Numbers -->
|
||
@for ($i = 1; $i <= $lastPage; $i++)
|
||
<button
|
||
wire:click="gotoPage({{ $i }})"
|
||
class="px-3 py-1 border rounded {{ $currentPage === $i ? 'bg-orange-600 text-white' : 'bg-white hover:bg-gray-100' }}">
|
||
{{ $i }}
|
||
</button>
|
||
@endfor
|
||
|
||
<!-- Next Button -->
|
||
<button
|
||
wire:click="gotoPage({{ $currentPage + 1 }})"
|
||
class="px-3 py-1 border rounded {{ $currentPage >= $lastPage ? 'bg-gray-200 cursor-not-allowed' : 'bg-white hover:bg-gray-100' }}"
|
||
{{ $currentPage >= $lastPage ? 'disabled' : '' }}>
|
||
Next
|
||
</button>
|
||
</div>
|
||
|
||
<!-- Entries Text -->
|
||
<div class="text-gray-600">
|
||
Showing {{ ($currentPage - 1) * $perPage + 1 }} to {{ min($currentPage * $perPage, $totalRows) }} of {{ $totalRows }} entries
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Modal for Viewing / Editing Row -->
|
||
@if ($showModal)
|
||
<div class="fixed inset-0 bg-gray-900 bg-opacity-50 flex items-center justify-center z-50">
|
||
<div class="bg-white p-6 rounded-lg shadow-lg w-1/2">
|
||
<!-- Modal Header -->
|
||
<div class="flex justify-between items-center mb-4">
|
||
<h2 class="text-lg font-semibold">
|
||
{{ $modalMode === 'view' ? 'View Details' : 'Edit Details' }}
|
||
</h2>
|
||
<button wire:click="closeModal" class="text-gray-600 hover:text-gray-800">×</button>
|
||
</div>
|
||
|
||
<!-- Modal Body -->
|
||
<div class="space-y-4">
|
||
@foreach ($columns as $column)
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700">
|
||
{{ $column['label'] }}
|
||
</label>
|
||
@if ($modalMode === 'edit')
|
||
<input type="text" wire:model.defer="modalData.{{ $column['field'] }}"
|
||
class="mt-1 p-2 border border-gray-300 rounded w-full">
|
||
@else
|
||
<div class="mt-1 p-2 bg-gray-100 rounded">
|
||
{{ $modalData[$column['field']] ?? '' }}
|
||
</div>
|
||
@endif
|
||
</div>
|
||
@endforeach
|
||
</div>
|
||
|
||
<!-- Modal Footer with Save Button (if in edit mode) -->
|
||
@if ($modalMode === 'edit')
|
||
<div class="mt-6 flex justify-end">
|
||
<button wire:click="saveRow" class="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700">
|
||
Save
|
||
</button>
|
||
</div>
|
||
@endif
|
||
</div>
|
||
</div>
|
||
@endif
|
||
</div>
|
||
</div> |