Skip to content

Commit

Permalink
wip create user
Browse files Browse the repository at this point in the history
  • Loading branch information
ikramsyakir committed Jan 18, 2025
1 parent fb1d0a5 commit e8ca134
Show file tree
Hide file tree
Showing 16 changed files with 237 additions and 244 deletions.
27 changes: 7 additions & 20 deletions app/Http/Controllers/UserController.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,31 +22,18 @@

class UserController extends Controller
{
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('permission:read-user')->only('index', 'changeStatus');
$this->middleware('permission:create-user')->only('create', 'store');
$this->middleware('permission:update-user')->only('edit', 'update');
$this->middleware('permission:user-profile')->only('show');
$this->middleware('permission:delete-user')->only('destroy');
$this->middleware('permission:browse-users')->only('index');
$this->middleware('permission:read-users')->only('show');
$this->middleware('permission:edit-users')->only('edit', 'update');
$this->middleware('permission:add-users')->only('create', 'store');
$this->middleware('permission:delete-users')->only('destroy');
}

/**
* Display a listing of the resource.
*
* @return Application|Factory|View
*/
public function index(Request $request)
public function index(): View
{
$users = User::filter($request->all())->sortable()->paginate($request->get('limit') ?? config('app.per_page'));
$roles = Role::pluck('display_name', 'name');

return view('users.index', compact('users', 'roles'));
return view('users.index');
}

/**
Expand Down
146 changes: 146 additions & 0 deletions app/Livewire/Users/UserTable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
<?php

namespace App\Livewire\Users;

use App\Models\Roles\Role;
use App\Models\Users\User;
use Illuminate\Database\Eloquent\Builder;
use Rappasoft\LaravelLivewireTables\DataTableComponent;
use Rappasoft\LaravelLivewireTables\Views\Column;
use Rappasoft\LaravelLivewireTables\Views\Filters\DateRangeFilter;
use Rappasoft\LaravelLivewireTables\Views\Filters\SelectFilter;
use Rappasoft\LaravelLivewireTables\Views\Filters\TextFilter;

class UserTable extends DataTableComponent
{
protected $model = User::class;

protected int $index = 0;

public function configure(): void
{
$this->setPrimaryKey('id')
->setAdditionalSelects(['id', 'avatar'])
->setDefaultSort('created_at', 'desc')
->setSearchDisabled()
->setFilterLayoutSlideDown()
->setColumnSelectStatus(false)
->setToolsAttributes(['class' => 'card-body border-bottom py-3', 'default-styling' => false])
->setTableAttributes([
'default' => false,
'class' => 'table card-table table-vcenter text-nowrap datatable',
])
->setTrAttributes(fn ($row, $index) => ['default' => false, 'class' => 'align-middle'])
->setPaginationWrapperAttributes(['class' => 'card-footer p-3']);
}

public function columns(): array
{
return [
Column::make('#')->label(
fn ($row, Column $column) => ++$this->index + ($this->paginators['page'] - 1) * $this->perPage
),
Column::make(__('messages.name'), 'name')
->sortable()
->view('users.columns.name'),
Column::make(__('messages.email'), 'email')
->sortable(),
Column::make(__('messages.verified'), 'email_verified_at')
->sortable()
->view('users.columns.email_verified_at'),
Column::make(__('messages.roles'), 'role_id')
->label(
fn ($row, Column $column) => view('users.columns.roles')->withRow($row)
),
Column::make(__('messages.created_at'), 'created_at')
->sortable()
->format(
fn ($value, $row, Column $column) => $value->format('d/m/Y h:i A')
),
Column::make(__('messages.updated_at'), 'updated_at')
->sortable()
->format(fn ($value) => $value ? $value->diffForHumans() : '-'),
Column::make(__('messages.actions'))
->label(
fn ($row, Column $column) => view('users.columns.table-actions')->withRow($row)
)
->hideIf(
! auth()->user()->can('read-users') &&
! auth()->user()->can('edit-users') &&
! auth()->user()->can('delete-users')
),
];
}

public function builder(): Builder
{
return User::with('roles');
}

public function filters(): array
{
$statusOptions = to_options([
User::VERIFIED => __('messages.verified'), User::UNVERIFIED => __('messages.unverified'),
]);

$roles = Role::all()->pluck('display_name', 'id')->toArray();
// to_options helper is replacing index of the array
$rolesOptions = ['' => __('messages.all')] + $roles;

return [
TextFilter::make(__('messages.name'), 'name')
->setWireLive()
->config([
'placeholder' => __('messages.search'),
'maxlength' => '25',
])
->filter(function (Builder $builder, string $value) {
$builder->where('name', 'like', '%'.$value.'%');
}),
TextFilter::make(__('messages.email'), 'email')
->setWireLive()
->config([
'placeholder' => __('messages.search'),
'maxlength' => '25',
])
->filter(function (Builder $builder, string $value) {
$builder->where('email', 'like', '%'.$value.'%');
}),
SelectFilter::make(__('messages.verified'), 'email_verified_at')
->setWireLive()
->options($statusOptions)
->filter(function (Builder $builder, string $value) {
if ($value == User::VERIFIED) {
$builder->whereNotNull('email_verified_at');
}

if ($value == User::UNVERIFIED) {
$builder->whereNull('email_verified_at');
}
}),
SelectFilter::make(__('messages.roles'), 'role_id')
->setWireLive()
->options($rolesOptions)
->filter(function (Builder $builder, string $value) {
$builder->whereHas('roles', fn ($query) => $query->where('id', $value));
}),
DateRangeFilter::make(__('messages.created_at'), 'created_at')
->setWireLive()
->config([
'allowInput' => false, // Allow manual input of dates
'altFormat' => 'd/m/Y', // Date format that will be displayed once selected
'ariaDateFormat' => 'd/m/Y', // An aria-friendly date format
])
->filter(function (Builder $builder, array $dateRange) { // Expects an array.
$builder
->whereDate('created_at', '>=', $dateRange['minDate']) // minDate is the start date selected
->whereDate('created_at', '<=', $dateRange['maxDate']); // maxDate is the end date selected
}),
];
}

public function customView(): string
{
return 'partials.livewire-delete-confirmation';
}
}
23 changes: 0 additions & 23 deletions app/ModelFilters/PermissionFilter.php

This file was deleted.

23 changes: 0 additions & 23 deletions app/ModelFilters/RoleFilter.php

This file was deleted.

4 changes: 4 additions & 0 deletions app/Models/Users/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ class User extends Authenticatable implements MustVerifyEmail

const string AVATAR_TYPE_UPLOADED = 'uploaded';

const string VERIFIED = 'verified';

const string UNVERIFIED = 'unverified';

protected $guarded = [];

protected $hidden = [
Expand Down
9 changes: 9 additions & 0 deletions app/helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,12 @@ function set_active(string $routeName): ?string
return Str::startsWith(Route::currentRouteName(), $routeName) ? 'active' : null;
}
}

if (! function_exists('to_options')) {
function to_options(array $array): array
{
return array_merge([
'' => __('messages.all'),
], $array);
}
}
7 changes: 7 additions & 0 deletions lang/en/messages.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,11 @@
'permission_list' => 'Permission List',
'view_permission' => 'View Permission',
'no_role' => 'No Role',
'user_list' => 'User List',
'create_user' => 'Create User',
'verified' => 'Verified',
'yes' => 'Yes',
'no' => 'No',
'all' => 'All',
'unverified' => 'Unverified',
];
13 changes: 10 additions & 3 deletions lang/ms/messages.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@
'cancel' => 'Batal',
'you_wont_be_able_to_revert_this' => 'Anda tidak akan dapat mengembalikan ini',
'create_a_new_role_to_manage_user_permissions' => 'Cipta peranan baru untuk menguruskan kebenaran pengguna',
'role_successfully_created' => 'Perana berjaya dicipta',
'role_successfully_updated' => 'Perana berjaya dikemaskini',
'role_successfully_deleted' => 'Perana berjaya dipadam',
'role_successfully_created' => 'Peranan berjaya dicipta',
'role_successfully_updated' => 'Peranan berjaya dikemaskini',
'role_successfully_deleted' => 'Peranan berjaya dipadam',
'view_role' => 'Lihat Peranan',
'id' => 'ID',
'no_permission' => 'Tiada Kebenaran',
Expand All @@ -73,4 +73,11 @@
'permission_list' => 'Senarai Kebenaran',
'view_permission' => 'Lihat Kebenaran',
'no_role' => 'Tiada Peranan',
'user_list' => 'Senarai Pengguna',
'create_user' => 'Cipta Pengguna',
'verified' => 'Disahkan',
'yes' => 'Ya',
'no' => 'Tidak',
'all' => 'Semua',
'unverified' => 'Tidak Disahkan',
];
5 changes: 5 additions & 0 deletions resources/views/users/columns/email_verified_at.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@if($row->hasVerifiedEmail())
<span class="badge bg-success text-success-fg">{{ __('messages.yes') }}</span>
@else
<span class="badge bg-danger text-danger-fg">{{ __('messages.no') }}</span>
@endif
4 changes: 4 additions & 0 deletions resources/views/users/columns/name.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<div class="d-flex align-items-center py-1">
<span class="avatar avatar-md me-2" style="background-image: url({{ $row->getAvatarPath() }})"></span>
<div class="fw-medium flex-fill">{{ $row->name }}</div>
</div>
5 changes: 5 additions & 0 deletions resources/views/users/columns/roles.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@foreach($row->roles as $role)
<span class="badge bg-primary text-primary-fg @if($row->roles()->count() > 1) 'me-2' @endif">
{{ $role->display_name }}
</span>
@endforeach
26 changes: 26 additions & 0 deletions resources/views/users/columns/table-actions.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<div class="dropdown position-static">
<a role="button" class="btn align-text-top" data-bs-toggle="dropdown" aria-expanded="true">
<i class="fas fa-ellipsis-h text-muted"></i>
</a>
<div class="dropdown-menu dropdown-menu-end" data-popper-placement="bottom-end">
@can('read-users')
<a class="dropdown-item" href="{{ route('users.show', $row->id) }}">
<i class="ti ti-eye me-2"></i>
{{ __('messages.view') }}
</a>
@endcan
@can('edit-users')
<a class="dropdown-item" href="{{ route('users.edit', $row->id) }}">
<i class="ti ti-pencil me-2"></i>
{{ __('messages.edit') }}
</a>
@endcan
@can('delete-users')
<a class="dropdown-item" role="button" wire:click="$dispatch('triggerDelete', {{ $row->id }})">
<i class="ti ti-trash me-2"></i>
{{ __('messages.delete') }}
</a>
@endcan
</div>
</div>

Loading

0 comments on commit e8ca134

Please sign in to comment.