加入分店列表 20250510
This commit is contained in:
parent
aeb14074d2
commit
7092566c8d
116
app/Livewire/Admin/BranchForm.php
Normal file
116
app/Livewire/Admin/BranchForm.php
Normal file
@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Admin;
|
||||
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
use Livewire\Component;
|
||||
use WireUi\Traits\WireUiActions;
|
||||
|
||||
use App\Models\Branch;
|
||||
|
||||
class BranchForm extends Component
|
||||
{
|
||||
use WireUiActions;
|
||||
|
||||
protected $listeners = ['openModal','closeModal', 'deleteArtist'];
|
||||
|
||||
public bool $canCreate;
|
||||
public bool $canEdit;
|
||||
public bool $canDelect;
|
||||
|
||||
public bool $showModal = false;
|
||||
public ?int $branchId = null;
|
||||
|
||||
public array $fields = [
|
||||
'name' =>'',
|
||||
'external_ip' =>'',
|
||||
'enable' => true,
|
||||
];
|
||||
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->canCreate = Auth::user()?->can('room-edit') ?? false;
|
||||
$this->canEdit = Auth::user()?->can('room-edit') ?? false;
|
||||
$this->canDelect = Auth::user()?->can('room-delete') ?? false;
|
||||
}
|
||||
|
||||
public function openModal($id = null)
|
||||
{
|
||||
$this->resetFields();
|
||||
|
||||
if ($id) {
|
||||
$branch = Branch::findOrFail($id);
|
||||
$this->branchId = $branch->id;
|
||||
$this->fields = $branch->only(array_keys($this->fields));
|
||||
}
|
||||
|
||||
$this->showModal = true;
|
||||
}
|
||||
|
||||
public function closeModal()
|
||||
{
|
||||
$this->resetFields();
|
||||
$this->showModal = false;
|
||||
}
|
||||
|
||||
public function save()
|
||||
{
|
||||
if ($this->branchId) {
|
||||
if ($this->canEdit) {
|
||||
$branch = Branch::findOrFail($this->branchId);
|
||||
$branch->update($this->fields);
|
||||
$this->notification()->send([
|
||||
'icon' => 'success',
|
||||
'title' => '成功',
|
||||
'description' => '分店已更新',
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
if ($this->canCreate) {
|
||||
$branch = Branch::create($this->fields);
|
||||
$this->notification()->send([
|
||||
'icon' => 'success',
|
||||
'title' => '成功',
|
||||
'description' => '分店已新增',
|
||||
]);
|
||||
}
|
||||
}
|
||||
$this->resetFields();
|
||||
$this->showModal = false;
|
||||
$this->dispatch('pg:eventRefresh-branch-table');
|
||||
}
|
||||
|
||||
public function deleteArtist($id)
|
||||
{
|
||||
if ($this->canDelect) {
|
||||
Branch::findOrFail($id)->delete();
|
||||
$this->notification()->send([
|
||||
'icon' => 'success',
|
||||
'title' => '成功',
|
||||
'description' => '分店已刪除',
|
||||
]);
|
||||
|
||||
$this->dispatch('pg:eventRefresh-branch-table');
|
||||
}
|
||||
}
|
||||
|
||||
public function resetFields()
|
||||
{
|
||||
foreach ($this->fields as $key => $value) {
|
||||
if ($key == 'enable') {
|
||||
$this->fields[$key] = true;
|
||||
} else {
|
||||
$this->fields[$key] = '';
|
||||
}
|
||||
}
|
||||
$this->branchId = null;
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.admin.branch-form');
|
||||
}
|
||||
}
|
112
app/Livewire/Admin/BranchImportData.php
Normal file
112
app/Livewire/Admin/BranchImportData.php
Normal file
@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Admin;
|
||||
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use WireUi\Traits\WireUiActions;
|
||||
use Livewire\Component;
|
||||
use Livewire\WithFileUploads;
|
||||
use App\Jobs\ImportJob;
|
||||
|
||||
|
||||
class BranchImportData extends Component
|
||||
{
|
||||
use WithFileUploads, WireUiActions;
|
||||
|
||||
protected $listeners = ['openModal','closeModal'];
|
||||
|
||||
public bool $canCreate;
|
||||
|
||||
public bool $showModal = false;
|
||||
|
||||
public $file;
|
||||
public string $maxUploadSize;
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->canCreate = Auth::user()?->can('room-edit') ?? false;
|
||||
$this->maxUploadSize = $this->getMaxUploadSize();
|
||||
}
|
||||
|
||||
public function openModal()
|
||||
{
|
||||
$this->showModal = true;
|
||||
}
|
||||
|
||||
public function closeModal()
|
||||
{
|
||||
$this->deleteTmpFile(); // 關閉 modal 時刪除暫存檔案
|
||||
$this->reset(['file']);
|
||||
$this->showModal = false;
|
||||
}
|
||||
|
||||
public function import()
|
||||
{
|
||||
// 檢查檔案是否有上傳
|
||||
$this->validate([
|
||||
'file' => 'required|file|mimes:csv,xlsx,xls'
|
||||
]);
|
||||
if ($this->canCreate) {
|
||||
// 儲存檔案至 storage
|
||||
$path = $this->file->storeAs('imports', uniqid() . '_' . $this->file->getClientOriginalName());
|
||||
|
||||
// 丟到 queue 執行
|
||||
ImportJob::dispatch($path,'Branch');
|
||||
|
||||
$this->notification()->send([
|
||||
'icon' => 'info',
|
||||
'title' => $this->file->getClientOriginalName(),
|
||||
'description' => '已排入背景匯入作業,請稍候查看結果',
|
||||
]);
|
||||
$this->deleteTmpFile(); // 匯入後也順便刪除 tmp 檔
|
||||
$this->reset(['file']);
|
||||
$this->showModal = false;
|
||||
}
|
||||
}
|
||||
protected function deleteTmpFile()
|
||||
{
|
||||
$Path = $this->file->getRealPath();
|
||||
if ($Path && File::exists($Path)) {
|
||||
File::delete($Path);
|
||||
}
|
||||
}
|
||||
|
||||
private function getMaxUploadSize(): string
|
||||
{
|
||||
$uploadMax = $this->convertPHPSizeToBytes(ini_get('upload_max_filesize'));
|
||||
$postMax = $this->convertPHPSizeToBytes(ini_get('post_max_size'));
|
||||
$max = min($uploadMax, $postMax);
|
||||
return $this->humanFileSize($max);
|
||||
}
|
||||
|
||||
private function convertPHPSizeToBytes(string $s): int
|
||||
{
|
||||
$s = trim($s);
|
||||
$unit = strtolower($s[strlen($s) - 1]);
|
||||
$bytes = (int) $s;
|
||||
switch ($unit) {
|
||||
case 'g':
|
||||
$bytes *= 1024;
|
||||
case 'm':
|
||||
$bytes *= 1024;
|
||||
case 'k':
|
||||
$bytes *= 1024;
|
||||
}
|
||||
return $bytes;
|
||||
}
|
||||
|
||||
private function humanFileSize(int $bytes, int $decimals = 2): string
|
||||
{
|
||||
$sizes = ['B', 'KB', 'MB', 'GB'];
|
||||
$factor = floor((strlen((string) $bytes) - 1) / 3);
|
||||
return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . $sizes[$factor];
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.admin.branch-import-data');
|
||||
}
|
||||
|
||||
}
|
213
app/Livewire/Admin/BranchTable.php
Normal file
213
app/Livewire/Admin/BranchTable.php
Normal file
@ -0,0 +1,213 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Admin;
|
||||
|
||||
use App\Models\Branch;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Blade;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use PowerComponents\LivewirePowerGrid\Button;
|
||||
use PowerComponents\LivewirePowerGrid\Column;
|
||||
use PowerComponents\LivewirePowerGrid\Facades\Filter;
|
||||
use PowerComponents\LivewirePowerGrid\Facades\PowerGrid;
|
||||
use PowerComponents\LivewirePowerGrid\PowerGridFields;
|
||||
use PowerComponents\LivewirePowerGrid\PowerGridComponent;
|
||||
use PowerComponents\LivewirePowerGrid\Traits\WithExport;
|
||||
use PowerComponents\LivewirePowerGrid\Components\SetUp\Exportable;
|
||||
use PowerComponents\LivewirePowerGrid\Facades\Rule;
|
||||
use Livewire\Attributes\On;
|
||||
use WireUi\Traits\WireUiActions;
|
||||
|
||||
final class BranchTable extends PowerGridComponent
|
||||
{
|
||||
public string $tableName = 'branch-table';
|
||||
public bool $canCreate;
|
||||
public bool $canEdit;
|
||||
public bool $canDownload;
|
||||
public bool $canDelect;
|
||||
|
||||
public bool $showFilters = false;
|
||||
|
||||
public function boot(): void
|
||||
{
|
||||
config(['livewire-powergrid.filter' => 'outside']);
|
||||
//權限設定
|
||||
$this->canCreate = Auth::user()?->can('room-edit') ?? false;
|
||||
$this->canEdit = Auth::user()?->can('room-edit') ?? false;
|
||||
$this->canDownload=Auth::user()?->can('room-delete') ?? false;
|
||||
$this->canDelect = Auth::user()?->can('room-delete') ?? false;
|
||||
}
|
||||
|
||||
public function setUp(): array
|
||||
{
|
||||
if($this->canDownload || $this->canDelect){
|
||||
$this->showCheckBox();
|
||||
}
|
||||
$actions = [];
|
||||
if($this->canDownload){
|
||||
$actions[]=PowerGrid::exportable(fileName: 'branch-file')
|
||||
->type(Exportable::TYPE_XLS, Exportable::TYPE_CSV);
|
||||
}
|
||||
$header = PowerGrid::header()
|
||||
->withoutLoading()
|
||||
->showToggleColumns();
|
||||
//->showSoftDeletes()
|
||||
//->showSearchInput()
|
||||
if($this->canCreate){
|
||||
$header->includeViewOnTop('livewire.admin.branch-header') ;
|
||||
}
|
||||
$actions[]=$header;
|
||||
$actions[]=PowerGrid::footer()->showPerPage()->showRecordCount();
|
||||
return $actions;
|
||||
}
|
||||
|
||||
public function header(): array
|
||||
{
|
||||
$actions = [];
|
||||
if ($this->canDelect) {
|
||||
$actions[]=Button::add('bulk-delete')
|
||||
->slot('Bulk delete (<span x-text="window.pgBulkActions.count(\'' . $this->tableName . '\')"></span>)')
|
||||
->icon('solid-trash',['id' => 'my-custom-icon-id', 'class' => 'font-bold'])
|
||||
->class('inline-flex items-center gap-1 px-3 py-1 rounded ')
|
||||
->dispatch('bulkDelete.' . $this->tableName, []);
|
||||
}
|
||||
return $actions;
|
||||
}
|
||||
|
||||
public function datasource(): Builder
|
||||
{
|
||||
return Branch::query();
|
||||
}
|
||||
|
||||
public function relationSearch(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function fields(): PowerGridFields
|
||||
{
|
||||
return PowerGrid::fields()
|
||||
->add('id')
|
||||
->add('name')
|
||||
->add('external_ip')
|
||||
->add('enable')
|
||||
->add('created_at_formatted', fn (Branch $model) => Carbon::parse($model->created_at)->format('d/m/Y H:i:s'));
|
||||
}
|
||||
|
||||
public function columns(): array
|
||||
{
|
||||
$column=[];
|
||||
$column[]=Column::make(__('branches.no'), 'id');
|
||||
$column[]=Column::make(__('branches.name'), 'name')->sortable()->searchable()
|
||||
->editOnClick(
|
||||
hasPermission: $this->canEdit,
|
||||
dataField: 'name',
|
||||
fallback: 'N/A',
|
||||
saveOnMouseOut: true
|
||||
);
|
||||
$column[]=Column::make(__('branches.external_ip'), 'external_ip')->sortable()->searchable()
|
||||
->editOnClick(
|
||||
hasPermission: $this->canEdit,
|
||||
dataField: 'external_ip',
|
||||
fallback: 'N/A',
|
||||
saveOnMouseOut: true
|
||||
);
|
||||
$column[]=Column::make(__('branches.enable'), 'enable')
|
||||
->toggleable(
|
||||
hasPermission: $this->canEdit,
|
||||
trueLabel: 'yes',
|
||||
falseLabel: 'no'
|
||||
);
|
||||
$column[]=Column::make('Created at', 'created_at_formatted', 'created_at')->sortable()->hidden(true, false);
|
||||
$column[]=Column::action(__('branches.actions'));
|
||||
return $column;
|
||||
}
|
||||
#[On('bulkDelete.{tableName}')]
|
||||
public function bulkDelete(): void
|
||||
{
|
||||
if ($this->canDelect) {
|
||||
$this->js('alert(window.pgBulkActions.get(\'' . $this->tableName . '\'))');
|
||||
if($this->checkboxValues){
|
||||
Branch::destroy($this->checkboxValues);
|
||||
$this->js('window.pgBulkActions.clearAll()'); // clear the count on the interface.
|
||||
}
|
||||
}
|
||||
}
|
||||
#[On('categoryChanged')]
|
||||
public function categoryChanged($value,$fieldName, $modelId): void
|
||||
{
|
||||
// dd($value,$fieldName, $modelId);
|
||||
if ($fieldName == 'category' && $this->canEdit) {
|
||||
$this->noUpdated($modelId,$fieldName,$value);
|
||||
}
|
||||
}
|
||||
#[On('onUpdatedEditable')]
|
||||
public function onUpdatedEditable($id, $field, $value): void
|
||||
{
|
||||
if ($field === 'name' && $this->canEdit) {
|
||||
$this->noUpdated($id,$field,$value);
|
||||
}
|
||||
}
|
||||
#[On('onUpdatedToggleable')]
|
||||
public function onUpdatedToggleable($id, $field, $value): void
|
||||
{
|
||||
if (in_array($field,['enable']) && $this->canEdit) {
|
||||
$this->noUpdated($id,$field,$value);
|
||||
}
|
||||
}
|
||||
private function noUpdated($id,$field,$value){
|
||||
$branch = Branch::find($id);
|
||||
if ($branch) {
|
||||
$branch->{$field} = $value;
|
||||
$branch->save(); // 明確觸發 saving
|
||||
}
|
||||
$this->notification()->send([
|
||||
'icon' => 'success',
|
||||
'title' => $id.'.'.__('branches.'.$field).':'.$value,
|
||||
'description' => '已經寫入',
|
||||
]);
|
||||
}
|
||||
public function filters(): array
|
||||
{
|
||||
return [
|
||||
Filter::inputText('name')->placeholder(__('branches.name')),
|
||||
Filter::inputText('external_ip')->placeholder(__('branches.external_ip')),
|
||||
Filter::boolean('enable')->label('✅', '❌'),
|
||||
Filter::datetimepicker('created_at'),
|
||||
];
|
||||
}
|
||||
|
||||
public function actions(Branch $row): array
|
||||
{
|
||||
$actions = [];
|
||||
if ($this->canEdit) {
|
||||
$actions[] =Button::add('edit')
|
||||
->slot(__('branches.edit'))
|
||||
->icon('solid-pencil-square')
|
||||
->class('inline-flex items-center gap-1 px-3 py-1 rounded ')
|
||||
->dispatchTo('admin.branch-form', 'openModal', ['id' => $row->id]);
|
||||
}
|
||||
if($this->canDelect){
|
||||
$actions[] =Button::add('delete')
|
||||
->slot(__('branches.delete'))
|
||||
->icon('solid-trash')
|
||||
->class('inline-flex items-center gap-1 px-3 py-1 rounded ')
|
||||
->dispatchTo('admin.branch-form', 'deleteBranch', ['id' => $row->id]);
|
||||
}
|
||||
return $actions;
|
||||
}
|
||||
|
||||
/*
|
||||
public function actionRules($row): array
|
||||
{
|
||||
return [
|
||||
// Hide button edit for ID 1
|
||||
Rule::button('edit')
|
||||
->when(fn($row) => $row->id === 1)
|
||||
->hide(),
|
||||
];
|
||||
}
|
||||
*/
|
||||
}
|
@ -1,108 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Admin;
|
||||
|
||||
use App\Models\Branches;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use PowerComponents\LivewirePowerGrid\Button;
|
||||
use PowerComponents\LivewirePowerGrid\Column;
|
||||
use PowerComponents\LivewirePowerGrid\Facades\Filter;
|
||||
use PowerComponents\LivewirePowerGrid\Facades\PowerGrid;
|
||||
use PowerComponents\LivewirePowerGrid\PowerGridFields;
|
||||
use PowerComponents\LivewirePowerGrid\PowerGridComponent;
|
||||
|
||||
final class BranchesTable extends PowerGridComponent
|
||||
{
|
||||
public string $tableName = 'branches-table-lcqb7y-table';
|
||||
|
||||
public function setUp(): array
|
||||
{
|
||||
$this->showCheckBox();
|
||||
|
||||
return [
|
||||
PowerGrid::header()
|
||||
->showSearchInput(),
|
||||
PowerGrid::footer()
|
||||
->showPerPage()
|
||||
->showRecordCount(),
|
||||
];
|
||||
}
|
||||
|
||||
public function datasource(): Builder
|
||||
{
|
||||
return Branches::query();
|
||||
}
|
||||
|
||||
public function relationSearch(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function fields(): PowerGridFields
|
||||
{
|
||||
return PowerGrid::fields()
|
||||
->add('id')
|
||||
->add('name')
|
||||
->add('external_ip')
|
||||
->add('created_at');
|
||||
}
|
||||
|
||||
public function columns(): array
|
||||
{
|
||||
return [
|
||||
Column::make('Id', 'id'),
|
||||
Column::make('Name', 'name')
|
||||
->sortable()
|
||||
->searchable(),
|
||||
|
||||
Column::make('External ip', 'external_ip')
|
||||
->sortable()
|
||||
->searchable(),
|
||||
|
||||
Column::make('Created at', 'created_at_formatted', 'created_at')
|
||||
->sortable(),
|
||||
|
||||
Column::make('Created at', 'created_at')
|
||||
->sortable()
|
||||
->searchable(),
|
||||
|
||||
Column::action('Action')
|
||||
];
|
||||
}
|
||||
|
||||
public function filters(): array
|
||||
{
|
||||
return [
|
||||
];
|
||||
}
|
||||
|
||||
#[\Livewire\Attributes\On('edit')]
|
||||
public function edit($rowId): void
|
||||
{
|
||||
$this->js('alert('.$rowId.')');
|
||||
}
|
||||
|
||||
public function actions(Branches $row): array
|
||||
{
|
||||
return [
|
||||
Button::add('edit')
|
||||
->slot('Edit: '.$row->id)
|
||||
->id()
|
||||
->class('pg-btn-white dark:ring-pg-primary-600 dark:border-pg-primary-600 dark:hover:bg-pg-primary-700 dark:ring-offset-pg-primary-800 dark:text-pg-primary-300 dark:bg-pg-primary-700')
|
||||
->dispatch('edit', ['rowId' => $row->id])
|
||||
];
|
||||
}
|
||||
|
||||
/*
|
||||
public function actionRules($row): array
|
||||
{
|
||||
return [
|
||||
// Hide button edit for ID 1
|
||||
Rule::button('edit')
|
||||
->when(fn($row) => $row->id === 1)
|
||||
->hide(),
|
||||
];
|
||||
}
|
||||
*/
|
||||
}
|
@ -13,8 +13,9 @@ return new class extends Migration
|
||||
{
|
||||
Schema::create('branches', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name');
|
||||
$table->ipAddress('external_ip'); // 對外 IP
|
||||
$table->string('name')->comment('店名');
|
||||
$table->ipAddress('external_ip')->comment('對外IP'); // 對外 IP
|
||||
$table->tinyInteger('enable')->default(1)->comment('狀態');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
@ -13,13 +13,13 @@ return new class extends Migration
|
||||
{
|
||||
Schema::create('rooms', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('branch_id')->constrained()->onDelete('cascade'); // 關聯分店
|
||||
$table->string('name'); // 包廂名稱
|
||||
$table->string('internal_ip'); // 內部 IP
|
||||
$table->unsignedSmallInteger('port'); // 通訊 Port
|
||||
$table->enum('status', ['active', 'closed', 'error', 'maintenance']); // 狀態:啟用中 / 已結束
|
||||
$table->dateTime('started_at'); // 開始時間
|
||||
$table->dateTime('ended_at')->nullable(); // 結束時間
|
||||
$table->foreignId('branch_id')->constrained()->onDelete('cascade')->comment('關聯分店');
|
||||
$table->string('name')->comment('包廂名稱');
|
||||
$table->string('internal_ip')->comment('內部 IP');
|
||||
$table->unsignedSmallInteger('port')->comment('通訊 Port');
|
||||
$table->enum('status', ['active', 'closed', 'error', 'maintenance'])->comment('狀態'); // :啟用中 / 已結束
|
||||
$table->dateTime('started_at')->comment('開始時間'); //
|
||||
$table->dateTime('ended_at')->nullable()->comment('結束時間'); //
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
23
resources/lang/zh-tw/branches.php
Normal file
23
resources/lang/zh-tw/branches.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'management' => '分店管理',
|
||||
'list' => '分店列表',
|
||||
'CreateNew' => '新增分店',
|
||||
'EditBranch' => '編輯分店',
|
||||
'ImportData' => '滙入分店',
|
||||
'create_edit' => '新增 / 編輯',
|
||||
'create' => '新增',
|
||||
'edit' => '編輯',
|
||||
'delete' => '刪除',
|
||||
'no' => '編號',
|
||||
'name' => '名稱',
|
||||
'external_ip' => '對外IP',
|
||||
'enable' => '狀態',
|
||||
|
||||
|
||||
'actions' => '操作',
|
||||
'view' => '查看',
|
||||
'submit' => '提交',
|
||||
'cancel' => '取消',
|
||||
];
|
15
resources/views/livewire/admin/branch-form.blade.php
Normal file
15
resources/views/livewire/admin/branch-form.blade.php
Normal file
@ -0,0 +1,15 @@
|
||||
<x-wireui:modal-card title="{{ $branchId ? __('branches.EditBranch') : __('branches.CreateNew') }}" blur wire:model.defer="showModal">
|
||||
<div class="space-y-4">
|
||||
<x-wireui:input label="{{__('branches.name')}}" wire:model.defer="fields.name" />
|
||||
<x-wireui:input label="{{__('branches.external_ip')}}" wire:model.defer="fields.external_ip" />
|
||||
<x-wireui:toggle label="{{__('branches.enable')}}" wire:model.defer="fields.enable" />
|
||||
</div>
|
||||
|
||||
<x-slot name="footer">
|
||||
<div class="flex justify-between w-full">
|
||||
<x-wireui:button flat label="{{__('branches.cancel')}}" wire:click="closeModal" />
|
||||
<x-wireui:button primary label="{{__('branches.submit')}}" wire:click="save" />
|
||||
</div>
|
||||
</x-slot>
|
||||
</x-wireui:modal-card>
|
||||
|
15
resources/views/livewire/admin/branch-header.blade.php
Normal file
15
resources/views/livewire/admin/branch-header.blade.php
Normal file
@ -0,0 +1,15 @@
|
||||
<div class="flex justify-end mb-2 mr-2 mt-2 sm:mt-0 gap-3">
|
||||
<x-wireui:button
|
||||
wire:click="$dispatchTo('admin.branch-form', 'openModal')"
|
||||
icon="plus"
|
||||
label="{{ __('branches.CreateNew') }}"
|
||||
class="bg-blue-600 text-white"
|
||||
/>
|
||||
|
||||
<x-wireui:button
|
||||
wire:click="$dispatchTo('admin.branch-import-data','openModal')"
|
||||
icon="document-plus"
|
||||
label="{{ __('branches.ImportData') }}"
|
||||
class="bg-green-600 text-white"
|
||||
/>
|
||||
</div>
|
62
resources/views/livewire/admin/branch-import-data.blade.php
Normal file
62
resources/views/livewire/admin/branch-import-data.blade.php
Normal file
@ -0,0 +1,62 @@
|
||||
<x-wireui:modal-card title="{{ __('branches.ImportData') }}" blur wire:model.defer="showModal" hide-close>
|
||||
|
||||
{{-- 說明區塊 --}}
|
||||
<div class="mb-4 p-4 bg-gray-100 border border-gray-300 rounded text-sm text-gray-700">
|
||||
<p class="font-semibold mb-2">匯入格式說明</p>
|
||||
<p class="mb-2">請依下列表格格式準備 Excel 或 CSV 檔案:</p>
|
||||
|
||||
<div class="overflow-x-auto mb-2">
|
||||
<table class="min-w-full text-sm text-left border border-collapse border-gray-300">
|
||||
<thead class="bg-gray-200">
|
||||
<tr>
|
||||
<th class="border border-gray-300 px-3 py-1">欄位名稱</th>
|
||||
<th class="border border-gray-300 px-3 py-1">說明</th>
|
||||
<th class="border border-gray-300 px-3 py-1">範例</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="border border-gray-300 px-3 py-1">??</td>
|
||||
<td class="border border-gray-300 px-3 py-1">??</td>
|
||||
<td class="border border-gray-300 px-3 py-1">??</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{{-- 檔案上傳 --}}
|
||||
<div x-data="{
|
||||
fileName: '',
|
||||
updateFileInfo(event) {
|
||||
const file = event.target.files[0];
|
||||
if (file) this.fileName = file.name+ '('+(file.size / 1024 / 1024).toFixed(2) + ' MB'+')';
|
||||
}
|
||||
}"
|
||||
>
|
||||
<div x-show="$wire.file === null" >
|
||||
<input type="file" wire:model="file" accept=".csv, .xls, .xlsx" class="mb-2 w-full" @change="updateFileInfo" />
|
||||
<p class="text-xs text-gray-500 mb-2" >
|
||||
系統限制:最大上傳 {{ $maxUploadSize }}
|
||||
</p>
|
||||
</div>
|
||||
<!-- 檔案資訊顯示 -->
|
||||
<div wire:loading.remove wire:target="file" class="text-sm text-green-600 flex items-center space-x-1" x-show="$wire.file != null">
|
||||
<x-wireui:icon name="check-circle" class="w-5 h-5 text-green-500" />
|
||||
<strong x-text="fileName"></strong>
|
||||
</div>
|
||||
<!-- 上傳中提示 -->
|
||||
<div wire:loading wire:target="file" class="text-sm text-blue-500">
|
||||
檔案上傳中,請稍候...
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<x-slot name="footer">
|
||||
<div class="flex justify-between w-full">
|
||||
<x-wireui:button flat label="{{ __('branches.cancel') }}" wire:click="closeModal" />
|
||||
<x-wireui:button primary label="{{ __('branches.submit') }}" wire:click="import" />
|
||||
</div>
|
||||
</x-slot>
|
||||
</x-wireui:modal-card>
|
7
resources/views/livewire/admin/branches.blade.php
Normal file
7
resources/views/livewire/admin/branches.blade.php
Normal file
@ -0,0 +1,7 @@
|
||||
|
||||
<x-layouts.admin>
|
||||
<x-wireui:notifications/>
|
||||
<livewire:admin.branch-table />
|
||||
<livewire:admin.branch-form />
|
||||
<livewire:admin.branch-import-data />
|
||||
</x-layouts.admin>
|
@ -7,6 +7,7 @@
|
||||
['label' => 'User', 'route' => 'admin.users', 'icon' => 'user-circle', 'permission' => 'user-list'],
|
||||
['label' => 'Artist', 'route' => 'admin.artists', 'icon' => 'musical-note', 'permission' => 'song-list'],
|
||||
['label' => 'Song', 'route' => 'admin.songs', 'icon' => 'musical-note', 'permission' => 'song-list'],
|
||||
['label' => 'Branche', 'route' => 'admin.branches', 'icon' => 'building-library', 'permission' => 'room-list'],
|
||||
];
|
||||
@endphp
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user