調整 檔案位置

修正 User新增 加入密碼驗証
20250726
This commit is contained in:
allen.yan 2025-07-26 17:22:09 +08:00
parent 14debd3e63
commit 81a86ff65d
41 changed files with 109 additions and 73 deletions

View File

@ -1,6 +1,6 @@
<?php
namespace App\Livewire\Admin;
namespace App\Livewire\Forms;
use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\Auth;
@ -119,6 +119,6 @@ class ArtistForm extends Component
public function render()
{
return view('livewire.admin.artist-form');
return view('livewire.forms.artist-form');
}
}

View File

@ -1,6 +1,6 @@
<?php
namespace App\Livewire\Admin;
namespace App\Livewire\Forms;
use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\Auth;
@ -145,6 +145,6 @@ class BranchForm extends Component
public function render()
{
return view('livewire.admin.branch-form');
return view('livewire.forms.branch-form');
}
}

View File

@ -1,6 +1,6 @@
<?php
namespace App\Livewire\Admin;
namespace App\Livewire\Forms\ImportDatas;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
@ -11,7 +11,7 @@ use Livewire\WithFileUploads;
use App\Jobs\ImportJob;
class ArtistImportData extends Component
class Artist extends Component
{
use WithFileUploads, WireUiActions;
@ -108,7 +108,7 @@ class ArtistImportData extends Component
public function render()
{
return view('livewire.admin.artist-import-data');
return view('livewire.forms.import-datas.artist');
}
}

View File

@ -1,6 +1,6 @@
<?php
namespace App\Livewire\Admin;
namespace App\Livewire\Forms\ImportDatas;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
@ -11,7 +11,7 @@ use Livewire\WithFileUploads;
use App\Jobs\ImportJob;
class BranchImportData extends Component
class Branch extends Component
{
use WithFileUploads, WireUiActions;
@ -108,7 +108,7 @@ class BranchImportData extends Component
public function render()
{
return view('livewire.admin.branch-import-data');
return view('livewire.forms.import-datas.branch');
}
}

View File

@ -1,6 +1,6 @@
<?php
namespace App\Livewire\Admin;
namespace App\Livewire\Forms\ImportDatas;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
@ -11,7 +11,7 @@ use Livewire\WithFileUploads;
use App\Jobs\ImportJob;
class SongImportData extends Component
class Song extends Component
{
use WithFileUploads, WireUiActions;
@ -108,7 +108,7 @@ class SongImportData extends Component
public function render()
{
return view('livewire.admin.song-import-data');
return view('livewire.forms.import-datas.song');
}
}

View File

@ -1,6 +1,6 @@
<?php
namespace App\Livewire\Admin;
namespace App\Livewire\Forms;
use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\Auth;
@ -109,6 +109,6 @@ class RoleForm extends Component
public function render()
{
return view('livewire.admin.role-form');
return view('livewire.forms.role-form');
}
}

View File

@ -1,6 +1,6 @@
<?php
namespace App\Livewire\Admin;
namespace App\Livewire\Forms;
use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\Auth;
@ -157,6 +157,6 @@ class SongForm extends Component
}
public function render()
{
return view('livewire.admin.song-form');
return view('livewire.forms.song-form');
}
}

View File

@ -1,6 +1,6 @@
<?php
namespace App\Livewire\Admin;
namespace App\Livewire\Forms;
use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\Auth;
@ -37,6 +37,8 @@ class UserForm extends Component
'birthday' => '',
'gender' => 'unset',
'status' => 0,
'password' => '', // 新增
'password_confirmation' => '', // 新增
];
@ -86,7 +88,16 @@ class UserForm extends Component
public function save()
{
//$this->validate();
$rules = $this->rules;
// 加入 email / phone 唯一性驗證,排除自己(編輯時)
$rules['fields.email'] .= '|unique:users,email' . ($this->userId ? ",{$this->userId}" : '');
$rules['fields.phone'] .= '|unique:users,phone' . ($this->userId ? ",{$this->userId}" : '');
// 新增時才驗證密碼
if (!$this->userId) {
$rules['fields.password'] = ['required', 'string', 'min:8', 'confirmed'];
}
$validated = $this->validate($rules);
if ($this->userId) {
if ($this->canEdit) {
@ -148,6 +159,6 @@ class UserForm extends Component
public function render()
{
return view('livewire.admin.user-form');
return view('livewire.forms.user-form');
}
}

View File

@ -1,6 +1,6 @@
<?php
namespace App\Livewire\Admin;
namespace App\Livewire\Grids\Modals;
use App\Models\Room;
use App\Models\Branch;
@ -110,6 +110,6 @@ class RoomDetailModal extends Component
}
public function render()
{
return view('livewire.admin.room-detail-modal');
return view('livewire.grids.modals.room-detail-modal');
}
}

View File

@ -1,6 +1,6 @@
<?php
namespace App\Livewire\Admin;
namespace App\Livewire\Grids;
use App\Models\Room;
use App\Models\Branch;
@ -42,6 +42,6 @@ class RoomGrid extends Component
// 取得樓層
$floors = $rooms->pluck('floor')->unique()->sort()->values()->toArray();
return view('livewire.admin.room-grid',['rooms' =>$rooms,'floors' =>$floors]);
return view('livewire.grids.room-grid',['rooms' =>$rooms,'floors' =>$floors]);
}
}

View File

@ -1,6 +1,6 @@
<?php
namespace App\Livewire\Admin;
namespace App\Livewire\Tables;
use App\Models\ActivityLog;
use Illuminate\Support\Carbon;
@ -44,7 +44,7 @@ final class ActivityLogTable extends PowerGridComponent
->showToggleColumns();
//->showSoftDeletes()
//->showSearchInput()
$header->includeViewOnTop('livewire.admin.activity-log-header');
$header->includeViewOnTop('livewire.forms.headers.activity-log');
$actions[]=$header;
$actions[]=PowerGrid::footer()->showPerPage()->showRecordCount();
return $actions;

View File

@ -1,6 +1,6 @@
<?php
namespace App\Livewire\Admin;
namespace App\Livewire\Tables;
use App\Models\Artist;
use App\Enums\ArtistCategory;
@ -63,7 +63,7 @@ final class ArtistTable extends PowerGridComponent
//->showSoftDeletes()
//->showSearchInput()
if($this->canCreate){
$header->includeViewOnTop('livewire.admin.artist-header') ;
$header->includeViewOnTop('livewire.forms.headers.artist') ;
}
$actions[]=$header;
$actions[]=PowerGrid::footer()->showPerPage()->showRecordCount();
@ -211,14 +211,14 @@ final class ArtistTable extends PowerGridComponent
->slot(__('artists.edit'))
->icon('solid-pencil-square')
->class('inline-flex items-center gap-1 px-3 py-1 rounded ')
->dispatchTo('admin.artist-form', 'openModal', ['id' => $row->id]);
->dispatchTo('forms.artist-form', 'openModal', ['id' => $row->id]);
}
if($this->canDelect){
$actions[] =Button::add('delete')
->slot(__('artists.delete'))
->icon('solid-trash')
->class('inline-flex items-center gap-1 px-3 py-1 rounded ')
->dispatchTo('admin.artist-form', 'deleteArtist', ['id' => $row->id]);
->dispatchTo('forms.artist-form', 'deleteArtist', ['id' => $row->id]);
}
return $actions;
}

View File

@ -1,6 +1,6 @@
<?php
namespace App\Livewire\Admin;
namespace App\Livewire\Tables;
use App\Models\Branch;
use App\Jobs\ExportSqliteBranchJob;
@ -61,7 +61,7 @@ final class BranchTable extends PowerGridComponent
//->showSoftDeletes()
//->showSearchInput()
if($this->canCreate){
$header->includeViewOnTop('livewire.admin.branch-header') ;
$header->includeViewOnTop('livewire.forms.headers.branch') ;
}
$actions[]=$header;
$actions[]=PowerGrid::footer()->showPerPage()->showRecordCount();
@ -205,7 +205,7 @@ final class BranchTable extends PowerGridComponent
->slot('包廂設定')
->icon('solid-cog')
->class('inline-flex items-center gap-1 px-3 py-1 rounded bg-amber-200 text-black')
->dispatchTo('admin.room-grid', 'openModal', ['branch_id' => $row->id]);
->dispatchTo('grids.room-grid', 'openModal', ['branch_id' => $row->id]);
$actions[] = Button::add('room-synchronous')
->slot('包廂同步')
->icon('solid-cog')
@ -216,14 +216,14 @@ final class BranchTable extends PowerGridComponent
->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]);
->dispatchTo('forms.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]);
->dispatchTo('forms.branch-form', 'deleteBranch', ['id' => $row->id]);
}
return $actions;
}

View File

@ -1,6 +1,6 @@
<?php
namespace App\Livewire\Admin;
namespace App\Livewire\Tables;
use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;
@ -42,7 +42,7 @@ final class RoleTable extends PowerGridComponent
$actions = [];
$header =PowerGrid::header();
if($this->canCreate){
$header->includeViewOnTop('livewire.admin.role-header');
$header->includeViewOnTop('livewire.forms.headers.role');
}
$actions[]=$header;
$actions[]=PowerGrid::footer()
@ -155,14 +155,14 @@ final class RoleTable extends PowerGridComponent
->slot(__('roles.edit'))
->icon('solid-pencil-square')
->class('inline-flex items-center gap-1 px-3 py-1 rounded ')
->dispatchTo('admin.role-form', 'openEditRoleModal', ['id' => $row->id]);
->dispatchTo('forms.role-form', 'openEditRoleModal', ['id' => $row->id]);
}
if($this->canDelect){
$actions[] =Button::add('delete')
->slot(__('roles.delete'))
->icon('solid-trash')
->class('inline-flex items-center gap-1 px-3 py-1 rounded ')
->dispatchTo('admin.role-form', 'deleteRole', ['id' => $row->id]);
->dispatchTo('forms.role-form', 'deleteRole', ['id' => $row->id]);
}
return $actions;
}

View File

@ -1,6 +1,6 @@
<?php
namespace App\Livewire\Admin;
namespace App\Livewire\Tables;
use App\Models\Song;
use App\Enums\SongLanguageType;
@ -59,7 +59,7 @@ final class SongTable extends PowerGridComponent
}
$header = PowerGrid::header()->showSoftDeletes()->showToggleColumns();
if($this->canCreate){
$header->includeViewOnTop('livewire.admin.song-header');
$header->includeViewOnTop('livewire.forms.headers.song');
}
$actions[]=$header;
$actions[]=PowerGrid::footer()->showPerPage()->showRecordCount();
@ -261,14 +261,14 @@ final class SongTable extends PowerGridComponent
->slot(__('songs.edit'))
->icon('solid-pencil-square')
->class('inline-flex items-center gap-1 px-3 py-1 rounded ')
->dispatchTo('admin.song-form', 'openModal', ['id' => $row->id]);
->dispatchTo('forms.song-form', 'openModal', ['id' => $row->id]);
}
if($this->canDelect){
$actions[]=Button::add('delete')
->slot(__('songs.delete'))
->icon('solid-trash')
->class('inline-flex items-center gap-1 px-3 py-1 rounded ')
->dispatchTo('admin.song-form', 'deleteSong', ['id' => $row->id]);
->dispatchTo('forms.song-form', 'deleteSong', ['id' => $row->id]);
}
return $actions;

View File

@ -53,7 +53,7 @@ final class TextAdsTable extends PowerGridComponent
}
$header = PowerGrid::header()->showSoftDeletes()->showToggleColumns();
if($this->canCreate){
$header->includeViewOnTop('livewire.header.text-ad');
$header->includeViewOnTop('livewire.forms.headers.text-ad');
}
$actions[]=$header;
$actions[]=PowerGrid::footer()->showPerPage()->showRecordCount();

View File

@ -1,6 +1,6 @@
<?php
namespace App\Livewire\Admin;
namespace App\Livewire\Tables;
use App\Models\User;
use App\Enums\UserGender;
@ -55,7 +55,7 @@ final class UserTable extends PowerGridComponent
$header = PowerGrid::header()
->showToggleColumns();
if($this->canCreate){
$header->includeViewOnTop('livewire.admin.user-header');
$header->includeViewOnTop('livewire.forms.headers.user');
}
$actions[]=$header;
$actions[]=PowerGrid::footer()->showPerPage()->showRecordCount();
@ -239,14 +239,14 @@ final class UserTable extends PowerGridComponent
->slot(__('users.edit'))
->icon('solid-pencil-square')
->class('inline-flex items-center gap-1 px-3 py-1 rounded ')
->dispatchTo('admin.user-form', 'openModal', ['id' => $row->id]);
->dispatchTo('forms.user-form', 'openModal', ['id' => $row->id]);
}
if($this->canDelect){
$actions[]=Button::add('delete')
->slot(__('users.delete'))
->icon('solid-trash')
->class('inline-flex items-center gap-1 px-3 py-1 rounded ')
->dispatchTo('admin.user-form', 'deleteUser', ['id' => $row->id]);
->dispatchTo('forms.user-form', 'deleteUser', ['id' => $row->id]);
}
return $actions;
}

View File

@ -14,6 +14,8 @@ return [
'birthday' => '生日',
'status' => '狀態',
'role' =>'角色',
'password' => '密碼',
'password_confirmation' => '確認密碼',
'select_gender'=>'選擇性別',
'select_status'=>'選擇狀態',

View File

@ -1,4 +1,4 @@
<x-layouts.admin>
<livewire:admin.activity-log-table />
<livewire:tables.activity-log-table />
</x-layouts.admin>

View File

@ -1,7 +1,7 @@
<x-layouts.admin>
<x-wireui:notifications/>
<livewire:admin.artist-table />
<livewire:admin.artist-form />
<livewire:admin.artist-import-data />
<livewire:tables.artist-table />
<livewire:forms.artist-form />
<livewire:forms.import-datas.artist />
</x-layouts.admin>

View File

@ -1,8 +1,8 @@
<x-layouts.admin>
<x-wireui:notifications/>
<livewire:admin.branch-table />
<livewire:admin.room-grid />
<livewire:admin.branch-form />
<livewire:admin.branch-import-data />
<livewire:tables.branch-table />
<livewire:grids.room-grid />
<livewire:forms.branch-form />
<livewire:forms.import-datas.branch />
</x-layouts.admin>

View File

@ -1,6 +1,6 @@
<x-layouts.admin>
<x-wireui:notifications/>
<livewire:admin.role-table />
<livewire:admin.role-form />
<livewire:tables.role-table />
<livewire:forms.role-form />
</x-layouts.admin>

View File

@ -1,7 +1,7 @@
<x-layouts.admin>
<x-wireui:notifications/>
<livewire:admin.song-table />
<livewire:admin.song-form />
<livewire:admin.song-import-data />
<livewire:tables.song-table />
<livewire:forms.song-form />
<livewire:forms.import-datas.song />
</x-layouts.admin>

View File

@ -1,6 +1,6 @@
<x-layouts.admin>
<x-wireui:notifications/>
<livewire:admin.user-table />
<livewire:admin.user-form />
<livewire:tables.user-table />
<livewire:forms.user-form />
</x-layouts.admin>

View File

@ -1,13 +1,13 @@
<x-admin.section-header title="{{ __('artists.list') }}">
<x-wireui:button
wire:click="$dispatchTo('admin.artist-form', 'openModal')"
wire:click="$dispatchTo('forms.artist-form', 'openModal')"
icon="plus"
label="{{ __('artists.CreateNew') }}"
class="bg-blue-600 text-white"
/>
<x-wireui:button
wire:click="$dispatchTo('admin.artist-import-data','openModal')"
wire:click="$dispatchTo('forms.import-datas.artist','openModal')"
icon="document-plus"
label="{{ __('artists.ImportData') }}"
class="bg-green-600 text-white"

View File

@ -1,13 +1,13 @@
<x-admin.section-header title="{{ __('branches.list') }}">
<x-wireui:button
wire:click="$dispatchTo('admin.branch-form', 'openModal')"
wire:click="$dispatchTo('forms.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')"
wire:click="$dispatchTo('forms.import-datas.branch','openModal')"
icon="document-plus"
label="{{ __('branches.ImportData') }}"
class="bg-green-600 text-white"

View File

@ -1,6 +1,6 @@
<x-admin.section-header title="{{ __('roles.list') }}">
<x-wireui:button
wire:click="$dispatchTo('admin.role-form', 'openCreateRoleModal')"
wire:click="$dispatchTo('forms.role-form', 'openCreateRoleModal')"
icon="plus"
label="{{ __('roles.CreateNew') }}"
class="bg-blue-600 text-white"

View File

@ -1,13 +1,13 @@
<x-admin.section-header title="{{ __('songs.list') }}">
<x-wireui:button
wire:click="$dispatchTo('admin.song-form', 'openModal')"
wire:click="$dispatchTo('forms.song-form', 'openModal')"
icon="plus"
label="{{ __('songs.CreateNew') }}"
class="bg-blue-600 text-white"
/>
<x-wireui:button
wire:click="$dispatchTo('admin.song-import-data','openModal')"
wire:click="$dispatchTo('forms.import-datas.song','openModal')"
icon="document-plus"
label="{{ __('songs.ImportData') }}"
class="bg-green-600 text-white"

View File

@ -0,0 +1,8 @@
<x-admin.section-header title="{{ __('text_ads.list') }}">
<x-wireui:button
wire:click="$dispatchTo('forms.text-ads-form', 'openModal')"
icon="plus"
label="{{ __('text_ads.CreateNew') }}"
class="bg-blue-600 text-white"
/>
</x-admin.section-header>

View File

@ -1,6 +1,6 @@
<x-admin.section-header title="{{ __('users.list') }}">
<x-wireui:button
wire:click="$dispatchTo('admin.user-form', 'openModal')"
wire:click="$dispatchTo('forms.user-form', 'openModal')"
icon="plus"
label="{{ __('users.CreateNew') }}"
class="bg-blue-600 text-white"

View File

@ -29,6 +29,21 @@
option-value="value"
:options="$rolesOptions->map(fn($p) => ['value' => $p->id, 'label' => $p->name])->toArray()"
/>
@if (!$userId)
<x-wireui:input
label="{{ __('users.password') }}"
wire:model.defer="fields.password"
type="password"
required
/>
<x-wireui:input
label="{{ __('users.password_confirmation') }}"
wire:model.defer="fields.password_confirmation"
type="password"
required
/>
@endif
</div>
<x-slot name="footer">

View File

@ -1,4 +1,4 @@
<x-wireui:modal id="room-detail-modal" wire:model.defer="showModal" persistent>
<x-wireui:modal id="room-modal" wire:model.defer="showModal" persistent>
<x-wireui:card class="border border-gray-200">
<x-slot name="action">
<button class="cursor-pointer p-1 rounded-full focus:outline-none focus:outline-hidden focus:ring-2 focus:ring-secondary-200 text-secondary-300"

View File

@ -54,6 +54,6 @@
</div>
</div>
<livewire:admin.room-detail-modal />
<livewire:grids.modals.room-detail-modal />
</x-wireui:card>
</x-wireui:modal>