codes convertion using livewire
This commit is contained in:
parent
9456bb3d57
commit
0077ae9ddb
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use Livewire\Component;
|
||||
|
||||
class AdvanceSearchFilter extends Component
|
||||
{
|
||||
public $filterField = '1'; // Default value
|
||||
public $filterValueStart = '';
|
||||
public $filterValueEnd = '';
|
||||
|
||||
public function submit()
|
||||
{
|
||||
$this->dispatch('formSubmitted', [
|
||||
'filter_field' => $this->filterField,
|
||||
'filter_value_start' => $this->filterValueStart,
|
||||
'filter_value_end' => $this->filterValueEnd,
|
||||
]);
|
||||
}
|
||||
|
||||
public function resetForm()
|
||||
{
|
||||
$this->reset(['filterField', 'filterValueStart', 'filterValueEnd']);
|
||||
$this->filterField = '1'; // Reset to default
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.advance-search-filter');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use Livewire\Component;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
|
||||
class CascaderForm extends Component
|
||||
{
|
||||
public $options = [];
|
||||
public $selected = [];
|
||||
public $url;
|
||||
|
||||
public function mount($url)
|
||||
{
|
||||
$this->url = $url;
|
||||
$this->fetchOptions();
|
||||
}
|
||||
|
||||
public function fetchOptions()
|
||||
{
|
||||
try {
|
||||
$response = Http::get($this->url);
|
||||
$this->options = $response->json('data') ?? [
|
||||
['value' => 'zhejiang', 'label' => 'Zhejiang', 'children' => [
|
||||
['value' => 'hangzhou', 'label' => 'Hangzhou', 'children' => [
|
||||
['value' => 'xihu', 'label' => 'West Lake']
|
||||
]]
|
||||
]],
|
||||
['value' => 'jiangsu', 'label' => 'Jiangsu', 'children' => [
|
||||
['value' => 'nanjing', 'label' => 'Nanjing', 'children' => [
|
||||
['value' => 'zhonghuamen', 'label' => 'Zhong Hua Men']
|
||||
]]
|
||||
]]
|
||||
];
|
||||
} catch (\Exception $e) {
|
||||
session()->flash('error', 'Failed to load options: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function updatedSelected()
|
||||
{
|
||||
$this->dispatch('cascaderChanged', $this->selected);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.cascader-form');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use Livewire\Component;
|
||||
|
||||
class CheckboxForm extends Component
|
||||
{
|
||||
public $value = false;
|
||||
public $name;
|
||||
public $label;
|
||||
public $inline = false;
|
||||
public $required = false;
|
||||
|
||||
public function mount($name, $label, $inline = false, $required = false)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->label = $label;
|
||||
$this->inline = $inline;
|
||||
$this->required = $required;
|
||||
}
|
||||
|
||||
public function updatedValue()
|
||||
{
|
||||
$this->dispatch('checkboxChanged', $this->value);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.checkbox-form');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use Livewire\Component;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
|
||||
class CustomTable extends Component
|
||||
{
|
||||
public $data = [];
|
||||
public $loading = false;
|
||||
public $currentPage = 1;
|
||||
public $pageSize = 10;
|
||||
public $totalData = 0;
|
||||
public $searchValue = '';
|
||||
public $sortedInfo = null;
|
||||
public $filteredInfo = [];
|
||||
public $columns = [];
|
||||
public $actions = [];
|
||||
public $url;
|
||||
public $keyValue = 'id';
|
||||
|
||||
// Initialize the component with URL, columns, actions, and key
|
||||
public function mount($url, $columns, $actions = [], $keyValue = 'id')
|
||||
{
|
||||
$this->url = $url;
|
||||
$this->columns = $columns;
|
||||
$this->actions = $actions;
|
||||
$this->keyValue = $keyValue;
|
||||
$this->fetchData();
|
||||
}
|
||||
|
||||
// Update data when search value changes (debounced in Blade)
|
||||
public function updatedSearchValue()
|
||||
{
|
||||
$this->currentPage = 1; // Reset to first page on search
|
||||
$this->fetchData();
|
||||
}
|
||||
|
||||
// Toggle sorting for a column
|
||||
public function sort($field)
|
||||
{
|
||||
if ($this->sortedInfo && $this->sortedInfo['field'] === $field) {
|
||||
$this->sortedInfo['order'] = $this->sortedInfo['order'] === 'asc' ? 'desc' : 'asc';
|
||||
} else {
|
||||
$this->sortedInfo = ['field' => $field, 'order' => 'asc'];
|
||||
}
|
||||
$this->fetchData();
|
||||
}
|
||||
|
||||
// Fetch data from the API
|
||||
public function fetchData()
|
||||
{
|
||||
$this->loading = true;
|
||||
$params = [
|
||||
'_page' => $this->currentPage,
|
||||
'_limit' => $this->pageSize,
|
||||
'q' => $this->searchValue,
|
||||
'_sort' => $this->sortedInfo ? $this->sortedInfo['field'] : null,
|
||||
'_order' => $this->sortedInfo ? $this->sortedInfo['order'] : null,
|
||||
];
|
||||
|
||||
try {
|
||||
$response = Http::get($this->url, $params);
|
||||
$this->data = $response->json('data') ?? []; // Adjust based on API response structure
|
||||
$this->totalData = $response->json('total') ?? count($this->data);
|
||||
} catch (\Exception $e) {
|
||||
session()->flash('error', 'Failed to load data: ' . $e->getMessage());
|
||||
} finally {
|
||||
$this->loading = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle pagination
|
||||
public function handlePagination($page)
|
||||
{
|
||||
$this->currentPage = $page;
|
||||
$this->fetchData();
|
||||
}
|
||||
|
||||
// Handle page size change (optional extension)
|
||||
public function handleSizeChange($size)
|
||||
{
|
||||
$this->pageSize = $size;
|
||||
$this->currentPage = 1; // Reset to first page
|
||||
$this->fetchData();
|
||||
}
|
||||
|
||||
// Clear all filters, sorting, and search
|
||||
public function handleClearAll()
|
||||
{
|
||||
$this->searchValue = '';
|
||||
$this->sortedInfo = null;
|
||||
$this->filteredInfo = [];
|
||||
$this->currentPage = 1;
|
||||
$this->fetchData();
|
||||
}
|
||||
|
||||
// Render the Blade view
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.custom-table');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use Livewire\Component;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
|
||||
class DataList extends Component
|
||||
{
|
||||
public $data = [];
|
||||
public $url;
|
||||
public $avatar = false;
|
||||
public $viewPath;
|
||||
public $header;
|
||||
public $footer;
|
||||
|
||||
public function mount($url, $avatar = false, $viewPath, $header = null, $footer = null)
|
||||
{
|
||||
$this->url = $url;
|
||||
$this->avatar = $avatar;
|
||||
$this->viewPath = $viewPath;
|
||||
$this->header = $header;
|
||||
$this->footer = $footer;
|
||||
$this->fetchData();
|
||||
}
|
||||
|
||||
public function fetchData()
|
||||
{
|
||||
try {
|
||||
$response = Http::get($this->url);
|
||||
$this->data = $response->json('data') ?? [];
|
||||
} catch (\Exception $e) {
|
||||
session()->flash('error', 'Failed to load data: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.data-list');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use Livewire\Component;
|
||||
use Carbon\Carbon;
|
||||
|
||||
class DatePickerForm extends Component
|
||||
{
|
||||
public $value;
|
||||
public $type = 'date';
|
||||
public $name;
|
||||
public $label;
|
||||
public $format = 'Y-m-d';
|
||||
public $minDateToday = false;
|
||||
public $required = false;
|
||||
public $disabledDateStart = false;
|
||||
public $dateStartEnd = null;
|
||||
public $disabledDateStartEndPhotoSlider = false;
|
||||
public $disabledDateStartEndPhotoSliderEndDate = false;
|
||||
public $isEdit = false;
|
||||
|
||||
public function mount($name, $label, $type = 'date', $format = 'Y-m-d', $minDateToday = false, $required = false, $disabledDateStart = false, $dateStartEnd = null, $disabledDateStartEndPhotoSlider = false, $disabledDateStartEndPhotoSliderEndDate = false, $isEdit = false)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->label = $label;
|
||||
$this->type = $type;
|
||||
$this->format = $format;
|
||||
$this->minDateToday = $minDateToday;
|
||||
$this->required = $required;
|
||||
$this->disabledDateStart = $disabledDateStart;
|
||||
$this->dateStartEnd = $dateStartEnd;
|
||||
$this->disabledDateStartEndPhotoSlider = $disabledDateStartEndPhotoSlider;
|
||||
$this->disabledDateStartEndPhotoSliderEndDate = $disabledDateStartEndPhotoSliderEndDate;
|
||||
$this->isEdit = $isEdit;
|
||||
}
|
||||
|
||||
public function updatedValue()
|
||||
{
|
||||
$this->dispatch('dateChanged', $this->value);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
$minDate = $this->minDateToday ? Carbon::today()->toDateString() : null;
|
||||
if ($this->disabledDateStart && $this->dateStartEnd) {
|
||||
$minDate = Carbon::parse($this->dateStartEnd['date_start'])->toDateString();
|
||||
}
|
||||
|
||||
return view('livewire.date-picker-form', ['minDate' => $minDate]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use Livewire\Component;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class DropdownExport extends Component
|
||||
{
|
||||
public $loading = false;
|
||||
public $url;
|
||||
public $defaultFilter = [];
|
||||
|
||||
public function mount($url, $defaultFilter = [])
|
||||
{
|
||||
$this->url = $url;
|
||||
$this->defaultFilter = $defaultFilter;
|
||||
}
|
||||
|
||||
public function handleExportCSV()
|
||||
{
|
||||
$this->loading = true;
|
||||
|
||||
try {
|
||||
// Merge query parameters with default filters
|
||||
$params = array_merge(request()->query(), $this->defaultFilter);
|
||||
$response = Http::withOptions(['response_type' => 'blob'])->get($this->url['path'], $params);
|
||||
|
||||
if ($response->successful()) {
|
||||
$dateNow = now()->format('mdY');
|
||||
$fileName = "{$this->url['fileName']}_{$dateNow}.csv";
|
||||
Storage::disk('local')->put($fileName, $response->body());
|
||||
return response()->download(storage_path("app/{$fileName}"))->deleteFileAfterSend(true);
|
||||
} else {
|
||||
session()->flash('error', 'Failed to export CSV.');
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
session()->flash('error', 'An error occurred: ' . $e->getMessage());
|
||||
} finally {
|
||||
$this->loading = false;
|
||||
}
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.dropdown-export');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use Livewire\Component;
|
||||
|
||||
class HeaderForm extends Component
|
||||
{
|
||||
public $title;
|
||||
public $actionBtnName = 'Save';
|
||||
public $cancelBtnName = 'Cancel';
|
||||
public $deleteBtnName = 'Delete';
|
||||
public $loading = false;
|
||||
public $withConfirm = false;
|
||||
public $withCancelConfirm = false;
|
||||
public $disabled = false;
|
||||
public $isDropDown = false;
|
||||
public $isInsideForm = false;
|
||||
|
||||
public function action()
|
||||
{
|
||||
$this->dispatch('actionTriggered');
|
||||
}
|
||||
|
||||
public function cancel()
|
||||
{
|
||||
$this->dispatch('cancelTriggered');
|
||||
}
|
||||
|
||||
public function deleteAction()
|
||||
{
|
||||
$this->dispatch('deleteTriggered');
|
||||
}
|
||||
|
||||
public function actionPrivacy()
|
||||
{
|
||||
$this->dispatch('privacyTriggered');
|
||||
}
|
||||
|
||||
public function actionTerms()
|
||||
{
|
||||
$this->dispatch('termsTriggered');
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.header-form');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use Livewire\Component;
|
||||
|
||||
class InputForm extends Component
|
||||
{
|
||||
public $value = '';
|
||||
public $name;
|
||||
public $label;
|
||||
public $required = false;
|
||||
public $withActionBtn = false;
|
||||
public $isCopyUsername = false;
|
||||
public $loading = false;
|
||||
|
||||
public function mount($name, $label, $required = false, $withActionBtn = false, $isCopyUsername = false, $loading = false)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->label = $label;
|
||||
$this->required = $required;
|
||||
$this->withActionBtn = $withActionBtn;
|
||||
$this->isCopyUsername = $isCopyUsername;
|
||||
$this->loading = $loading;
|
||||
}
|
||||
|
||||
public function updatedValue()
|
||||
{
|
||||
$this->dispatch('inputChanged', $this->value);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.input-form');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use Livewire\Component;
|
||||
|
||||
class InputMaskNumberForm extends Component
|
||||
{
|
||||
public $value = '';
|
||||
public $name;
|
||||
public $label;
|
||||
public $required = false;
|
||||
public $mask = '999-999-9999'; // Example mask
|
||||
|
||||
public function mount($name, $label, $required = false, $mask = '999-999-9999')
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->label = $label;
|
||||
$this->required = $required;
|
||||
$this->mask = $mask;
|
||||
}
|
||||
|
||||
public function updatedValue()
|
||||
{
|
||||
$this->dispatch('inputChanged', $this->value);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.input-mask-number-form');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use Livewire\Component;
|
||||
|
||||
class InputNumberAntD extends Component
|
||||
{
|
||||
public $value = 0;
|
||||
public $name;
|
||||
public $label;
|
||||
public $required = false;
|
||||
public $min = null;
|
||||
public $max = null;
|
||||
public $step = 1;
|
||||
|
||||
public function mount($name, $label, $required = false, $min = null, $max = null, $step = 1)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->label = $label;
|
||||
$this->required = $required;
|
||||
$this->min = $min;
|
||||
$this->max = $max;
|
||||
$this->step = $step;
|
||||
}
|
||||
|
||||
public function updatedValue()
|
||||
{
|
||||
$this->dispatch('numberChanged', $this->value);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.input-number-ant-d');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use Livewire\Component;
|
||||
|
||||
class InputPassword extends Component
|
||||
{
|
||||
public $value = '';
|
||||
public $name;
|
||||
public $label;
|
||||
public $required = false;
|
||||
|
||||
public function mount($name, $label, $required = false)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->label = $label;
|
||||
$this->required = $required;
|
||||
}
|
||||
|
||||
public function updatedValue()
|
||||
{
|
||||
$this->dispatch('passwordChanged', $this->value);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.input-password');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use Livewire\Component;
|
||||
|
||||
class InputTextArea extends Component
|
||||
{
|
||||
public $value = '';
|
||||
public $name;
|
||||
public $label;
|
||||
public $required = false;
|
||||
public $onCountText = false;
|
||||
public $charsperpage = 100;
|
||||
public $hasIcon = false;
|
||||
|
||||
public function mount($name, $label, $required = false, $onCountText = false, $charsperpage = 100, $hasIcon = false)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->label = $label;
|
||||
$this->required = $required;
|
||||
$this->onCountText = $onCountText;
|
||||
$this->charsperpage = $charsperpage;
|
||||
$this->hasIcon = $hasIcon;
|
||||
}
|
||||
|
||||
public function updatedValue()
|
||||
{
|
||||
$this->dispatch('textAreaChanged', $this->value);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.input-text-area');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use Livewire\Component;
|
||||
|
||||
class Loading extends Component
|
||||
{
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.loading');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use Livewire\Component;
|
||||
|
||||
class LoginLayout extends Component
|
||||
{
|
||||
public $children;
|
||||
|
||||
public function mount($children = null)
|
||||
{
|
||||
$this->children = $children;
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.login-layout');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use Livewire\Component;
|
||||
|
||||
class ModalCancel extends Component
|
||||
{
|
||||
public $visible = false;
|
||||
public $path;
|
||||
public $title;
|
||||
public $message;
|
||||
public $id;
|
||||
public $dirty = false;
|
||||
public $name;
|
||||
public $loading = false;
|
||||
|
||||
public function mount($path, $title = null, $message = null, $id = null, $dirty = false, $name = null, $loading = false)
|
||||
{
|
||||
$this->path = $path;
|
||||
$this->title = $title ?? 'Your Title';
|
||||
$this->message = $message ?? 'Your Message';
|
||||
$this->id = $id;
|
||||
$this->dirty = $dirty;
|
||||
$this->name = $name ?? 'Cancel';
|
||||
$this->loading = $loading;
|
||||
}
|
||||
|
||||
public function showModal()
|
||||
{
|
||||
$this->visible = true;
|
||||
}
|
||||
|
||||
public function handleCancel()
|
||||
{
|
||||
$this->visible = false;
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.modal-cancel');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use Livewire\Component;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
|
||||
class MultiSelectForm extends Component
|
||||
{
|
||||
public $value = [];
|
||||
public $name;
|
||||
public $label;
|
||||
public $required = false;
|
||||
public $optionsList = [];
|
||||
public $url;
|
||||
|
||||
public function mount($name, $label, $required = false, $url = null, $optionsList = [])
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->label = $label;
|
||||
$this->required = $required;
|
||||
$this->url = $url;
|
||||
$this->optionsList = $optionsList;
|
||||
if ($url) {
|
||||
$this->fetchOptions();
|
||||
}
|
||||
}
|
||||
|
||||
public function fetchOptions()
|
||||
{
|
||||
try {
|
||||
$response = Http::get($this->url);
|
||||
$this->optionsList = $response->json('data') ?? [];
|
||||
} catch (\Exception $e) {
|
||||
session()->flash('error', 'Failed to load options: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function updatedValue()
|
||||
{
|
||||
$this->dispatch('multiSelectChanged', $this->value);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.multi-select-form');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use Livewire\Component;
|
||||
|
||||
class MultiSelectOptions extends Component
|
||||
{
|
||||
public $value = [];
|
||||
public $name;
|
||||
public $label;
|
||||
public $required = false;
|
||||
public $optionsList = [];
|
||||
|
||||
public function mount($name, $label, $required = false, $optionsList = [])
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->label = $label;
|
||||
$this->required = $required;
|
||||
$this->optionsList = $optionsList;
|
||||
}
|
||||
|
||||
public function updatedValue()
|
||||
{
|
||||
$this->dispatch('multiSelectOptionsChanged', $this->value);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.multi-select-options');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,147 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use Livewire\Component;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
|
||||
class NotificationTable extends Component
|
||||
{
|
||||
public $data = [];
|
||||
public $total = 0;
|
||||
public $loading = false;
|
||||
public $selectedRowKeys = [];
|
||||
public $searchFilter = '';
|
||||
public $mounted = false;
|
||||
public $updating = false;
|
||||
public $columns = [];
|
||||
public $currentPage = 1;
|
||||
public $perPage = 10;
|
||||
public $sortBy = '';
|
||||
public $sortOrder = '';
|
||||
public $filters = [];
|
||||
|
||||
public $props = [];
|
||||
|
||||
protected $queryString = ['searchFilter', 'currentPage', 'perPage', 'sortBy', 'sortOrder', 'filters'];
|
||||
|
||||
public function mount($props)
|
||||
{
|
||||
$this->props = $props;
|
||||
$this->mounted = true;
|
||||
$this->columns = $props['columns'] ?? [];
|
||||
$this->fetchData();
|
||||
}
|
||||
|
||||
public function updatedSearchFilter()
|
||||
{
|
||||
$this->resetPage();
|
||||
$this->fetchData();
|
||||
}
|
||||
|
||||
public function setSort($field)
|
||||
{
|
||||
if ($this->sortBy === $field) {
|
||||
$this->sortOrder = $this->sortOrder === 'asc' ? 'desc' : 'asc';
|
||||
} else {
|
||||
$this->sortBy = $field;
|
||||
$this->sortOrder = 'asc';
|
||||
}
|
||||
$this->fetchData();
|
||||
}
|
||||
|
||||
public function clearAll()
|
||||
{
|
||||
$this->reset(['searchFilter', 'filters', 'sortBy', 'sortOrder', 'selectedRowKeys']);
|
||||
$this->fetchData();
|
||||
}
|
||||
|
||||
public function updatePage($page)
|
||||
{
|
||||
$this->currentPage = $page;
|
||||
$this->fetchData();
|
||||
}
|
||||
|
||||
public function delete($uuid)
|
||||
{
|
||||
try {
|
||||
$api = env('REACT_APP_STATION_API'); // Ensure this is set in your .env file
|
||||
$path = substr(request()->path(), 1); // Get current path
|
||||
$response = Http::delete("{$api}{$path}/{$uuid}");
|
||||
|
||||
if ($response->successful()) {
|
||||
session()->flash('success', 'Record was successfully deleted.');
|
||||
$this->fetchData();
|
||||
} else {
|
||||
session()->flash('error', 'Something went wrong deleting the record.');
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
session()->flash('error', 'An error occurred: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function handleBatchDelete()
|
||||
{
|
||||
if (empty($this->selectedRowKeys)) return;
|
||||
|
||||
try {
|
||||
$response = Http::delete("your-external-api-endpoint/{$this->props['url']['apiDelete']}", [
|
||||
'data' => [$this->props['keyValue'] => $this->selectedRowKeys]
|
||||
]);
|
||||
|
||||
if ($response->successful()) {
|
||||
session()->flash('success', 'Records were successfully deleted.');
|
||||
$this->selectedRowKeys = [];
|
||||
$this->fetchData();
|
||||
} else {
|
||||
session()->flash('error', 'Something went wrong deleting records.');
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
session()->flash('error', 'An error occurred: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function fetchData()
|
||||
{
|
||||
$this->loading = true;
|
||||
|
||||
$params = array_filter([
|
||||
'page' => $this->currentPage,
|
||||
'page_size' => $this->perPage,
|
||||
'search' => $this->searchFilter,
|
||||
'sort_by' => $this->sortBy,
|
||||
'sort_order' => $this->sortOrder,
|
||||
...$this->filters,
|
||||
]);
|
||||
|
||||
try {
|
||||
$defaultUrl = $this->props['url']['default'] ?? 'notification';
|
||||
$response = Http::get("your-external-api-endpoint/{$defaultUrl}", $params);
|
||||
$data = $response->json();
|
||||
|
||||
$this->data = $data['data'] ?? [];
|
||||
$this->total = $data['total'] ?? 0;
|
||||
|
||||
if (empty($this->data) && $this->props['isEmptyMessagePopUp']) {
|
||||
session()->flash('info', 'No records found.');
|
||||
}
|
||||
|
||||
} catch (\Exception $e) {
|
||||
session()->flash('error', 'An error occurred while fetching data: ' . $e->getMessage());
|
||||
$this->data = [];
|
||||
$this->total = 0;
|
||||
} finally {
|
||||
$this->loading = false;
|
||||
}
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.notification-table', [
|
||||
'columns' => $this->columns,
|
||||
'keyValue' => $this->props['keyValue'] ?? 'id',
|
||||
'apiDelete' => $this->props['url']['apiDelete'] ?? false,
|
||||
'url' => $this->props['url'] ?? [],
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use Livewire\Component;
|
||||
|
||||
class Page404New extends Component
|
||||
{
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.page404-new');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use Livewire\Component;
|
||||
|
||||
class RadioForm extends Component
|
||||
{
|
||||
public $value;
|
||||
public $name;
|
||||
public $label;
|
||||
public $optionsList = [];
|
||||
public $isRadioButton = false;
|
||||
public $required = false;
|
||||
|
||||
public function mount($name, $label, $optionsList = [], $isRadioButton = false, $required = false)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->label = $label;
|
||||
$this->optionsList = $optionsList;
|
||||
$this->isRadioButton = $isRadioButton;
|
||||
$this->required = $required;
|
||||
}
|
||||
|
||||
public function updatedValue()
|
||||
{
|
||||
$this->dispatch('radioChanged', $this->value);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.radio-form');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use Livewire\Component;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
|
||||
class SelectForm extends Component
|
||||
{
|
||||
public $value;
|
||||
public $name;
|
||||
public $label;
|
||||
public $required = false;
|
||||
public $optionsList = [];
|
||||
public $url;
|
||||
|
||||
public function mount($name, $label, $required = false, $url = null, $optionsList = [])
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->label = $label;
|
||||
$this->required = $required;
|
||||
$this->url = $url;
|
||||
$this->optionsList = $optionsList;
|
||||
if ($url) {
|
||||
$this->fetchOptions();
|
||||
}
|
||||
}
|
||||
|
||||
public function fetchOptions()
|
||||
{
|
||||
try {
|
||||
$response = Http::get($this->url);
|
||||
$this->optionsList = $response->json('data') ?? [];
|
||||
} catch (\Exception $e) {
|
||||
session()->flash('error', 'Failed to load options: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function updatedValue()
|
||||
{
|
||||
$this->dispatch('selectChanged', $this->value);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.select-form');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use Livewire\Component;
|
||||
use Livewire\WithFileUploads;
|
||||
|
||||
class SingleUploadImage extends Component
|
||||
{
|
||||
use WithFileUploads;
|
||||
|
||||
public $image;
|
||||
public $name;
|
||||
public $label;
|
||||
public $required = false;
|
||||
public $limit100kb = false;
|
||||
public $imgStyle = ['width' => '100%', 'height' => '135px'];
|
||||
|
||||
public function updatedImage()
|
||||
{
|
||||
$this->validate([
|
||||
'image' => 'image|mimes:jpeg,png,gif|max:' . ($this->limit100kb ? '100' : '2048'), // 100KB or 2MB
|
||||
]);
|
||||
|
||||
$this->dispatch('imageUploaded', $this->image);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.single-upload-image');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use Livewire\Component;
|
||||
|
||||
class TimePickerForm extends Component
|
||||
{
|
||||
public $value;
|
||||
public $name;
|
||||
public $label;
|
||||
public $format = 'H:i';
|
||||
public $required = false;
|
||||
|
||||
public function mount($name, $label, $format = 'H:i', $required = false)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->label = $label;
|
||||
$this->format = $format;
|
||||
$this->required = $required;
|
||||
}
|
||||
|
||||
public function updatedValue()
|
||||
{
|
||||
$this->dispatch('timeChanged', $this->value);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.time-picker-form');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use Livewire\Component;
|
||||
use Livewire\WithFileUploads;
|
||||
|
||||
class UploadImage extends Component
|
||||
{
|
||||
use WithFileUploads;
|
||||
|
||||
public $image; // Holds the uploaded file(s)
|
||||
public $name; // Input name
|
||||
public $label; // Input label
|
||||
public $required = false; // Required field flag
|
||||
public $limit100kb = false; // Limit file size to 100KB or 2MB
|
||||
public $imgStyle = ['width' => '100%', 'height' => '135px']; // Image style
|
||||
public $multipleFileUpload = false; // Toggle multiple uploads
|
||||
public $imageUrl; // URL for single image preview
|
||||
public $fileList = []; // Array for multiple image previews
|
||||
public $loading = false; // Loading state (not used extensively here)
|
||||
|
||||
// Mount method to initialize props from the view
|
||||
public function mount($name, $label, $required = false, $limit100kb = false, $imgStyle = ['width' => '100%', 'height' => '135px'], $multipleFileUpload = false, $imageUrl = null)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->label = $label;
|
||||
$this->required = $required;
|
||||
$this->limit100kb = $limit100kb;
|
||||
$this->imgStyle = $imgStyle;
|
||||
$this->multipleFileUpload = $multipleFileUpload;
|
||||
$this->imageUrl = $imageUrl;
|
||||
}
|
||||
|
||||
// Validation and preview logic when the image is updated
|
||||
public function updatedImage()
|
||||
{
|
||||
$this->validate([
|
||||
'image' => 'required|image|mimes:jpeg,png,gif|max:' . ($this->limit100kb ? '100' : '2048'), // 100KB or 2MB
|
||||
]);
|
||||
|
||||
if ($this->multipleFileUpload) {
|
||||
$this->fileList = array_map(function ($file) {
|
||||
return $file->temporaryUrl();
|
||||
}, $this->image);
|
||||
} else {
|
||||
$this->imageUrl = $this->image->temporaryUrl();
|
||||
}
|
||||
|
||||
// Dispatch an event to notify parent components (similar to handleFileUpload in React)
|
||||
$this->dispatch('imageUploaded', $this->image);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.upload-image');
|
||||
}
|
||||
}
|
|
@ -45,11 +45,11 @@ return [
|
|||
'mysql' => [
|
||||
'driver' => 'mysql',
|
||||
'url' => env('DB_URL'),
|
||||
'host' => env('DB_HOST', '127.0.0.1'),
|
||||
'host' => env('DB_HOST', 'mysql'),
|
||||
'port' => env('DB_PORT', '3306'),
|
||||
'database' => env('DB_DATABASE', 'laravel'),
|
||||
'username' => env('DB_USERNAME', 'root'),
|
||||
'password' => env('DB_PASSWORD', ''),
|
||||
'database' => env('DB_DATABASE', 'laravel-cms'),
|
||||
'username' => env('DB_USERNAME', 'laravel_user'),
|
||||
'password' => env('DB_PASSWORD', 'password'),
|
||||
'unix_socket' => env('DB_SOCKET', ''),
|
||||
'charset' => env('DB_CHARSET', 'utf8mb4'),
|
||||
'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'),
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
version: '3.8'
|
||||
|
||||
services:
|
||||
# Laravel App
|
||||
app:
|
||||
build:
|
||||
context: ./docker/php
|
||||
dockerfile: Dockerfile
|
||||
container_name: laravel-app
|
||||
restart: always
|
||||
working_dir: /var/www
|
||||
volumes:
|
||||
- .:/var/www
|
||||
depends_on:
|
||||
db_mysql:
|
||||
condition: service_healthy
|
||||
command: >
|
||||
/bin/sh -c '
|
||||
mkdir -p /var/www/storage /var/www/bootstrap/cache &&
|
||||
chown -R www-data:www-data /var/www/storage /var/www/bootstrap/cache &&
|
||||
chmod -R 775 /var/www/storage /var/www/bootstrap/cache &&
|
||||
composer install --no-dev --optimize-autoloader &&
|
||||
php artisan migrate --force &&
|
||||
php-fpm '
|
||||
healthcheck:
|
||||
test: ["CMD", "sh", "-c", "pgrep php-fpm"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 10
|
||||
networks:
|
||||
- app_network
|
||||
|
||||
# MySQL
|
||||
db_mysql:
|
||||
image: mysql:8.0
|
||||
container_name: db_mysql
|
||||
restart: always
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: newpassword
|
||||
MYSQL_DATABASE: laravel-cms
|
||||
MYSQL_USER: laravel_user
|
||||
MYSQL_PASSWORD: password
|
||||
MYSQL_ALLOW_EMPTY_PASSWORD: "no"
|
||||
volumes:
|
||||
- mysql-data:/var/lib/mysql
|
||||
healthcheck:
|
||||
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-uroot", "-pnewpassword"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
networks:
|
||||
- app_network
|
||||
|
||||
# Nginx
|
||||
web:
|
||||
image: nginx:1.26.3-alpine
|
||||
container_name: web
|
||||
restart: always
|
||||
ports:
|
||||
- "8000:80"
|
||||
volumes:
|
||||
- .:/var/www
|
||||
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:rw
|
||||
depends_on:
|
||||
app:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 5
|
||||
networks:
|
||||
- app_network
|
||||
|
||||
volumes:
|
||||
mysql-data:
|
||||
|
||||
networks:
|
||||
app_network:
|
||||
driver: bridge
|
|
@ -0,0 +1,28 @@
|
|||
server {
|
||||
listen 80;
|
||||
server_name localhost;
|
||||
|
||||
root /var/www/public;
|
||||
index index.php index.html;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.php?$query_string;
|
||||
}
|
||||
|
||||
location ~ \.php$ {
|
||||
try_files $uri =404;
|
||||
include fastcgi.conf;
|
||||
fastcgi_pass app:9000;
|
||||
fastcgi_index index.php;
|
||||
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
|
||||
fastcgi_param DOCUMENT_ROOT $realpath_root;
|
||||
}
|
||||
|
||||
# Deny access to .htaccess files
|
||||
location ~ /\.ht {
|
||||
deny all;
|
||||
}
|
||||
|
||||
error_log /var/log/nginx/error.log;
|
||||
access_log /var/log/nginx/access.log;
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
# Use PHP 8.2 Alpine (compatible with Laravel 11)
|
||||
FROM php:8.2-fpm-alpine
|
||||
|
||||
# Install required dependencies
|
||||
RUN apk add --no-cache \
|
||||
oniguruma-dev \
|
||||
libpng-dev \
|
||||
libjpeg-turbo-dev \
|
||||
libwebp-dev \
|
||||
freetype-dev \
|
||||
libzip-dev \
|
||||
zip \
|
||||
unzip \
|
||||
openssl # Laravel requires OpenSSL for encryption
|
||||
|
||||
# Install required extensions
|
||||
RUN docker-php-ext-configure gd --with-freetype --with-jpeg --with-webp \
|
||||
&& docker-php-ext-install gd pdo pdo_mysql bcmath mbstring zip
|
||||
|
||||
# Install Composer (using official Composer image)
|
||||
COPY --from=composer:2.7 /usr/bin/composer /usr/bin/composer
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /var/www
|
||||
|
||||
# Copy Laravel application files BEFORE running composer install
|
||||
COPY . /var/www/
|
||||
|
||||
# Ensure composer.json exists before running install
|
||||
RUN if [ -f "composer.json" ]; then composer install --no-dev --optimize-autoloader; else echo "composer.json not found!"; fi
|
||||
|
||||
# Ensure required Laravel directories exist and set permissions
|
||||
RUN mkdir -p /var/www/storage /var/www/bootstrap/cache && \
|
||||
chown -R www-data:www-data /var/www && \
|
||||
chmod -R 775 /var/www/storage /var/www/bootstrap/cache
|
||||
|
||||
# Expose PHP-FPM port
|
||||
EXPOSE 9000
|
||||
|
||||
# Start PHP-FPM server
|
||||
CMD ["php-fpm"]
|
|
@ -0,0 +1,34 @@
|
|||
<?php return array (
|
||||
'laravel/tinker' =>
|
||||
array (
|
||||
'providers' =>
|
||||
array (
|
||||
0 => 'Laravel\\Tinker\\TinkerServiceProvider',
|
||||
),
|
||||
),
|
||||
'livewire/livewire' =>
|
||||
array (
|
||||
'aliases' =>
|
||||
array (
|
||||
'Livewire' => 'Livewire\\Livewire',
|
||||
),
|
||||
'providers' =>
|
||||
array (
|
||||
0 => 'Livewire\\LivewireServiceProvider',
|
||||
),
|
||||
),
|
||||
'nesbot/carbon' =>
|
||||
array (
|
||||
'providers' =>
|
||||
array (
|
||||
0 => 'Carbon\\Laravel\\ServiceProvider',
|
||||
),
|
||||
),
|
||||
'nunomaduro/termwind' =>
|
||||
array (
|
||||
'providers' =>
|
||||
array (
|
||||
0 => 'Termwind\\Laravel\\TermwindServiceProvider',
|
||||
),
|
||||
),
|
||||
);
|
|
@ -0,0 +1,248 @@
|
|||
<?php return array (
|
||||
'providers' =>
|
||||
array (
|
||||
0 => 'Illuminate\\Auth\\AuthServiceProvider',
|
||||
1 => 'Illuminate\\Broadcasting\\BroadcastServiceProvider',
|
||||
2 => 'Illuminate\\Bus\\BusServiceProvider',
|
||||
3 => 'Illuminate\\Cache\\CacheServiceProvider',
|
||||
4 => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
5 => 'Illuminate\\Concurrency\\ConcurrencyServiceProvider',
|
||||
6 => 'Illuminate\\Cookie\\CookieServiceProvider',
|
||||
7 => 'Illuminate\\Database\\DatabaseServiceProvider',
|
||||
8 => 'Illuminate\\Encryption\\EncryptionServiceProvider',
|
||||
9 => 'Illuminate\\Filesystem\\FilesystemServiceProvider',
|
||||
10 => 'Illuminate\\Foundation\\Providers\\FoundationServiceProvider',
|
||||
11 => 'Illuminate\\Hashing\\HashServiceProvider',
|
||||
12 => 'Illuminate\\Mail\\MailServiceProvider',
|
||||
13 => 'Illuminate\\Notifications\\NotificationServiceProvider',
|
||||
14 => 'Illuminate\\Pagination\\PaginationServiceProvider',
|
||||
15 => 'Illuminate\\Auth\\Passwords\\PasswordResetServiceProvider',
|
||||
16 => 'Illuminate\\Pipeline\\PipelineServiceProvider',
|
||||
17 => 'Illuminate\\Queue\\QueueServiceProvider',
|
||||
18 => 'Illuminate\\Redis\\RedisServiceProvider',
|
||||
19 => 'Illuminate\\Session\\SessionServiceProvider',
|
||||
20 => 'Illuminate\\Translation\\TranslationServiceProvider',
|
||||
21 => 'Illuminate\\Validation\\ValidationServiceProvider',
|
||||
22 => 'Illuminate\\View\\ViewServiceProvider',
|
||||
23 => 'Laravel\\Tinker\\TinkerServiceProvider',
|
||||
24 => 'Livewire\\LivewireServiceProvider',
|
||||
25 => 'Carbon\\Laravel\\ServiceProvider',
|
||||
26 => 'Termwind\\Laravel\\TermwindServiceProvider',
|
||||
27 => 'App\\Providers\\AppServiceProvider',
|
||||
),
|
||||
'eager' =>
|
||||
array (
|
||||
0 => 'Illuminate\\Auth\\AuthServiceProvider',
|
||||
1 => 'Illuminate\\Cookie\\CookieServiceProvider',
|
||||
2 => 'Illuminate\\Database\\DatabaseServiceProvider',
|
||||
3 => 'Illuminate\\Encryption\\EncryptionServiceProvider',
|
||||
4 => 'Illuminate\\Filesystem\\FilesystemServiceProvider',
|
||||
5 => 'Illuminate\\Foundation\\Providers\\FoundationServiceProvider',
|
||||
6 => 'Illuminate\\Notifications\\NotificationServiceProvider',
|
||||
7 => 'Illuminate\\Pagination\\PaginationServiceProvider',
|
||||
8 => 'Illuminate\\Session\\SessionServiceProvider',
|
||||
9 => 'Illuminate\\View\\ViewServiceProvider',
|
||||
10 => 'Livewire\\LivewireServiceProvider',
|
||||
11 => 'Carbon\\Laravel\\ServiceProvider',
|
||||
12 => 'Termwind\\Laravel\\TermwindServiceProvider',
|
||||
13 => 'App\\Providers\\AppServiceProvider',
|
||||
),
|
||||
'deferred' =>
|
||||
array (
|
||||
'Illuminate\\Broadcasting\\BroadcastManager' => 'Illuminate\\Broadcasting\\BroadcastServiceProvider',
|
||||
'Illuminate\\Contracts\\Broadcasting\\Factory' => 'Illuminate\\Broadcasting\\BroadcastServiceProvider',
|
||||
'Illuminate\\Contracts\\Broadcasting\\Broadcaster' => 'Illuminate\\Broadcasting\\BroadcastServiceProvider',
|
||||
'Illuminate\\Bus\\Dispatcher' => 'Illuminate\\Bus\\BusServiceProvider',
|
||||
'Illuminate\\Contracts\\Bus\\Dispatcher' => 'Illuminate\\Bus\\BusServiceProvider',
|
||||
'Illuminate\\Contracts\\Bus\\QueueingDispatcher' => 'Illuminate\\Bus\\BusServiceProvider',
|
||||
'Illuminate\\Bus\\BatchRepository' => 'Illuminate\\Bus\\BusServiceProvider',
|
||||
'Illuminate\\Bus\\DatabaseBatchRepository' => 'Illuminate\\Bus\\BusServiceProvider',
|
||||
'cache' => 'Illuminate\\Cache\\CacheServiceProvider',
|
||||
'cache.store' => 'Illuminate\\Cache\\CacheServiceProvider',
|
||||
'cache.psr6' => 'Illuminate\\Cache\\CacheServiceProvider',
|
||||
'memcached.connector' => 'Illuminate\\Cache\\CacheServiceProvider',
|
||||
'Illuminate\\Cache\\RateLimiter' => 'Illuminate\\Cache\\CacheServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\AboutCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Cache\\Console\\ClearCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Cache\\Console\\ForgetCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\ClearCompiledCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Auth\\Console\\ClearResetsCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\ConfigCacheCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\ConfigClearCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\ConfigShowCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Database\\Console\\DbCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Database\\Console\\MonitorCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Database\\Console\\PruneCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Database\\Console\\ShowCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Database\\Console\\TableCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Database\\Console\\WipeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\DownCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\EnvironmentCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\EnvironmentDecryptCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\EnvironmentEncryptCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\EventCacheCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\EventClearCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\EventListCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Concurrency\\Console\\InvokeSerializedClosureCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\KeyGenerateCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\OptimizeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\OptimizeClearCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\PackageDiscoverCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Cache\\Console\\PruneStaleTagsCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Queue\\Console\\ClearCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Queue\\Console\\ListFailedCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Queue\\Console\\FlushFailedCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Queue\\Console\\ForgetFailedCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Queue\\Console\\ListenCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Queue\\Console\\MonitorCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Queue\\Console\\PruneBatchesCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Queue\\Console\\PruneFailedJobsCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Queue\\Console\\RestartCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Queue\\Console\\RetryCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Queue\\Console\\RetryBatchCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Queue\\Console\\WorkCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\RouteCacheCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\RouteClearCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\RouteListCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Database\\Console\\DumpCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Database\\Console\\Seeds\\SeedCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Console\\Scheduling\\ScheduleFinishCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Console\\Scheduling\\ScheduleListCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Console\\Scheduling\\ScheduleRunCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Console\\Scheduling\\ScheduleClearCacheCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Console\\Scheduling\\ScheduleTestCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Console\\Scheduling\\ScheduleWorkCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Console\\Scheduling\\ScheduleInterruptCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Database\\Console\\ShowModelCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\StorageLinkCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\StorageUnlinkCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\UpCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\ViewCacheCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\ViewClearCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\ApiInstallCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\BroadcastingInstallCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Cache\\Console\\CacheTableCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\CastMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\ChannelListCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\ChannelMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\ClassMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\ComponentMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\ConfigPublishCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\ConsoleMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Routing\\Console\\ControllerMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\DocsCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\EnumMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\EventGenerateCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\EventMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\ExceptionMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Database\\Console\\Factories\\FactoryMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\InterfaceMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\JobMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\JobMiddlewareMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\LangPublishCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\ListenerMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\MailMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Routing\\Console\\MiddlewareMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\ModelMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\NotificationMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Notifications\\Console\\NotificationTableCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\ObserverMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\PolicyMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\ProviderMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Queue\\Console\\FailedTableCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Queue\\Console\\TableCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Queue\\Console\\BatchesTableCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\RequestMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\ResourceMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\RuleMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\ScopeMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Database\\Console\\Seeds\\SeederMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Session\\Console\\SessionTableCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\ServeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\StubPublishCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\TestMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\TraitMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\VendorPublishCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Foundation\\Console\\ViewMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'migrator' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'migration.repository' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'migration.creator' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Database\\Console\\Migrations\\MigrateCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Database\\Console\\Migrations\\FreshCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Database\\Console\\Migrations\\InstallCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Database\\Console\\Migrations\\RefreshCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Database\\Console\\Migrations\\ResetCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Database\\Console\\Migrations\\RollbackCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Database\\Console\\Migrations\\StatusCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Database\\Console\\Migrations\\MigrateMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'composer' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider',
|
||||
'Illuminate\\Concurrency\\ConcurrencyManager' => 'Illuminate\\Concurrency\\ConcurrencyServiceProvider',
|
||||
'hash' => 'Illuminate\\Hashing\\HashServiceProvider',
|
||||
'hash.driver' => 'Illuminate\\Hashing\\HashServiceProvider',
|
||||
'mail.manager' => 'Illuminate\\Mail\\MailServiceProvider',
|
||||
'mailer' => 'Illuminate\\Mail\\MailServiceProvider',
|
||||
'Illuminate\\Mail\\Markdown' => 'Illuminate\\Mail\\MailServiceProvider',
|
||||
'auth.password' => 'Illuminate\\Auth\\Passwords\\PasswordResetServiceProvider',
|
||||
'auth.password.broker' => 'Illuminate\\Auth\\Passwords\\PasswordResetServiceProvider',
|
||||
'Illuminate\\Contracts\\Pipeline\\Hub' => 'Illuminate\\Pipeline\\PipelineServiceProvider',
|
||||
'pipeline' => 'Illuminate\\Pipeline\\PipelineServiceProvider',
|
||||
'queue' => 'Illuminate\\Queue\\QueueServiceProvider',
|
||||
'queue.connection' => 'Illuminate\\Queue\\QueueServiceProvider',
|
||||
'queue.failer' => 'Illuminate\\Queue\\QueueServiceProvider',
|
||||
'queue.listener' => 'Illuminate\\Queue\\QueueServiceProvider',
|
||||
'queue.worker' => 'Illuminate\\Queue\\QueueServiceProvider',
|
||||
'redis' => 'Illuminate\\Redis\\RedisServiceProvider',
|
||||
'redis.connection' => 'Illuminate\\Redis\\RedisServiceProvider',
|
||||
'translator' => 'Illuminate\\Translation\\TranslationServiceProvider',
|
||||
'translation.loader' => 'Illuminate\\Translation\\TranslationServiceProvider',
|
||||
'validator' => 'Illuminate\\Validation\\ValidationServiceProvider',
|
||||
'validation.presence' => 'Illuminate\\Validation\\ValidationServiceProvider',
|
||||
'Illuminate\\Contracts\\Validation\\UncompromisedVerifier' => 'Illuminate\\Validation\\ValidationServiceProvider',
|
||||
'command.tinker' => 'Laravel\\Tinker\\TinkerServiceProvider',
|
||||
),
|
||||
'when' =>
|
||||
array (
|
||||
'Illuminate\\Broadcasting\\BroadcastServiceProvider' =>
|
||||
array (
|
||||
),
|
||||
'Illuminate\\Bus\\BusServiceProvider' =>
|
||||
array (
|
||||
),
|
||||
'Illuminate\\Cache\\CacheServiceProvider' =>
|
||||
array (
|
||||
),
|
||||
'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider' =>
|
||||
array (
|
||||
),
|
||||
'Illuminate\\Concurrency\\ConcurrencyServiceProvider' =>
|
||||
array (
|
||||
),
|
||||
'Illuminate\\Hashing\\HashServiceProvider' =>
|
||||
array (
|
||||
),
|
||||
'Illuminate\\Mail\\MailServiceProvider' =>
|
||||
array (
|
||||
),
|
||||
'Illuminate\\Auth\\Passwords\\PasswordResetServiceProvider' =>
|
||||
array (
|
||||
),
|
||||
'Illuminate\\Pipeline\\PipelineServiceProvider' =>
|
||||
array (
|
||||
),
|
||||
'Illuminate\\Queue\\QueueServiceProvider' =>
|
||||
array (
|
||||
),
|
||||
'Illuminate\\Redis\\RedisServiceProvider' =>
|
||||
array (
|
||||
),
|
||||
'Illuminate\\Translation\\TranslationServiceProvider' =>
|
||||
array (
|
||||
),
|
||||
'Illuminate\\Validation\\ValidationServiceProvider' =>
|
||||
array (
|
||||
),
|
||||
'Laravel\\Tinker\\TinkerServiceProvider' =>
|
||||
array (
|
||||
),
|
||||
),
|
||||
);
|
File diff suppressed because it is too large
Load Diff
|
@ -4,13 +4,17 @@
|
|||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"dependencies": {
|
||||
"bootstrap": "^5.3.5",
|
||||
"bootstrap-icons": "^1.11.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"autoprefixer": "^10.4.20",
|
||||
"axios": "^1.7.4",
|
||||
"concurrently": "^9.0.1",
|
||||
"laravel-vite-plugin": "^1.2.0",
|
||||
"postcss": "^8.4.47",
|
||||
"tailwindcss": "^3.4.13",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"vite": "^6.0.11"
|
||||
}
|
||||
},
|
||||
|
@ -536,6 +540,16 @@
|
|||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@popperjs/core": {
|
||||
"version": "2.11.8",
|
||||
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
|
||||
"integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
|
||||
"peer": true,
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/popperjs"
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||
"version": "4.39.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.39.0.tgz",
|
||||
|
@ -926,6 +940,39 @@
|
|||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/bootstrap": {
|
||||
"version": "5.3.5",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.5.tgz",
|
||||
"integrity": "sha512-ct1CHKtiobRimyGzmsSldEtM03E8fcEX4Tb3dGXz1V8faRwM50+vfHwTzOxB3IlKO7m+9vTH3s/3C6T2EAPeTA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/twbs"
|
||||
},
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/bootstrap"
|
||||
}
|
||||
],
|
||||
"peerDependencies": {
|
||||
"@popperjs/core": "^2.11.8"
|
||||
}
|
||||
},
|
||||
"node_modules/bootstrap-icons": {
|
||||
"version": "1.11.3",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.11.3.tgz",
|
||||
"integrity": "sha512-+3lpHrCw/it2/7lBL15VR0HEumaBss0+f/Lb6ZvHISn1mlK83jjFpooTLsMWbIjJMDjDjOExMsTxnXSIT4k4ww==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/twbs"
|
||||
},
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/bootstrap"
|
||||
}
|
||||
]
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||
|
|
|
@ -11,7 +11,11 @@
|
|||
"concurrently": "^9.0.1",
|
||||
"laravel-vite-plugin": "^1.2.0",
|
||||
"postcss": "^8.4.47",
|
||||
"tailwindcss": "^3.4.13",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"vite": "^6.0.11"
|
||||
},
|
||||
"dependencies": {
|
||||
"bootstrap": "^5.3.5",
|
||||
"bootstrap-icons": "^1.11.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
@import 'bootstrap/dist/css/bootstrap.min.css';
|
||||
|
||||
|
||||
.table-operations > button {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
@ -17,3 +20,18 @@
|
|||
.alert-success { background-color: #dff0d8; border-color: #d6e9c6; color: #3c763d; }
|
||||
.alert-danger { background-color: #f2dede; border-color: #ebccd1; color: #a94442; }
|
||||
.alert-info { background-color: #cce5ff; border-color: #b8daff; color: #004085; }
|
||||
|
||||
.error-404 {
|
||||
text-align: center;
|
||||
margin-top: 10%;
|
||||
}
|
||||
.error-404 h1 {
|
||||
font-size: 150px;
|
||||
font-weight: bold;
|
||||
margin: 0;
|
||||
}
|
||||
.error-404 p:first-of-type {
|
||||
font-size: 30px;
|
||||
font-weight: bold;
|
||||
margin: 0;
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 224 KiB |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 57.834 57.955"><defs><style>.a{fill:#f4825c;stroke:#707070;}.b{fill:#e74610;}.c{stroke:none;}.d{fill:none;}</style></defs><g transform="translate(-0.498 0.199)"><g transform="translate(0 0)"><g class="a" transform="translate(1.009 0.934)"><circle class="c" cx="27.989" cy="27.989" r="27.989"/><circle class="d" cx="27.989" cy="27.989" r="27.489"/></g><g transform="translate(-26.502 -27.6)"><g transform="translate(27 27.4)"><path class="b" d="M55.917,85.355A28.978,28.978,0,1,1,84.834,56.317,29.012,29.012,0,0,1,55.917,85.355Zm0-54.31A25.272,25.272,0,1,0,81.189,56.317,25.253,25.253,0,0,0,55.917,31.045Z" transform="translate(-27 -27.4)"/><g transform="translate(18.529 18.65)"><path class="b" d="M59.638,63.344a1.827,1.827,0,0,1-1.337-.486l-8.5-8.5a1.762,1.762,0,0,1,0-2.551l8.5-8.5a1.8,1.8,0,0,1,2.551,2.551l-7.168,7.168,7.168,7.169a1.762,1.762,0,0,1,0,2.551A1.234,1.234,0,0,1,59.638,63.344Z" transform="translate(-40.745 -42.75)"/><path class="b" d="M44.133,63.323a1.827,1.827,0,0,1-1.336-.486,1.762,1.762,0,0,1,0-2.551l7.169-7.169L42.8,45.948A1.8,1.8,0,0,1,45.348,43.4l8.5,8.5a1.762,1.762,0,0,1,0,2.551l-8.5,8.5A1.814,1.814,0,0,1,44.133,63.323Z" transform="translate(-42.25 -42.729)"/></g></g></g></g></g></svg>
|
After Width: | Height: | Size: 1.2 KiB |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 58.184 58.184"><defs><style>.a{fill:#56b68b;stroke:#707070;}.b{fill:#018952;fill-rule:evenodd;}.c{stroke:none;}.d{fill:none;}</style></defs><g transform="translate(-138.502 -248.613)"><g transform="translate(138.502 248.613)"><g transform="translate(0 0)"><g class="a" transform="translate(1.009 0.934)"><circle class="c" cx="27.989" cy="27.989" r="27.989"/><circle class="d" cx="27.989" cy="27.989" r="27.489"/></g><path class="b" d="M47.664,22.747l2.3,2.3L31.8,43.209l-2.3,2.3-2.3-2.3-8.978-8.978,2.3-2.3L29.5,40.913ZM34.092,5A29.092,29.092,0,1,1,5,34.092,29.079,29.079,0,0,1,34.092,5Zm0,3.967A25.16,25.16,0,1,1,8.967,34.092,25.173,25.173,0,0,1,34.092,8.967Z" transform="translate(-5 -5)"/></g></g></g></svg>
|
After Width: | Height: | Size: 763 B |
Binary file not shown.
After Width: | Height: | Size: 8.1 KiB |
|
@ -0,0 +1,8 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container my-5">
|
||||
<h1 class="mb-4">Advanced Search Filter</h1>
|
||||
@livewire('advance-search-filter')
|
||||
</div>
|
||||
@endsection
|
|
@ -1,5 +1,8 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
@livewire($component, $props)
|
||||
<div class="container my-5">
|
||||
<h1 class="mb-4">Advance Table</h1>
|
||||
@livewire('advance-table', ['props' => ['columns' => [], 'url' => [], 'keyValue' => 'id']])
|
||||
</div>
|
||||
@endsection
|
|
@ -0,0 +1,8 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container my-5">
|
||||
<h1 class="mb-4">Cascader Form</h1>
|
||||
@livewire('cascader-form', ['url' => 'your-api-endpoint'])
|
||||
</div>
|
||||
@endsection
|
|
@ -0,0 +1,8 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container my-5">
|
||||
<h1 class="mb-4">Checkbox Form</h1>
|
||||
@livewire('checkbox-form', ['name' => 'agree', 'label' => 'I Agree', 'inline' => false, 'required' => true])
|
||||
</div>
|
||||
@endsection
|
|
@ -0,0 +1,20 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container my-5">
|
||||
<h1 class="mb-4">Custom Table</h1>
|
||||
@livewire('custom-table', [
|
||||
'url' => 'https://your-api-endpoint',
|
||||
'columns' => [
|
||||
['title' => 'Name', 'dataIndex' => 'name'],
|
||||
['title' => 'Email', 'dataIndex' => 'email'],
|
||||
],
|
||||
'actions' => [
|
||||
['type' => 'edit', 'path' => '/edit'],
|
||||
['type' => 'view', 'path' => '/view'],
|
||||
['type' => 'delete'],
|
||||
],
|
||||
'keyValue' => 'id'
|
||||
])
|
||||
</div>
|
||||
@endsection
|
|
@ -0,0 +1,14 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container my-5">
|
||||
<h1 class="mb-4">Data List</h1>
|
||||
@livewire('data-list', [
|
||||
'url' => 'your-api-endpoint',
|
||||
'avatar' => true,
|
||||
'viewPath' => '/view/:id',
|
||||
'header' => 'List Header',
|
||||
'footer' => 'List Footer'
|
||||
])
|
||||
</div>
|
||||
@endsection
|
|
@ -0,0 +1,8 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container my-5">
|
||||
<h1 class="mb-4">Date Picker Form</h1>
|
||||
@livewire('date-picker-form', ['name' => 'date', 'label' => 'Select Date', 'type' => 'date', 'required' => true, 'minDateToday' => true])
|
||||
</div>
|
||||
@endsection
|
|
@ -1,5 +1,7 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
@livewire($component)
|
||||
<div class="container my-5">
|
||||
@livewire('page403')
|
||||
</div>
|
||||
@endsection
|
|
@ -0,0 +1,7 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container my-5">
|
||||
@livewire('page404-new')
|
||||
</div>
|
||||
@endsection
|
|
@ -1,5 +1,7 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
@livewire($component)
|
||||
<div class="container my-5">
|
||||
@livewire('page404')
|
||||
</div>
|
||||
@endsection
|
|
@ -0,0 +1,7 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container my-5">
|
||||
@livewire('header-form', ['title' => 'Form Header', 'actionBtnName' => 'Save', 'cancelBtnName' => 'Cancel', 'deleteBtnName' => 'Delete', 'withConfirm' => true, 'isDropDown' => true])
|
||||
</div>
|
||||
@endsection
|
|
@ -0,0 +1,8 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container my-5">
|
||||
<h1 class="mb-4">Text Input</h1>
|
||||
@livewire('input-form', ['name' => 'username', 'label' => 'Username', 'required' => true, 'isCopyUsername' => true])
|
||||
</div>
|
||||
@endsection
|
|
@ -0,0 +1,8 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container my-5">
|
||||
<h1 class="mb-4">Input Mask Number Form</h1>
|
||||
@livewire('input-mask-number-form', ['name' => 'phone', 'label' => 'Phone Number', 'required' => true, 'mask' => '999-999-9999'])
|
||||
</div>
|
||||
@endsection
|
|
@ -0,0 +1,8 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container my-5">
|
||||
<h1 class="mb-4">Input Number Form</h1>
|
||||
@livewire('input-number-ant-d', ['name' => 'quantity', 'label' => 'Quantity', 'required' => true, 'min' => 0, 'max' => 100, 'step' => 1])
|
||||
</div>
|
||||
@endsection
|
|
@ -0,0 +1,8 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container my-5">
|
||||
<h1 class="mb-4">Password Input</h1>
|
||||
@livewire('input-password', ['name' => 'password', 'label' => 'Password', 'required' => true])
|
||||
</div>
|
||||
@endsection
|
|
@ -0,0 +1,8 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container my-5">
|
||||
<h1 class="mb-4">Text Area Input</h1>
|
||||
@livewire('input-text-area', ['name' => 'description', 'label' => 'Description', 'required' => true, 'onCountText' => true, 'charsperpage' => 100, 'hasIcon' => true])
|
||||
</div>
|
||||
@endsection
|
|
@ -4,11 +4,13 @@
|
|||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Laravel</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.css" rel="stylesheet">
|
||||
@livewireStyles
|
||||
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
@yield('content')
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
|
||||
@livewireScripts
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,16 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Login - Laravel</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.css" rel="stylesheet">
|
||||
@livewireStyles
|
||||
</head>
|
||||
<body>
|
||||
@livewire('login-layout')
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
|
||||
@livewireScripts
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,33 @@
|
|||
<form wire:submit.prevent="submit" class="container py-4">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-4">
|
||||
<label for="filterField" class="form-label">Filter by Code</label>
|
||||
<select wire:model="filterField" class="form-select" id="filterField" required>
|
||||
<option value="ff0000">Red</option>
|
||||
<option value="00ff00">Green</option>
|
||||
<option value="0000ff">Blue</option>
|
||||
</select>
|
||||
@error('filterField')
|
||||
<div class="text-danger small">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Filter by Date Range</label>
|
||||
<div class="row g-2">
|
||||
<div class="col">
|
||||
<input type="date" wire:model="filterValueStart" class="form-control" placeholder="From">
|
||||
</div>
|
||||
<div class="col">
|
||||
<input type="date" wire:model="filterValueEnd" class="form-control" placeholder="To">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mt-3">
|
||||
<div class="col text-end">
|
||||
<button type="submit" class="btn btn-primary me-2">Search</button>
|
||||
<button type="button" wire:click="resetForm" class="btn btn-secondary">Clear</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
|
@ -1,119 +1,101 @@
|
|||
<div style="margin: 0 24px; padding: 24px 0">
|
||||
<div class="container mx-auto py-6">
|
||||
@if (session()->has('success'))
|
||||
<div class="alert alert-success">{{ session('success') }}</div>
|
||||
<div class="alert alert-success mb-4">{{ session('success') }}</div>
|
||||
@endif
|
||||
@if (session()->has('error'))
|
||||
<div class="alert alert-danger">{{ session('error') }}</div>
|
||||
<div class="alert alert-danger mb-4">{{ session('error') }}</div>
|
||||
@endif
|
||||
@if (session()->has('info'))
|
||||
<div class="alert alert-info">{{ session('info') }}</div>
|
||||
<div class="alert alert-info mb-4">{{ session('info') }}</div>
|
||||
@endif
|
||||
|
||||
<div wire:loading wire:target="fetchData" class="loading-overlay">
|
||||
<div wire:loading wire:target="fetchData" class="position-fixed top-0 start-0 w-100 h-100 bg-dark bg-opacity-50 text-white d-flex align-items-center justify-content-center" style="z-index: 1050;">
|
||||
Loading...
|
||||
</div>
|
||||
|
||||
<div class="row-type-flex justify-space-between align-bottom" style="padding-bottom: 25px">
|
||||
<div>
|
||||
<input type="text" wire:model.debounce.1000ms="searchFilter" style="width: 300px"
|
||||
placeholder="Search" class="ant-input">
|
||||
<span class="ant-input-prefix" style="color: rgba(0,0,0,.25)">
|
||||
<i class="anticon anticon-search"></i>
|
||||
</span>
|
||||
</div>
|
||||
<div class="table-operations">
|
||||
<button wire:click="clearAll" class="ant-btn">Clear filters</button>
|
||||
<div class="row justify-content-between align-items-end pb-4">
|
||||
<div class="col-auto">
|
||||
@if ($url['csv'])
|
||||
<div>Export Dropdown Placeholder</div>
|
||||
<input type="text" placeholder="Date Range Picker Placeholder" class="form-control" style="width: 300px;">
|
||||
@else
|
||||
<div class="input-group" style="width: 300px;">
|
||||
<span class="input-group-text"><i class="bi bi-search"></i></span>
|
||||
<input type="text" wire:model.debounce.1000ms="searchFilter" class="form-control" placeholder="Search">
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<button wire:click="clearAll" class="btn btn-secondary me-2">Clear filters</button>
|
||||
@if ($url['csv'])
|
||||
<span>Export Dropdown Placeholder</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="ant-table ant-table-middle" wire:loading.class="loading">
|
||||
<thead>
|
||||
<tr>
|
||||
@foreach($columns as $column)
|
||||
<th wire:click="setSort('{{ $column['dataIndex'] }}')"
|
||||
class="{{ $sortBy === $column['dataIndex'] ? 'ant-table-column-sort' : '' }}
|
||||
{{ $sortOrder === 'asc' ? 'ascend' : 'descend' }}">
|
||||
{{ $column['title'] }}
|
||||
<span class="ant-table-column-sorter">
|
||||
<span class="ant-table-column-sorter-inner">
|
||||
<i class="anticon anticon-caret-up"></i>
|
||||
<i class="anticon anticon-caret-down"></i>
|
||||
</span>
|
||||
</span>
|
||||
</th>
|
||||
@endforeach
|
||||
@if($apiDelete)
|
||||
<th>Action</th>
|
||||
@endif
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($data as $record)
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered table-hover">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
@foreach($columns as $column)
|
||||
<td>{{ $record[$column['dataIndex']] ?? '' }}</td>
|
||||
<th wire:click="setSort('{{ $column['dataIndex'] }}')" class="cursor-pointer {{ $sortBy === $column['dataIndex'] ? 'bg-primary-subtle' : '' }}">
|
||||
{{ $column['title'] }}
|
||||
<span>
|
||||
<i class="bi bi-caret-up-fill {{ $sortOrder === 'asc' ? 'text-primary' : 'text-muted' }}"></i>
|
||||
<i class="bi bi-caret-down-fill {{ $sortOrder === 'desc' ? 'text-primary' : 'text-muted' }}"></i>
|
||||
</span>
|
||||
</th>
|
||||
@endforeach
|
||||
@if($apiDelete)
|
||||
<td>
|
||||
@foreach($column['buttons'] ?? [] as $action)
|
||||
@if($action['key'] === 'delete' && $record['editable'] !== false)
|
||||
<button wire:click="delete({{ $record[$keyValue] }})" class="ant-btn ant-btn-danger">
|
||||
Delete
|
||||
</button>
|
||||
@elseif(in_array($action['key'], ['edit', 'view', 'location']))
|
||||
<button class="ant-btn ant-btn-primary" wire:click="redirect('{{ $action['key'] }}', {{ $record[$keyValue] }})">
|
||||
{{ ucfirst($action['key']) }}
|
||||
</button>
|
||||
@endif
|
||||
@endforeach
|
||||
</td>
|
||||
<th>Action</th>
|
||||
@endif
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($data as $record)
|
||||
<tr>
|
||||
@foreach($columns as $column)
|
||||
<td>{{ $record[$column['dataIndex']] ?? '' }}</td>
|
||||
@endforeach
|
||||
@if($apiDelete)
|
||||
<td>
|
||||
@foreach($column['buttons'] ?? [] as $action)
|
||||
@if($action['key'] === 'delete' && $record['editable'] !== false)
|
||||
<button wire:click="delete({{ $record[$keyValue] }})" class="btn btn-danger btn-sm me-1">Delete</button>
|
||||
@elseif(in_array($action['key'], ['edit', 'view']))
|
||||
<button wire:click="redirect('{{ $action['key'] }}', {{ $record[$keyValue] }})" class="btn btn-primary btn-sm me-1">{{ ucfirst($action['key']) }}</button>
|
||||
@endif
|
||||
@endforeach
|
||||
</td>
|
||||
@endif
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@if($total > 0)
|
||||
<div class="row-type-flex justify-space-between" style="margin-top: 20px">
|
||||
<div>
|
||||
<div class="row justify-content-between align-items-center mt-4">
|
||||
<div class="col-auto">
|
||||
@if($apiDelete)
|
||||
<button wire:click="handleBatchDelete" class="ant-btn ant-btn-danger" disabled="{{ count($selectedRowKeys) === 0 }}">
|
||||
<button wire:click="handleBatchDelete" class="btn btn-danger" {{ count($selectedRowKeys) === 0 ? 'disabled' : '' }}>
|
||||
Delete
|
||||
</button>
|
||||
<span style="margin-left: 8px">
|
||||
<span class="ms-2">
|
||||
{{ count($selectedRowKeys) > 0 ? "Selected " . count($selectedRowKeys) . " item(s)" : '' }}
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
<div>
|
||||
<ul class="ant-pagination">
|
||||
@for($i = 1; $i <= ceil($total / $perPage); $i++)
|
||||
<li class="{{ $currentPage === $i ? 'ant-pagination-item-active' : 'ant-pagination-item' }}" wire:click="updatePage({{ $i }})">
|
||||
{{ $i }}
|
||||
</li>
|
||||
@endfor
|
||||
</ul>
|
||||
<div class="col-auto">
|
||||
<nav aria-label="Page navigation">
|
||||
<ul class="pagination">
|
||||
@for($i = 1; $i <= ceil($total / $perPage); $i++)
|
||||
<li class="page-item {{ $currentPage === $i ? 'active' : '' }}">
|
||||
<button wire:click="updatePage({{ $i }})" class="page-link">{{ $i }}</button>
|
||||
</li>
|
||||
@endfor
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.row-type-flex { display: flex; justify-content: space-between; align-items: bottom; }
|
||||
.justify-space-between { justify-content: space-between; }
|
||||
.align-bottom { align-items: bottom; }
|
||||
.table-operations > button { margin-right: 8px; }
|
||||
.ant-table { width: 100%; border-collapse: collapse; }
|
||||
.ant-table th, .ant-table td { border: 1px solid #f0f0f0; padding: 8px; text-align: left; }
|
||||
.ant-table th { background: #fafafa; cursor: pointer; }
|
||||
.ant-table-column-sort { background: #e6f7ff; }
|
||||
.ant-btn { padding: 0 15px; height: 32px; border: 1px solid #d9d9d9; border-radius: 4px; cursor: pointer; }
|
||||
.ant-btn-primary { background: #1890ff; color: white; border-color: #1890ff; }
|
||||
.ant-btn-danger { background: #ff4d4f; color: white; border-color: #ff4d4f; }
|
||||
.loading-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0, 0, 0, 0.5); color: white; text-align: center; padding-top: 20%; z-index: 1000; }
|
||||
.ant-input { border: 1px solid #d9d9d9; border-radius: 4px; padding: 4px 11px; }
|
||||
.ant-input-prefix { position: absolute; left: 8px; top: 50%; transform: translateY(-50%); }
|
||||
</style>
|
|
@ -0,0 +1,22 @@
|
|||
<div class="mb-3">
|
||||
@if (session()->has('error'))
|
||||
<div class="alert alert-danger mb-2">{{ session('error') }}</div>
|
||||
@endif
|
||||
|
||||
<label for="cascader" class="form-label">Select Location</label>
|
||||
<select wire:model="selected" class="form-select" id="cascader" multiple>
|
||||
@foreach($options as $option)
|
||||
<optgroup label="{{ $option['label'] }}">
|
||||
@foreach($option['children'] as $child)
|
||||
<option value="{{ $child['value'] }}">{{ $child['label'] }}</option>
|
||||
@foreach($child['children'] ?? [] as $grandchild)
|
||||
<option value="{{ $grandchild['value'] }}">{{ $grandchild['label'] }}</option>
|
||||
@endforeach
|
||||
@endforeach
|
||||
</optgroup>
|
||||
@endforeach
|
||||
</select>
|
||||
@error('selected')
|
||||
<div class="text-danger small">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
|
@ -0,0 +1,7 @@
|
|||
<div class="{{ $inline ? 'form-check form-check-inline' : 'form-check mb-3' }}" style="{{ !$inline ? 'margin-left: 20.9%;' : '' }}">
|
||||
<input type="checkbox" wire:model="value" class="form-check-input" id="{{ $name }}" {{ $required ? 'required' : '' }}>
|
||||
<label for="{{ $name }}" class="form-check-label">{{ $label }}</label>
|
||||
@error('value')
|
||||
<div class="text-danger small">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
|
@ -0,0 +1,75 @@
|
|||
<div>
|
||||
<!-- Search Input -->
|
||||
<div class="mb-3">
|
||||
<input
|
||||
type="text"
|
||||
wire:model.debounce.500ms="searchValue"
|
||||
class="form-control"
|
||||
placeholder="Search..."
|
||||
>
|
||||
</div>
|
||||
|
||||
<!-- Table -->
|
||||
<table class="table table-bordered table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
@foreach($columns as $column)
|
||||
<th wire:click="sort('{{ $column['dataIndex'] }}')" style="cursor: pointer;">
|
||||
{{ $column['title'] }}
|
||||
@if($sortedInfo && $sortedInfo['field'] === $column['dataIndex'])
|
||||
<i class="bi bi-caret-{{ $sortedInfo['order'] === 'asc' ? 'up' : 'down' }}-fill"></i>
|
||||
@endif
|
||||
</th>
|
||||
@endforeach
|
||||
@if($actions)
|
||||
<th>Action</th>
|
||||
@endif
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse($data as $item)
|
||||
<tr>
|
||||
@foreach($columns as $column)
|
||||
<td>{{ $item[$column['dataIndex']] }}</td>
|
||||
@endforeach
|
||||
@if($actions)
|
||||
<td>
|
||||
@foreach($actions as $action)
|
||||
@if($action['type'] === 'edit')
|
||||
<a href="{{ $action['path'] . '/' . $item[$keyValue] }}" class="btn btn-sm btn-primary me-1">Edit</a>
|
||||
@elseif($action['type'] === 'view')
|
||||
<a href="{{ $action['path'] . '/' . $item[$keyValue] }}" class="btn btn-sm btn-info me-1">View</a>
|
||||
@elseif($action['type'] === 'delete')
|
||||
<button class="btn btn-sm btn-danger" wire:click="$dispatch('delete', {{ $item[$keyValue] }})">Delete</button>
|
||||
@endif
|
||||
@endforeach
|
||||
</td>
|
||||
@endif
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="{{ count($columns) + ($actions ? 1 : 0) }}" class="text-center">No data available</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!-- Pagination and Clear Filters -->
|
||||
<div class="d-flex justify-content-between align-items-center mt-3">
|
||||
<button wire:click="handleClearAll" class="btn btn-secondary">Clear Filters</button>
|
||||
<nav>
|
||||
<ul class="pagination">
|
||||
@for($i = 1; $i <= ceil($totalData / $pageSize); $i++)
|
||||
<li class="page-item {{ $currentPage === $i ? 'active' : '' }}">
|
||||
<button wire:click="handlePagination({{ $i }})" class="page-link">{{ $i }}</button>
|
||||
</li>
|
||||
@endfor
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<!-- Loading Indicator -->
|
||||
@if($loading)
|
||||
<div class="text-center my-3">Loading...</div>
|
||||
@endif
|
||||
</div>
|
|
@ -0,0 +1,27 @@
|
|||
<div>
|
||||
@if(session()->has('error'))
|
||||
<div class="alert alert-danger">{{ session('error') }}</div>
|
||||
@endif
|
||||
|
||||
@if($header)
|
||||
<div class="mb-3">{{ $header }}</div>
|
||||
@endif
|
||||
|
||||
<ul class="list-group">
|
||||
@foreach($data as $item)
|
||||
<li class="list-group-item d-flex align-items-center">
|
||||
@if($avatar)
|
||||
<img src="{{ $item['avatar'] }}" alt="Avatar" class="rounded-circle me-3" style="width: 40px; height: 40px;">
|
||||
@endif
|
||||
<div>
|
||||
<a href="{{ str_replace(':id', $item['id'], $viewPath) }}" class="text-primary">{{ $item['first_name'] }}</a>
|
||||
<p class="mb-0 text-muted">{{ strtolower($item['first_name']) . '_' . strtolower($item['last_name']) . '@gmail.com' }}</p>
|
||||
</div>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
|
||||
@if($footer)
|
||||
<div class="mt-3">{{ $footer }}</div>
|
||||
@endif
|
||||
</div>
|
|
@ -0,0 +1,18 @@
|
|||
<div class="mb-3">
|
||||
<label for="{{ $name }}" class="form-label">{{ $label }}</label>
|
||||
@if($type === 'range')
|
||||
<div class="row g-2">
|
||||
<div class="col">
|
||||
<input type="date" wire:model="value.0" class="form-control" id="{{ $name }}_start" {{ $required ? 'required' : '' }} min="{{ $minDate }}">
|
||||
</div>
|
||||
<div class="col">
|
||||
<input type="date" wire:model="value.1" class="form-control" id="{{ $name }}_end" {{ $required ? 'required' : '' }} min="{{ $minDate }}">
|
||||
</div>
|
||||
</div>
|
||||
@else
|
||||
<input type="{{ $type === 'date-time' ? 'datetime-local' : 'date' }}" wire:model="value" class="form-control" id="{{ $name }}" {{ $required ? 'required' : '' }} min="{{ $minDate }}">
|
||||
@endif
|
||||
@error('value')
|
||||
<div class="text-danger small">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
|
@ -0,0 +1,19 @@
|
|||
<div>
|
||||
<button
|
||||
wire:click="handleExportCSV"
|
||||
class="btn"
|
||||
style="background: rgb(231, 70, 16); border-color: rgb(231, 70, 16); color: #fff;"
|
||||
wire:loading.attr="disabled"
|
||||
>
|
||||
@if($loading)
|
||||
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
|
||||
Exporting...
|
||||
@else
|
||||
Export CSV
|
||||
@endif
|
||||
</button>
|
||||
|
||||
@if(session()->has('error'))
|
||||
<div class="alert alert-danger mt-2">{{ session('error') }}</div>
|
||||
@endif
|
||||
</div>
|
|
@ -0,0 +1,95 @@
|
|||
<div class="d-flex justify-content-between align-items-center border-bottom bg-white position-fixed w-100 py-2 px-4" style="z-index: 99; top: {{ $isInsideForm ? '-154px' : '-73px' }}; left: -17px;">
|
||||
<h1 class="fs-4 mb-0">{{ $title }}</h1>
|
||||
<div class="d-flex position-fixed" style="right: 24px;">
|
||||
@if($actionBtnName)
|
||||
@if($withConfirm)
|
||||
<button type="button" class="btn btn-primary me-2" style="width: 135px;" wire:click="action" {{ $loading || $disabled ? 'disabled' : '' }} data-bs-toggle="modal" data-bs-target="#confirmModal">
|
||||
{{ $actionBtnName }}
|
||||
</button>
|
||||
<div class="modal fade" id="confirmModal" tabindex="-1" aria-labelledby="confirmModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="confirmModalLabel">Confirmation</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
Are you sure?
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">No</button>
|
||||
<button type="button" class="btn btn-primary" wire:click="action" data-bs-dismiss="modal">Yes</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@else
|
||||
@if(!$isDropDown)
|
||||
<button type="button" class="btn btn-primary me-2" style="width: 135px;" wire:click="action" {{ $loading || $disabled ? 'disabled' : '' }}>
|
||||
{{ $actionBtnName }}
|
||||
</button>
|
||||
@endif
|
||||
@endif
|
||||
@endif
|
||||
|
||||
@if($cancelBtnName)
|
||||
<button type="button" class="btn btn-outline-secondary me-2" style="width: 135px;" wire:click="cancel" {{ $loading ? 'disabled' : '' }} {{ $withCancelConfirm ? 'data-bs-toggle=modal data-bs-target=#cancelModal' : '' }}>
|
||||
{{ $cancelBtnName }}
|
||||
</button>
|
||||
@if($withCancelConfirm)
|
||||
<div class="modal fade" id="cancelModal" tabindex="-1" aria-labelledby="cancelModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="cancelModalLabel">Cancel Confirmation</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
Are you sure you want to cancel?
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">No</button>
|
||||
<button type="button" class="btn btn-primary" wire:click="cancel" data-bs-dismiss="modal">Yes</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
@endif
|
||||
|
||||
@if($deleteBtnName)
|
||||
<button type="button" class="btn btn-outline-danger me-2" style="width: 135px;" wire:click="deleteAction" {{ $loading || $disabled ? 'disabled' : '' }} data-bs-toggle="modal" data-bs-target="#deleteModal">
|
||||
{{ $deleteBtnName }}
|
||||
</button>
|
||||
<div class="modal fade" id="deleteModal" tabindex="-1" aria-labelledby="deleteModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="deleteModalLabel">Delete Confirmation</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
Are you sure you want to delete this record?
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">No</button>
|
||||
<button type="button" class="btn btn-danger" wire:click="deleteAction" data-bs-dismiss="modal">Yes</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if($isDropDown)
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-primary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false" {{ $disabled ? 'disabled' : '' }}>
|
||||
Add
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><button class="dropdown-item" wire:click="actionPrivacy">Terms & Condition</button></li>
|
||||
<li><button class="dropdown-item" wire:click="actionTerms">Privacy Policy</button></li>
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,30 @@
|
|||
<div class="mb-3">
|
||||
<label for="{{ $name }}" class="form-label">{{ $label }}</label>
|
||||
@if(!$withActionBtn)
|
||||
<div class="input-group">
|
||||
<input type="text" wire:model="value" class="form-control" id="{{ $name }}" {{ $required ? 'required' : '' }}>
|
||||
@if($isCopyUsername)
|
||||
<button class="btn btn-primary" type="button" wire:click="$dispatch('copy', '{{ $value }}')" {{ $value ? '' : 'disabled' }} onclick="navigator.clipboard.writeText('{{ $value }}'); alert('Copied to clipboard!');">
|
||||
Copy
|
||||
</button>
|
||||
@endif
|
||||
</div>
|
||||
@else
|
||||
<div class="row g-2">
|
||||
<div class="col-md-6">
|
||||
<input type="text" wire:model="value" class="form-control" id="{{ $name }}" {{ $required ? 'required' : '' }}>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<button class="btn btn-primary me-2" type="button" wire:click="$dispatch('action')" {{ $loading ? 'disabled' : '' }}>
|
||||
Action
|
||||
</button>
|
||||
<button class="btn btn-primary" type="button" wire:click="$dispatch('copy', '{{ $value }}')" {{ $value ? '' : 'disabled' }} onclick="navigator.clipboard.writeText('{{ $value }}'); alert('Copied to clipboard!');">
|
||||
Copy
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
@error('value')
|
||||
<div class="text-danger small">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
|
@ -0,0 +1,33 @@
|
|||
<div class="mb-3">
|
||||
<label for="{{ $name }}" class="form-label">{{ $label }}</label>
|
||||
<input type="text" wire:model="value" class="form-control" id="{{ $name }}" {{ $required ? 'required' : '' }} data-mask="{{ $mask }}">
|
||||
@error('value')
|
||||
<div class="text-danger small">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener('livewire:load', function () {
|
||||
const inputs = document.querySelectorAll('[data-mask]');
|
||||
inputs.forEach(input => {
|
||||
const mask = input.getAttribute('data-mask');
|
||||
input.addEventListener('input', function (e) {
|
||||
let value = e.target.value.replace(/\D/g, '');
|
||||
let formatted = '';
|
||||
let maskIndex = 0;
|
||||
for (let i = 0; i < value.length && maskIndex < mask.length; i++) {
|
||||
if (mask[maskIndex] === '9') {
|
||||
formatted += value[i];
|
||||
maskIndex++;
|
||||
} else {
|
||||
formatted += mask[maskIndex];
|
||||
maskIndex++;
|
||||
i--; // Stay on the same digit
|
||||
}
|
||||
}
|
||||
e.target.value = formatted;
|
||||
@this.set('value', formatted);
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,7 @@
|
|||
<div class="mb-3">
|
||||
<label for="{{ $name }}" class="form-label">{{ $label }}</label>
|
||||
<input type="number" wire:model="value" class="form-control" id="{{ $name }}" {{ $required ? 'required' : '' }} min="{{ $min }}" max="{{ $max }}" step="{{ $step }}">
|
||||
@error('value')
|
||||
<div class="text-danger small">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
|
@ -0,0 +1,7 @@
|
|||
<div class="mb-3">
|
||||
<label for="{{ $name }}" class="form-label">{{ $label }}</label>
|
||||
<input type="password" wire:model="value" class="form-control" id="{{ $name }}" {{ $required ? 'required' : '' }}>
|
||||
@error('value')
|
||||
<div class="text-danger small">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
|
@ -0,0 +1,30 @@
|
|||
<div class="mb-3">
|
||||
<label for="{{ $name }}" class="form-label">
|
||||
{{ $label }}
|
||||
@if($hasIcon)
|
||||
<span class="ms-1" data-bs-toggle="tooltip" data-bs-placement="top" title="This content will be used in the 'Enter ID Number' page as part of the Apply for a Card process of the Unioil Mobile App.">
|
||||
<i class="bi bi-question-circle"></i>
|
||||
</span>
|
||||
@endif
|
||||
</label>
|
||||
<textarea wire:model="value" class="form-control" id="{{ $name }}" rows="3" {{ $required ? 'required' : '' }}></textarea>
|
||||
@if($onCountText)
|
||||
<div class="position-relative">
|
||||
<small class="position-absolute end-0 top-0 mt-1 me-2" style="color: {{ strlen($value) > $charsperpage ? 'red' : '#6c757d' }};">
|
||||
{{ strlen($value) }}/{{ $charsperpage }}
|
||||
</small>
|
||||
</div>
|
||||
@endif
|
||||
@error('value')
|
||||
<div class="text-danger small">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
|
||||
tooltipTriggerList.map(function (tooltipTriggerEl) {
|
||||
return new bootstrap.Tooltip(tooltipTriggerEl);
|
||||
});
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,8 @@
|
|||
<div class="d-flex justify-content-center align-items-center py-4">
|
||||
<div class="text-center">
|
||||
<div class="spinner-border text-primary me-2" role="status">
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
</div>
|
||||
Loading Data Please wait...
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,19 @@
|
|||
<div class="min-vh-100 d-flex">
|
||||
<!-- Sider -->
|
||||
<div class="col-md-6 d-none d-md-block" style="background: url('/img/bg_cms.png') center / cover no-repeat;"></div>
|
||||
<!-- Content and Footer -->
|
||||
<div class="col-md-6 d-flex flex-column justify-content-between">
|
||||
<div class="p-4 flex-grow-1">
|
||||
@if($children)
|
||||
{{ $children }}
|
||||
@else
|
||||
@yield('content')
|
||||
@endif
|
||||
</div>
|
||||
<footer class="text-center py-3" style="font-size: 12px;">
|
||||
<div class="mx-auto px-0 py-4" style="width: 325px; border-top: 1px solid #e0e0e0; text-align: left; color: #8E8E93;">
|
||||
By logging in you agree to Unioil's Terms of Service, <br>Privacy Policy and Content Policies.
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,33 @@
|
|||
<div>
|
||||
@if($dirty)
|
||||
<button wire:click="showModal" class="btn btn-secondary" {{ $loading ? 'disabled' : '' }}>
|
||||
{{ $name }}
|
||||
</button>
|
||||
|
||||
@if($visible)
|
||||
<div class="modal fade show d-block" id="{{ $id }}" tabindex="-1" aria-labelledby="{{ $id }}Label" style="background-color: rgba(0,0,0,0.4);">
|
||||
<div class="modal-dialog modal-dialog-centered" style="max-width: 300px;">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="{{ $id }}Label">{{ $title }}</h5>
|
||||
<button type="button" wire:click="handleCancel" class="btn-close" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>{{ $message }}</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button wire:click="handleCancel" class="btn btn-primary">No</button>
|
||||
<a href="{{ $path }}" class="btn btn-secondary">Yes</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
@else
|
||||
<a href="{{ $path }}" class="{{ $loading ? 'pointer-events-none' : '' }}">
|
||||
<button class="btn btn-secondary" {{ $loading ? 'disabled' : '' }}>
|
||||
{{ $name }}
|
||||
</button>
|
||||
</a>
|
||||
@endif
|
||||
</div>
|
|
@ -0,0 +1,14 @@
|
|||
<div class="mb-3">
|
||||
@if (session()->has('error'))
|
||||
<div class="alert alert-danger mb-2">{{ session('error') }}</div>
|
||||
@endif
|
||||
<label for="{{ $name }}" class="form-label">{{ $label }}</label>
|
||||
<select wire:model="value" class="form-select" id="{{ $name }}" multiple {{ $required ? 'required' : '' }}>
|
||||
@foreach($optionsList as $item)
|
||||
<option value="{{ $item['id'] }}">{{ $item['name'] ?? $item['first_name'] }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@error('value')
|
||||
<div class="text-danger small">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
|
@ -0,0 +1,11 @@
|
|||
<div class="mb-3">
|
||||
<label for="{{ $name }}" class="form-label">{{ $label }}</label>
|
||||
<select wire:model="value" class="form-select" id="{{ $name }}" multiple {{ $required ? 'required' : '' }}>
|
||||
@foreach($optionsList as $item)
|
||||
<option value="{{ $item['id'] }}">{{ $item['name'] }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@error('value')
|
||||
<div class="text-danger small">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
|
@ -0,0 +1,101 @@
|
|||
<div class="container mx-auto py-6">
|
||||
@if (session()->has('success'))
|
||||
<div class="alert alert-success mb-4">{{ session('success') }}</div>
|
||||
@endif
|
||||
@if (session()->has('error'))
|
||||
<div class="alert alert-danger mb-4">{{ session('error') }}</div>
|
||||
@endif
|
||||
@if (session()->has('info'))
|
||||
<div class="alert alert-info mb-4">{{ session('info') }}</div>
|
||||
@endif
|
||||
|
||||
<div wire:loading wire:target="fetchData" class="position-fixed top-0 start-0 w-100 h-100 bg-dark bg-opacity-50 text-white d-flex align-items-center justify-content-center" style="z-index: 1050;">
|
||||
Loading...
|
||||
</div>
|
||||
|
||||
<div class="row justify-content-between align-items-end pb-4">
|
||||
<div class="col-auto">
|
||||
@if ($url['csv'])
|
||||
<input type="text" placeholder="Date Range Picker Placeholder" class="form-control" style="width: 300px;">
|
||||
@else
|
||||
<div class="input-group" style="width: 300px;">
|
||||
<span class="input-group-text"><i class="bi bi-search"></i></span>
|
||||
<input type="text" wire:model.debounce.1000ms="searchFilter" class="form-control" placeholder="Search">
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<button wire:click="clearAll" class="btn btn-secondary me-2">Clear filters</button>
|
||||
@if ($url['csv'])
|
||||
<span>Export Dropdown Placeholder</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered table-hover">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
@foreach($columns as $column)
|
||||
<th wire:click="setSort('{{ $column['dataIndex'] }}')" class="cursor-pointer {{ $sortBy === $column['dataIndex'] ? 'bg-primary-subtle' : '' }}">
|
||||
{{ $column['title'] }}
|
||||
<span>
|
||||
<i class="bi bi-caret-up-fill {{ $sortOrder === 'asc' ? 'text-primary' : 'text-muted' }}"></i>
|
||||
<i class="bi bi-caret-down-fill {{ $sortOrder === 'desc' ? 'text-primary' : 'text-muted' }}"></i>
|
||||
</span>
|
||||
</th>
|
||||
@endforeach
|
||||
@if($apiDelete)
|
||||
<th>Action</th>
|
||||
@endif
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($data as $record)
|
||||
<tr>
|
||||
@foreach($columns as $column)
|
||||
<td>{{ $record[$column['dataIndex']] ?? '' }}</td>
|
||||
@endforeach
|
||||
@if($apiDelete)
|
||||
<td>
|
||||
@foreach($column['buttons'] ?? [] as $action)
|
||||
@if($action['key'] === 'delete' && $record['editable'] !== false)
|
||||
<button wire:click="delete({{ $record[$keyValue] }})" class="btn btn-danger btn-sm me-1">Delete</button>
|
||||
@elseif(in_array($action['key'], ['edit', 'view', 'location']))
|
||||
<button wire:click="redirect('{{ $action['key'] }}', {{ $record[$keyValue] }})" class="btn btn-primary btn-sm me-1">{{ ucfirst($action['key']) }}</button>
|
||||
@endif
|
||||
@endforeach
|
||||
</td>
|
||||
@endif
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@if($total > 0)
|
||||
<div class="row justify-content-between align-items-center mt-4">
|
||||
<div class="col-auto">
|
||||
@if($apiDelete)
|
||||
<button wire:click="handleBatchDelete" class="btn btn-danger" {{ count($selectedRowKeys) === 0 ? 'disabled' : '' }}>
|
||||
Delete
|
||||
</button>
|
||||
<span class="ms-2">
|
||||
{{ count($selectedRowKeys) > 0 ? "Selected " . count($selectedRowKeys) . " item(s)" : '' }}
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<nav aria-label="Page navigation">
|
||||
<ul class="pagination">
|
||||
@for($i = 1; $i <= ceil($total / $perPage); $i++)
|
||||
<li class="page-item {{ $currentPage === $i ? 'active' : '' }}">
|
||||
<button wire:click="updatePage({{ $i }})" class="page-link">{{ $i }}</button>
|
||||
</li>
|
||||
@endfor
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
|
@ -1,6 +1,6 @@
|
|||
<div align="center" style="margin-top: 10%">
|
||||
<h1 style="font-size: 150px; font-weight: bold; margin: 0">403</h1>
|
||||
<p style="font-size: 30px; font-weight: bold; margin: 0">Forbidden</p>
|
||||
<p>Access to this resource on the server is denied!</p>
|
||||
<a href="{{ route('locations') }}">Go Back</a>
|
||||
<div class="container text-center py-5" style="margin-top: 10%;">
|
||||
<h1 class="display-1 fw-bold mb-0">403</h1>
|
||||
<p class="fs-2 fw-bold mb-0">Forbidden</p>
|
||||
<p class="mb-3">Access to this resource on the server is denied!</p>
|
||||
<a href="{{ route('locations') }}" class="btn btn-primary">Go Back</a>
|
||||
</div>
|
|
@ -0,0 +1,5 @@
|
|||
<div class="container text-center py-5" style="margin-top: 10%;">
|
||||
<h1 class="display-1 fw-bold mb-0">404</h1>
|
||||
<p class="fs-2 fw-bold mb-0">Page not found</p>
|
||||
<p class="mb-3">Sorry, but the page you are looking for doesn't exist</p>
|
||||
</div>
|
|
@ -1,5 +1,7 @@
|
|||
<div align="center">
|
||||
<h1 style="font-size: 150px; font-weight: bold; margin: 0">404</h1>
|
||||
<p style="font-size: 30px; font-weight: bold; margin: 0">Page not found</p>
|
||||
<p>Sorry, but the page you are looking for doesn't exist</p>
|
||||
<div class="container text-center py-5">
|
||||
<h1 class="display-1 fw-bold mb-0">404</h1>
|
||||
<p class="fs-2 fw-bold mb-0">Page not found</p>
|
||||
<p class="mb-3">Sorry, but the page you are looking for doesn't exist</p>
|
||||
|
||||
|
||||
</div>
|
|
@ -0,0 +1,14 @@
|
|||
<div class="mb-3">
|
||||
<label class="form-label">{{ $label }}</label>
|
||||
<div class="d-flex flex-column">
|
||||
@foreach($optionsList as $option)
|
||||
<div class="form-check {{ $isRadioButton ? 'form-check-inline' : '' }}">
|
||||
<input type="radio" wire:model="value" value="{{ $option['value'] }}" class="form-check-input" id="{{ $name }}_{{ $option['value'] }}" {{ $required ? 'required' : '' }} {{ $option['isDisabled'] ?? false ? 'disabled' : '' }}>
|
||||
<label for="{{ $name }}_{{ $option['value'] }}" class="form-check-label">{{ $option['label'] }}</label>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
@error('value')
|
||||
<div class="text-danger small">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
|
@ -0,0 +1,15 @@
|
|||
<div class="mb-3">
|
||||
@if (session()->has('error'))
|
||||
<div class="alert alert-danger mb-2">{{ session('error') }}</div>
|
||||
@endif
|
||||
<label for="{{ $name }}" class="form-label">{{ $label }}</label>
|
||||
<select wire:model="value" class="form-select" id="{{ $name }}" {{ $required ? 'required' : '' }}>
|
||||
<option value="">Select an option</option>
|
||||
@foreach($optionsList as $item)
|
||||
<option value="{{ $item['value'] }}">{{ $item['label'] }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@error('value')
|
||||
<div class="text-danger small">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
|
@ -0,0 +1,15 @@
|
|||
<div class="mb-3">
|
||||
<label for="{{ $name }}" class="form-label">{{ $label }}</label>
|
||||
<input type="file" wire:model="image" class="form-control" id="{{ $name }}" accept="image/jpeg,image/png,image/gif" {{ $required ? 'required' : '' }}>
|
||||
@if($image)
|
||||
<img src="{{ $image->temporaryUrl() }}" alt="Preview" class="mt-2" style="width: {{ $imgStyle['width'] }}; height: {{ $imgStyle['height'] }};">
|
||||
@else
|
||||
<div class="border rounded p-3 text-center mt-2">
|
||||
<i class="bi bi-upload"></i>
|
||||
<p>Click or drag file to upload</p>
|
||||
</div>
|
||||
@endif
|
||||
@error('image')
|
||||
<div class="text-danger small">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
|
@ -1,119 +1,101 @@
|
|||
<div style="margin: 0 24px; padding: 24px 0">
|
||||
<div class="container mx-auto py-6">
|
||||
@if (session()->has('success'))
|
||||
<div class="alert alert-success">{{ session('success') }}</div>
|
||||
<div class="alert alert-success mb-4">{{ session('success') }}</div>
|
||||
@endif
|
||||
@if (session()->has('error'))
|
||||
<div class="alert alert-danger">{{ session('error') }}</div>
|
||||
<div class="alert alert-danger mb-4">{{ session('error') }}</div>
|
||||
@endif
|
||||
@if (session()->has('info'))
|
||||
<div class="alert alert-info">{{ session('info') }}</div>
|
||||
<div class="alert alert-info mb-4">{{ session('info') }}</div>
|
||||
@endif
|
||||
|
||||
<div wire:loading wire:target="fetchData" class="loading-overlay">
|
||||
<div wire:loading wire:target="fetchData" class="position-fixed top-0 start-0 w-100 h-100 bg-dark bg-opacity-50 text-white d-flex align-items-center justify-content-center" style="z-index: 1050;">
|
||||
Loading...
|
||||
</div>
|
||||
|
||||
<div class="row-type-flex justify-space-between align-bottom" style="padding-bottom: 25px">
|
||||
<div>
|
||||
<input type="text" wire:model.debounce.1000ms="searchFilter" style="width: 300px"
|
||||
placeholder="Search" class="ant-input">
|
||||
<span class="ant-input-prefix" style="color: rgba(0,0,0,.25)">
|
||||
<i class="anticon anticon-search"></i>
|
||||
</span>
|
||||
</div>
|
||||
<div class="table-operations">
|
||||
<button wire:click="clearAll" class="ant-btn">Clear filters</button>
|
||||
<div class="row justify-content-between align-items-end pb-4">
|
||||
<div class="col-auto">
|
||||
@if ($url['csv'])
|
||||
<div>Export Dropdown Placeholder</div>
|
||||
<input type="text" placeholder="Date Range Picker Placeholder" class="form-control" style="width: 300px;">
|
||||
@else
|
||||
<div class="input-group" style="width: 300px;">
|
||||
<span class="input-group-text"><i class="bi bi-search"></i></span>
|
||||
<input type="text" wire:model.debounce.1000ms="searchFilter" class="form-control" placeholder="Search">
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<button wire:click="clearAll" class="btn btn-secondary me-2">Clear filters</button>
|
||||
@if ($url['csv'])
|
||||
<span>Export Dropdown Placeholder</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="ant-table ant-table-middle" wire:loading.class="loading">
|
||||
<thead>
|
||||
<tr>
|
||||
@foreach($columns as $column)
|
||||
<th wire:click="setSort('{{ $column['dataIndex'] }}')"
|
||||
class="{{ $sortBy === $column['dataIndex'] ? 'ant-table-column-sort' : '' }}
|
||||
{{ $sortOrder === 'asc' ? 'ascend' : 'descend' }}">
|
||||
{{ $column['title'] }}
|
||||
<span class="ant-table-column-sorter">
|
||||
<span class="ant-table-column-sorter-inner">
|
||||
<i class="anticon anticon-caret-up"></i>
|
||||
<i class="anticon anticon-caret-down"></i>
|
||||
</span>
|
||||
</span>
|
||||
</th>
|
||||
@endforeach
|
||||
@if($apiDelete)
|
||||
<th>Action</th>
|
||||
@endif
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($data as $record)
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered table-hover">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
@foreach($columns as $column)
|
||||
<td>{{ $record[$column['dataIndex']] ?? '' }}</td>
|
||||
<th wire:click="setSort('{{ $column['dataIndex'] }}')" class="cursor-pointer {{ $sortBy === $column['dataIndex'] ? 'bg-primary-subtle' : '' }}">
|
||||
{{ $column['title'] }}
|
||||
<span>
|
||||
<i class="bi bi-caret-up-fill {{ $sortOrder === 'asc' ? 'text-primary' : 'text-muted' }}"></i>
|
||||
<i class="bi bi-caret-down-fill {{ $sortOrder === 'desc' ? 'text-primary' : 'text-muted' }}"></i>
|
||||
</span>
|
||||
</th>
|
||||
@endforeach
|
||||
@if($apiDelete)
|
||||
<td>
|
||||
@foreach($column['buttons'] ?? [] as $action)
|
||||
@if($action['key'] === 'delete' && $record['editable'] !== false)
|
||||
<button wire:click="delete({{ $record[$keyValue] }})" class="ant-btn ant-btn-danger">
|
||||
Delete
|
||||
</button>
|
||||
@elseif(in_array($action['key'], ['edit', 'view', 'location']))
|
||||
<button class="ant-btn ant-btn-primary" wire:click="redirect('{{ $action['key'] }}', {{ $record[$keyValue] }})">
|
||||
{{ ucfirst($action['key']) }}
|
||||
</button>
|
||||
@endif
|
||||
@endforeach
|
||||
</td>
|
||||
<th>Action</th>
|
||||
@endif
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($data as $record)
|
||||
<tr>
|
||||
@foreach($columns as $column)
|
||||
<td>{{ $record[$column['dataIndex']] ?? '' }}</td>
|
||||
@endforeach
|
||||
@if($apiDelete)
|
||||
<td>
|
||||
@foreach($column['buttons'] ?? [] as $action)
|
||||
@if($action['key'] === 'delete' && $record['editable'] !== false)
|
||||
<button wire:click="delete({{ $record[$keyValue] }})" class="btn btn-danger btn-sm me-1">Delete</button>
|
||||
@elseif(in_array($action['key'], ['edit', 'view', 'location']))
|
||||
<button wire:click="redirect('{{ $action['key'] }}', {{ $record[$keyValue] }})" class="btn btn-primary btn-sm me-1">{{ ucfirst($action['key']) }}</button>
|
||||
@endif
|
||||
@endforeach
|
||||
</td>
|
||||
@endif
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@if($total > 0)
|
||||
<div class="row-type-flex justify-space-between" style="margin-top: 20px">
|
||||
<div>
|
||||
<div class="row justify-content-between align-items-center mt-4">
|
||||
<div class="col-auto">
|
||||
@if($apiDelete)
|
||||
<button wire:click="handleBatchDelete" class="ant-btn ant-btn-danger" disabled="{{ count($selectedRowKeys) === 0 }}">
|
||||
<button wire:click="handleBatchDelete" class="btn btn-danger" {{ count($selectedRowKeys) === 0 ? 'disabled' : '' }}>
|
||||
Delete
|
||||
</button>
|
||||
<span style="margin-left: 8px">
|
||||
<span class="ms-2">
|
||||
{{ count($selectedRowKeys) > 0 ? "Selected " . count($selectedRowKeys) . " item(s)" : '' }}
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
<div>
|
||||
<ul class="ant-pagination">
|
||||
@for($i = 1; $i <= ceil($total / $perPage); $i++)
|
||||
<li class="{{ $currentPage === $i ? 'ant-pagination-item-active' : 'ant-pagination-item' }}" wire:click="updatePage({{ $i }})">
|
||||
{{ $i }}
|
||||
</li>
|
||||
@endfor
|
||||
</ul>
|
||||
<div class="col-auto">
|
||||
<nav aria-label="Page navigation">
|
||||
<ul class="pagination">
|
||||
@for($i = 1; $i <= ceil($total / $perPage); $i++)
|
||||
<li class="page-item {{ $currentPage === $i ? 'active' : '' }}">
|
||||
<button wire:click="updatePage({{ $i }})" class="page-link">{{ $i }}</button>
|
||||
</li>
|
||||
@endfor
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.row-type-flex { display: flex; justify-content: space-between; align-items: bottom; }
|
||||
.justify-space-between { justify-content: space-between; }
|
||||
.align-bottom { align-items: bottom; }
|
||||
.table-operations > button { margin-right: 8px; }
|
||||
.ant-table { width: 100%; border-collapse: collapse; }
|
||||
.ant-table th, .ant-table td { border: 1px solid #f0f0f0; padding: 8px; text-align: left; }
|
||||
.ant-table th { background: #fafafa; cursor: pointer; }
|
||||
.ant-table-column-sort { background: #e6f7ff; }
|
||||
.ant-btn { padding: 0 15px; height: 32px; border: 1px solid #d9d9d9; border-radius: 4px; cursor: pointer; }
|
||||
.ant-btn-primary { background: #1890ff; color: white; border-color: #1890ff; }
|
||||
.ant-btn-danger { background: #ff4d4f; color: white; border-color: #ff4d4f; }
|
||||
.loading-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0, 0, 0, 0.5); color: white; text-align: center; padding-top: 20%; z-index: 1000; }
|
||||
.ant-input { border: 1px solid #d9d9d9; border-radius: 4px; padding: 4px 11px; }
|
||||
.ant-input-prefix { position: absolute; left: 8px; top: 50%; transform: translateY(-50%); color: rgba(0,0,0,.25); }
|
||||
</style>
|
|
@ -1,92 +1,75 @@
|
|||
<div style="margin: 0 24px; padding: 24px 0">
|
||||
<div class="container mx-auto py-6">
|
||||
@if (session()->has('success'))
|
||||
<div class="alert alert-success">{{ session('success') }}</div>
|
||||
<div class="alert alert-success mb-4">{{ session('success') }}</div>
|
||||
@endif
|
||||
@if (session()->has('error'))
|
||||
<div class="alert alert-danger">{{ session('error') }}</div>
|
||||
@endif
|
||||
@if (session()->has('info'))
|
||||
<div class="alert alert-info">{{ session('info') }}</div>
|
||||
<div class="alert alert-danger mb-4">{{ session('error') }}</div>
|
||||
@endif
|
||||
|
||||
<div wire:loading wire:target="fetchData" class="loading-overlay">
|
||||
<div wire:loading wire:target="fetchData" class="position-fixed top-0 start-0 w-100 h-100 bg-dark bg-opacity-50 text-white d-flex align-items-center justify-content-center" style="z-index: 1050;">
|
||||
Loading...
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 16px; margin-top: 16px">
|
||||
<input type="text" wire:model.debounce.1000ms="search" placeholder="Search" class="ant-input">
|
||||
<span class="ant-input-prefix" style="color: rgba(0,0,0,.25)">
|
||||
<i class="anticon anticon-search"></i>
|
||||
</span>
|
||||
<button wire:click="handleBatchDelete" class="ant-btn ant-btn-danger" disabled="{{ count($selectedRowKeys) === 0 }}">
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-8">
|
||||
<div class="input-group" style="width: 300px;">
|
||||
<span class="input-group-text"><i class="bi bi-search"></i></span>
|
||||
<input type="text" wire:model.debounce.1000ms="search" class="form-control" placeholder="Search">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<button wire:click="handleBatchDelete" class="btn btn-danger" {{ count($selectedRowKeys) === 0 ? 'disabled' : '' }}>
|
||||
Delete All
|
||||
</button>
|
||||
<span style="margin-left: 8px">
|
||||
<span class="ms-2">
|
||||
{{ count($selectedRowKeys) > 0 ? "Selected " . count($selectedRowKeys) . " items" : '' }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<table class="ant-table ant-table-middle" wire:loading.class="loading">
|
||||
<thead>
|
||||
<tr>
|
||||
@foreach($columns as $column)
|
||||
<th>
|
||||
{{ $column['title'] }}
|
||||
</th>
|
||||
@endforeach
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($data as $record)
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered table-hover">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
@foreach($columns as $column)
|
||||
<td>{{ $record[$column['dataIndex']] ?? '' }}</td>
|
||||
<th>{{ $column['title'] }}</th>
|
||||
@endforeach
|
||||
<td>
|
||||
@foreach($column['renderActions'] ?? [] as $action)
|
||||
@if($action['action_name'] === 'delete')
|
||||
<button wire:click="delete('{{ $action['path'] }}', {{ $record[$keyValue] }})" class="ant-btn ant-btn-danger">
|
||||
Delete
|
||||
</button>
|
||||
@else
|
||||
<button class="ant-btn ant-btn-primary" wire:click="redirect('{{ $action['action_name'] }}', '{{ $action['path'] }}', {{ $record[$keyValue] }})">
|
||||
{{ $action['action_name'] }}
|
||||
</button>
|
||||
@endif
|
||||
@endforeach
|
||||
</td>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($data as $record)
|
||||
<tr>
|
||||
@foreach($columns as $column)
|
||||
<td>{{ $record[$column['dataIndex']] ?? '' }}</td>
|
||||
@endforeach
|
||||
<td>
|
||||
@foreach($column['renderActions'] ?? [] as $action)
|
||||
@if($action['action_name'] === 'delete')
|
||||
<button wire:click="delete('{{ $action['path'] }}', {{ $record[$keyValue] }})" class="btn btn-danger btn-sm me-1">Delete</button>
|
||||
@else
|
||||
<button wire:click="redirect('{{ $action['action_name'] }}', '{{ $action['path'] }}', {{ $record[$keyValue] }})" class="btn btn-primary btn-sm me-1">{{ ucfirst($action['action_name']) }}</button>
|
||||
@endif
|
||||
@endforeach
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@if($total > 0)
|
||||
<div style="float: right; margin-top: 16px">
|
||||
<ul class="ant-pagination">
|
||||
@for($i = 1; $i <= ceil($total / $perPage); $i++)
|
||||
<li class="{{ $currentPage === $i ? 'ant-pagination-item-active' : 'ant-pagination-item' }}" wire:click="updatePage({{ $i }})">
|
||||
{{ $i }}
|
||||
</li>
|
||||
@endfor
|
||||
</ul>
|
||||
<div class="d-flex justify-content-end mt-4">
|
||||
<nav aria-label="Page navigation">
|
||||
<ul class="pagination">
|
||||
@for($i = 1; $i <= ceil($total / $perPage); $i++)
|
||||
<li class="page-item {{ $currentPage === $i ? 'active' : '' }}">
|
||||
<button wire:click="updatePage({{ $i }})" class="page-link">{{ $i }}</button>
|
||||
</li>
|
||||
@endfor
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.row-type-flex { display: flex; justify-content: space-between; align-items: bottom; }
|
||||
.justify-space-between { justify-content: space-between; }
|
||||
.align-bottom { align-items: bottom; }
|
||||
.table-operations > button { margin-right: 8px; }
|
||||
.ant-table { width: 100%; border-collapse: collapse; }
|
||||
.ant-table th, .ant-table td { border: 1px solid #f0f0f0; padding: 8px; text-align: left; }
|
||||
.ant-table th { background: #fafafa; cursor: pointer; }
|
||||
.ant-table-column-sort { background: #e6f7ff; }
|
||||
.ant-btn { padding: 0 15px; height: 32px; border: 1px solid #d9d9d9; border-radius: 4px; cursor: pointer; }
|
||||
.ant-btn-primary { background: #1890ff; color: white; border-color: #1890ff; }
|
||||
.ant-btn-danger { background: #ff4d4f; color: white; border-color: #ff4d4f; }
|
||||
.loading-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0, 0, 0, 0.5); color: white; text-align: center; padding-top: 20%; z-index: 1000; }
|
||||
.ant-input { border: 1px solid #d9d9d9; border-radius: 4px; padding: 4px 11px; }
|
||||
.ant-input-prefix { position: absolute; left: 8px; top: 50%; transform: translateY(-50%); }
|
||||
</style>
|
|
@ -0,0 +1,7 @@
|
|||
<div class="mb-3">
|
||||
<label for="{{ $name }}" class="form-label">{{ $label }}</label>
|
||||
<input type="time" wire:model="value" class="form-control" id="{{ $name }}" {{ $required ? 'required' : '' }}>
|
||||
@error('value')
|
||||
<div class="text-danger small">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
|
@ -0,0 +1,36 @@
|
|||
<div class="mb-3">
|
||||
<label for="{{ $name }}" class="form-label">{{ $label }}</label>
|
||||
|
||||
@if($multipleFileUpload)
|
||||
<!-- Multiple File Upload -->
|
||||
<div class="border rounded p-3 text-center" wire:loading.class="opacity-50">
|
||||
<input type="file" wire:model="image" class="form-control" id="{{ $name }}" accept="image/jpeg,image/png,image/gif" multiple {{ $required ? 'required' : '' }}>
|
||||
<i class="bi bi-upload"></i>
|
||||
<p class="mt-2">Click or drag file to this area to upload</p>
|
||||
<p class="small text-muted">Support for single or bulk upload.</p>
|
||||
</div>
|
||||
@if($fileList)
|
||||
<div class="mt-2 d-flex flex-wrap">
|
||||
@foreach($fileList as $url)
|
||||
<img src="{{ $url }}" alt="Preview" class="img-thumbnail me-2 mb-2" style="width: 100px; height: 100px;">
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
@else
|
||||
<!-- Single File Upload -->
|
||||
<div class="border rounded p-3 text-center" wire:loading.class="opacity-50">
|
||||
<input type="file" wire:model="image" class="form-control" id="{{ $name }}" accept="image/jpeg,image/png,image/gif" {{ $required ? 'required' : '' }}>
|
||||
@if($imageUrl)
|
||||
<img src="{{ $imageUrl }}" alt="Preview" class="mt-2" style="width: {{ $imgStyle['width'] }}; height: {{ $imgStyle['height'] }};">
|
||||
@else
|
||||
<i class="bi bi-upload"></i>
|
||||
<p class="mt-2">Click or drag file to this area to upload</p>
|
||||
<p class="small text-muted">Support for a single upload only.</p>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@error('image')
|
||||
<div class="text-danger small mt-1">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
|
@ -0,0 +1,8 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container my-5">
|
||||
<h1 class="mb-4">Loading Test</h1>
|
||||
@livewire('loading')
|
||||
</div>
|
||||
@endsection
|
|
@ -0,0 +1,9 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container my-5">
|
||||
<h1 class="mb-4">Locations</h1>
|
||||
<p class="lead">This is a placeholder for the Locations page.</p>
|
||||
<a href="{{ url('/') }}" class="btn btn-primary">Back to Home</a>
|
||||
</div>
|
||||
@endsection
|
|
@ -0,0 +1,8 @@
|
|||
@extends('layouts.login')
|
||||
|
||||
@section('content')
|
||||
<div class="container py-5">
|
||||
<h1 class="text-center mb-4">Login</h1>
|
||||
<p class="text-center">Placeholder for login form.</p>
|
||||
</div>
|
||||
@endsection
|
|
@ -0,0 +1,8 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container my-5">
|
||||
<h1 class="mb-4">Multi Select Form</h1>
|
||||
@livewire('multi-select-form', ['name' => 'items', 'label' => 'Select Items', 'required' => true, 'optionsList' => [['id' => 1, 'name' => 'Item 1'], ['id' => 2, 'name' => 'Item 2']]])
|
||||
</div>
|
||||
@endsection
|
|
@ -0,0 +1,8 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container my-5">
|
||||
<h1 class="mb-4">Multi Select Options</h1>
|
||||
@livewire('multi-select-options', ['name' => 'fuels', 'label' => 'Select Fuels', 'required' => true, 'optionsList' => [['id' => 1, 'name' => 'Fuel 1'], ['id' => 2, 'name' => 'Fuel 2']]])
|
||||
</div>
|
||||
@endsection
|
|
@ -0,0 +1,8 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container my-5">
|
||||
<h1 class="mb-4">Notifications</h1>
|
||||
@livewire('notification-table', ['props' => ['columns' => [], 'url' => [], 'keyValue' => 'id']])
|
||||
</div>
|
||||
@endsection
|
|
@ -0,0 +1,16 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container my-5">
|
||||
<h1 class="mb-4">Select Form</h1>
|
||||
@livewire('select-form', [
|
||||
'name' => 'category',
|
||||
'label' => 'Select Category',
|
||||
'required' => true,
|
||||
'optionsList' => [
|
||||
['value' => '1', 'label' => 'Category 1'],
|
||||
['value' => '2', 'label' => 'Category 2']
|
||||
]
|
||||
])
|
||||
</div>
|
||||
@endsection
|
|
@ -0,0 +1,13 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container my-5">
|
||||
<h1 class="mb-4">Image Upload</h1>
|
||||
@livewire('single-upload-image', [
|
||||
'name' => 'avatar',
|
||||
'label' => 'Upload Avatar',
|
||||
'required' => true,
|
||||
'limit100kb' => false
|
||||
])
|
||||
</div>
|
||||
@endsection
|
|
@ -0,0 +1,5 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
@livewire('modal-cancel', ['path' => '/somewhere', 'title' => 'Confirm Exit', 'message' => 'Are you sure?', 'id' => 'modal-container', 'dirty' => true, 'name' => 'Cancel', 'loading' => false])
|
||||
@endsection
|
|
@ -0,0 +1,8 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container my-5">
|
||||
<h1 class="mb-4">Station Table</h1>
|
||||
@livewire('station-table', ['props' => ['columns' => [], 'url' => [], 'keyValue' => 'id']])
|
||||
</div>
|
||||
@endsection
|
|
@ -0,0 +1,8 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container my-5">
|
||||
<h1 class="mb-4">Table Layout</h1>
|
||||
@livewire('table-layout', ['props' => ['headers' => [], 'api' => [], 'keyValue' => 'id']])
|
||||
</div>
|
||||
@endsection
|
|
@ -0,0 +1,19 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container my-5">
|
||||
<h1 class="mb-4">Test Modal</h1>
|
||||
<div id="modal-container">
|
||||
@livewire('modal-cancel', [
|
||||
'path' => '/locations',
|
||||
'title' => 'Confirm Exit',
|
||||
'message' => 'Are you sure you want to leave? Unsaved changes will be lost.',
|
||||
'id' => 'modal-container',
|
||||
'dirty' => true,
|
||||
'name' => 'Cancel',
|
||||
'loading' => false
|
||||
])
|
||||
</div>
|
||||
<p class="mt-3">Click the "Cancel" button to see the modal in action.</p>
|
||||
</div>
|
||||
@endsection
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue