You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
184 lines
9.4 KiB
184 lines
9.4 KiB
{{-- resources/views/components/user/manager.blade.php --}}
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<div class="card mb-4">
|
|
{{-- Header --}}
|
|
<div class="card-header d-flex justify-content-between align-items-center pb-0">
|
|
<h6 class="mb-0">{{ $title }}</h6>
|
|
@if ($mode === 'index')
|
|
<div class="d-flex align-items-center">
|
|
<div class="me-2">
|
|
<select wire:model="perPage" wire:change="resetPage"
|
|
class="form-select form-select-sm" style="width:100px;display:inline-block">
|
|
@foreach ($perPageOptions as $opt)
|
|
<option value="{{ $opt }}">{{ $opt }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
<div class="input-group input-group-outline me-2">
|
|
<input type="text"
|
|
wire:model.debounce.500ms="search"
|
|
wire:keydown.enter="resetPage"
|
|
class="form-control form-control-sm"
|
|
placeholder="Search name or email...">
|
|
</div>
|
|
<button wire:click="resetPage"
|
|
class="btn btn-sm btn-outline-success me-2 m-0">
|
|
<i class="fas fa-search"></i>
|
|
</button>
|
|
</div>
|
|
@else
|
|
<button wire:click="showIndex" class="btn btn-sm btn-secondary">
|
|
← Back to list
|
|
</button>
|
|
@endif
|
|
</div>
|
|
|
|
{{-- Body --}}
|
|
<div class="card-body p-3">
|
|
@if (session()->has('message'))
|
|
<div class="alert alert-success">{{ session('message') }}</div>
|
|
@endif
|
|
|
|
@if ($mode === 'index')
|
|
{{-- Skeleton with pagination placeholders --}}
|
|
<x-skeleton-table
|
|
:columns="6"
|
|
:rows="10"
|
|
height="3.5rem"
|
|
:pages="5"
|
|
/>
|
|
|
|
{{-- Actual table --}}
|
|
<div wire:loading.remove class="table-responsive">
|
|
<table class="table table-sm align-middle mb-0">
|
|
<thead>
|
|
<tr style="height:3.5rem">
|
|
<th class="text-center" style="width:5%;">ID</th>
|
|
<th style="width:25%;">Full Name</th>
|
|
<th style="width:30%;">Email</th>
|
|
<th style="width:20%;">Role</th>
|
|
<th style="width:20%;">Phone</th>
|
|
<th class="text-center" style="width:5%;">Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@forelse($users as $u)
|
|
<tr style="height:3.5rem">
|
|
<td class="text-center">{{ $u->id }}</td>
|
|
<td>{{ $u->fullname }}</td>
|
|
<td>{{ $u->email }}</td>
|
|
<td>{{ $u->roles->pluck('name')->join(', ') }}</td>
|
|
<td>{{ $u->phone }}</td>
|
|
<td class="text-center">
|
|
<button wire:click="showForm({{ $u->id }})"
|
|
class="btn btn-sm btn-outline-info me-1">
|
|
Edit
|
|
</button>
|
|
<button x-data
|
|
@click.prevent="if(confirm('Delete user?')){ $wire.delete({{ $u->id }}) }"
|
|
class="btn btn-sm btn-danger">
|
|
Delete
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
@empty
|
|
<tr>
|
|
<td colspan="6" class="text-center">No users found.</td>
|
|
</tr>
|
|
@endforelse
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
{{-- Real pagination --}}
|
|
<div wire:loading.remove class="mt-3">
|
|
@if ($users->lastPage() > 1)
|
|
{{ $users->links() }}
|
|
@endif
|
|
</div>
|
|
@else
|
|
{{-- Form create/edit --}}
|
|
<x-skeleton-form :fields="8" :button-count="2" />
|
|
<div wire:loading.remove>
|
|
<form>
|
|
<div class="mb-3">
|
|
<label class="form-label">Name</label>
|
|
<input type="text"
|
|
wire:model.defer="fullname"
|
|
class="form-control form-control-sm"
|
|
placeholder="fullname">
|
|
@error('fullname')
|
|
<div class="text-danger small">{{ $message }}</div>
|
|
@enderror
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label">Email</label>
|
|
<input type="email"
|
|
wire:model.defer="email"
|
|
class="form-control form-control-sm"
|
|
placeholder="Email">
|
|
@error('email')
|
|
<div class="text-danger small">{{ $message }}</div>
|
|
@enderror
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label">
|
|
Password
|
|
@if ($editingId)
|
|
<small>(leave blank to keep current)</small>
|
|
@endif
|
|
</label>
|
|
<input type="password"
|
|
wire:model.defer="password"
|
|
class="form-control form-control-sm"
|
|
placeholder="Password">
|
|
@error('password')
|
|
<div class="text-danger small">{{ $message }}</div>
|
|
@enderror
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label">Confirm Password</label>
|
|
<input type="password"
|
|
wire:model.defer="password_confirmation"
|
|
class="form-control form-control-sm"
|
|
placeholder="Confirm">
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label">Roles</label>
|
|
<select wire:model.defer="roles"
|
|
multiple
|
|
class="form-select form-select-sm">
|
|
@foreach ($allRoles as $role)
|
|
<option value="{{ $role['name'] }}">{{ ucfirst($role['name']) }}</option>
|
|
@endforeach
|
|
</select>
|
|
@error('roles')
|
|
<div class="text-danger small">{{ $message }}</div>
|
|
@enderror
|
|
</div>
|
|
<div class="d-flex justify-content-end">
|
|
<button type="button"
|
|
wire:click="showIndex"
|
|
class="btn btn-secondary btn-sm me-2">
|
|
Cancel
|
|
</button>
|
|
<button type="button"
|
|
@click.prevent="if(confirm('Do you really want to {{ $editingId ? 'update' : 'create' }} this user?')){ $wire.save() }"
|
|
class="btn btn-primary btn-sm">
|
|
{{ $editingId ? 'Update' : 'Create' }}
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
@script
|
|
<script>
|
|
document.title = @json($title);
|
|
</script>
|
|
@endscript
|
|
</div>
|
|
|