modal refactor

This commit is contained in:
erishBRBS 2025-04-22 11:30:32 +08:00
parent 121c57d3ee
commit 92351c0bc1
2 changed files with 177 additions and 135 deletions

View File

@ -6,45 +6,28 @@ use Livewire\Component;
class Table extends Component class Table extends Component
{ {
public $columns = []; // Table Configuration
public $rows = []; public $columns = []; // Columns to display
public $selected = []; public $rows = []; // Data rows for the table
public $addRoute = null; public $selected = []; // Selected row IDs
public $hasAddButton = true; public $addRoute = null; // Route for adding new rows (optional)
public $selectAll = false; public $hasAddButton = true; // Whether the 'Add' button is shown
public $hasCheckbox = true; public $selectAll = false; // Whether 'Select All' is active
public $hasActions = false; public $hasCheckbox = true; // Whether checkboxes are shown for row selection
public $isViewPage = false; public $hasActions = false; // Whether action buttons (like Edit/Delete) are shown
public $search = ''; public $isViewPage = false; // Whether the table is for a view page
public $sortField = null; // Column to sort public $search = ''; // Search query for filtering rows
public $sortDirection = 'asc'; // Default sort direction public $sortField = null; // Column to sort by
public $sortDirection = 'asc'; // Sorting direction (asc or desc)
// Inside App\Livewire\Components\Table // Modal Configuration
public $showModal = false; // Whether the modal is visible
public $showModal = false; public $modalMode = 'view'; // Modal mode: 'view' or 'edit'
public $modalMode = 'view'; // or 'edit' public $modalData = []; // Data for the modal
public $modalData = [];
public function viewRow($id)
{
$this->modalData = collect($this->rows)->firstWhere('id', $id) ?? [];
$this->modalMode = 'view';
$this->showModal = true;
}
public function editRow($id)
{
$this->modalData = collect($this->rows)->firstWhere('id', $id) ?? [];
$this->modalMode = 'edit';
$this->showModal = true;
}
public function closeModal()
{
$this->showModal = false;
$this->modalData = [];
}
/**
* Initialize the table with given columns and rows
*/
public function mount($columns, $rows, $addRoute = null) public function mount($columns, $rows, $addRoute = null)
{ {
$this->columns = $columns; $this->columns = $columns;
@ -52,13 +35,46 @@ public function closeModal()
$this->addRoute = $addRoute; $this->addRoute = $addRoute;
} }
// Update rows based on search /**
* View a row's details in the modal
*/
public function viewRow($id)
{
$this->modalData = collect($this->rows)->firstWhere('id', $id) ?? [];
$this->modalMode = 'view';
$this->showModal = true;
}
/**
* Edit a row's details in the modal
*/
public function editRow($id)
{
$this->modalData = collect($this->rows)->firstWhere('id', $id) ?? [];
$this->modalMode = 'edit';
$this->showModal = true;
}
/**
* Close the modal
*/
public function closeModal()
{
$this->showModal = false;
$this->modalData = [];
}
/**
* Update the selected rows based on search input
*/
public function updatedSearch() public function updatedSearch()
{ {
$this->selected = []; $this->selected = [];
} }
// Select all rows /**
* Select or deselect all rows
*/
public function selectAllRows() public function selectAllRows()
{ {
if ($this->selectAll) { if ($this->selectAll) {
@ -68,7 +84,9 @@ public function closeModal()
} }
} }
// Select single row /**
* Select or deselect a single row
*/
public function selectRow($rowId) public function selectRow($rowId)
{ {
if (in_array($rowId, $this->selected)) { if (in_array($rowId, $this->selected)) {
@ -78,7 +96,9 @@ public function closeModal()
} }
} }
// Sorting /**
* Sort rows by a specific field
*/
public function sortBy($field) public function sortBy($field)
{ {
if ($this->sortField === $field) { if ($this->sortField === $field) {
@ -93,6 +113,9 @@ public function closeModal()
}, SORT_REGULAR, $this->sortDirection === 'desc')->values()->all(); // Use all() to return plain array again }, SORT_REGULAR, $this->sortDirection === 'desc')->values()->all(); // Use all() to return plain array again
} }
/**
* Render the table view
*/
public function render() public function render()
{ {
return view('livewire.components.table', [ return view('livewire.components.table', [

View File

@ -1,12 +1,15 @@
<div class="mt-10"> <div class="mt-10">
<div class="p-4 bg-white shadow-md"> <div class="p-4 bg-white shadow-md">
<!-- Top Bar with Search & Add Button --> <!-- Top Bar with Search & Add Button -->
<div class="mb-4 flex items-center justify-between"> <div class="mb-4 flex items-center justify-between">
<!-- Search Input -->
<input type="text" wire:model.debounce.500ms="search" <input type="text" wire:model.debounce.500ms="search"
class="w-80 p-2 border border-gray-300 rounded-md" class="w-80 p-2 border border-gray-300 rounded-md"
placeholder="Search..." placeholder="Search..."
autofocus> autofocus>
<!-- Add Button (if enabled and route exists) -->
@if ($hasAddButton && $addRoute) @if ($hasAddButton && $addRoute)
<a href="{{ $addRoute }}" wire:navigate <a href="{{ $addRoute }}" wire:navigate
class="ml-4 px-4 py-2 bg-orange-500 text-white rounded-md hover:bg-orange-600"> class="ml-4 px-4 py-2 bg-orange-500 text-white rounded-md hover:bg-orange-600">
@ -15,15 +18,18 @@
@endif @endif
</div> </div>
<!-- Table Header -->
<table class="table-auto w-full"> <table class="table-auto w-full">
<thead class="bg-gray-100"> <thead class="bg-gray-100">
<tr> <tr>
<!-- Checkbox for selecting rows (if enabled) -->
@if ($hasCheckbox) @if ($hasCheckbox)
<th class="px-4 py-2 text-left"> <th class="px-4 py-2 text-left">
<input type="checkbox" wire:model="selectAll" wire:change="selectAllRows" class="cursor-pointer"> <input type="checkbox" wire:model="selectAll" wire:change="selectAllRows" class="cursor-pointer">
</th> </th>
@endif @endif
<!-- Dynamic Columns (sortable) -->
@foreach ($columns as $column) @foreach ($columns as $column)
<th class="px-4 py-2 text-left cursor-pointer" wire:click="sortBy('{{ $column['field'] }}')"> <th class="px-4 py-2 text-left cursor-pointer" wire:click="sortBy('{{ $column['field'] }}')">
{{ $column['label'] }} {{ $column['label'] }}
@ -39,14 +45,18 @@
</th> </th>
@endforeach @endforeach
<!-- Actions Column (if enabled) -->
@if ($hasActions) @if ($hasActions)
<th class="px-4 py-2 text-left">Actions</th> <th class="px-4 py-2 text-left">Actions</th>
@endif @endif
</tr> </tr>
</thead> </thead>
<!-- Table Body -->
<tbody> <tbody>
@forelse ($rows as $row) @forelse ($rows as $row)
<tr class="hover:bg-gray-50"> <tr class="hover:bg-gray-50">
<!-- Checkbox for row selection (if enabled) -->
@if ($hasCheckbox) @if ($hasCheckbox)
<td class="px-4 py-2"> <td class="px-4 py-2">
<input type="checkbox" wire:click="selectRow('{{ $row['id'] }}')" <input type="checkbox" wire:click="selectRow('{{ $row['id'] }}')"
@ -54,12 +64,14 @@
</td> </td>
@endif @endif
<!-- Display Data for each column -->
@foreach ($columns as $column) @foreach ($columns as $column)
<td class="px-4 py-2"> <td class="px-4 py-2">
{{ $row[$column['field']] ?? '' }} {{ $row[$column['field']] ?? '' }}
</td> </td>
@endforeach @endforeach
<!-- Action Buttons (if enabled) -->
@if ($hasActions) @if ($hasActions)
<td class="px-4 py-2 gap-2 flex"> <td class="px-4 py-2 gap-2 flex">
@if($isViewPage) @if($isViewPage)
@ -79,15 +91,28 @@
@endif @endif
</td> </td>
@endif @endif
</tr>
@empty
<tr>
<td colspan="{{ count($columns) + 1 }}" class="text-center p-4">No data available</td>
</tr>
@endforelse
</tbody>
</table>
<!-- Modal for Viewing / Editing Row -->
@if ($showModal) @if ($showModal)
<div class="fixed inset-0 bg-gray-900 bg-opacity-50 flex items-center justify-center z-50"> <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"> <div class="bg-white p-6 rounded-lg shadow-lg w-1/2">
<!-- Modal Header -->
<div class="flex justify-between items-center mb-4"> <div class="flex justify-between items-center mb-4">
<h2 class="text-lg font-semibold"> <h2 class="text-lg font-semibold">
{{ $modalMode === 'view' ? 'View Details' : 'Edit Details' }} {{ $modalMode === 'view' ? 'View Details' : 'Edit Details' }}
</h2> </h2>
<button wire:click="closeModal" class="text-gray-600 hover:text-gray-800">&times;</button> <button wire:click="closeModal" class="text-gray-600 hover:text-gray-800">&times;</button>
</div> </div>
<!-- Modal Body -->
<div class="space-y-4"> <div class="space-y-4">
@foreach ($columns as $column) @foreach ($columns as $column)
<div> <div>
@ -105,6 +130,8 @@
</div> </div>
@endforeach @endforeach
</div> </div>
<!-- Modal Footer with Save Button (if in edit mode) -->
@if ($modalMode === 'edit') @if ($modalMode === 'edit')
<div class="mt-6 flex justify-end"> <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"> <button wire:click="saveRow" class="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700">
@ -115,13 +142,5 @@
</div> </div>
</div> </div>
@endif @endif
</tr>
@empty
<tr>
<td colspan="{{ count($columns) + 1 }}" class="text-center p-4">No data available</td>
</tr>
@endforelse
</tbody>
</table>
</div> </div>
</div> </div>