feat: crud user

This commit is contained in:
Yoga Pangestu 2024-11-24 16:02:21 +07:00
parent 1ff72959b6
commit 0cea04e147
8 changed files with 878 additions and 13 deletions

View File

@ -0,0 +1,175 @@
<?php
namespace App\Http\Controllers\Admin\Master;
use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\Master\UserRequest;
use App\Models\Barbershop;
use App\Models\Biography;
use App\Models\Role;
use App\Models\User;
use App\Traits\UploadAttachment;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
class UserController extends Controller
{
use UploadAttachment;
public function index(): View
{
return view('pages.admin.master.user.index', [
'pageTitle' => 'Pengguna',
'users' => User::latest()->get(),
]);
}
public function create(): View
{
return view('pages.admin.master.user.create', [
'pageTitle' => 'Tambah Pengguna',
'roles' => Role::latest()->get(),
'barbershop' => Barbershop::latest()->get(),
]);
}
public function store(UserRequest $request): RedirectResponse
{
$validatedData = $request->validated();
DB::transaction(function () use ($validatedData) {
$newUser = User::create(array_merge($validatedData, [
'role_id' => $validatedData['role'],
'barbershop_id' => $validatedData['barbershop'],
'password' => Hash::make(env('PASSWORD_DEFAULT_USER')),
]));
Biography::create(array_merge($validatedData, [
'user_id' => $newUser->id,
]), $validatedData);
$this->uploadAttachment($validatedData['avatar'], 'users', User::class, $newUser->id);
});
notify()->success('Data berhasil ditambahkan', 'Berhasil');
return redirect('dashboard/master/users');
}
public function edit(User $user): View
{
return view('pages.admin.master.user.edit', [
'pageTitle' => 'Edit Pengguna',
'roles' => Role::latest()->get(),
'barbershop' => Barbershop::latest()->get(),
'user' => $user,
]);
}
public function update(User $user, UserRequest $request): RedirectResponse
{
$validatedData = $request->validated();
DB::transaction(function () use ($validatedData, $user) {
$user->update(array_merge($validatedData, [
'role_id' => $validatedData['role'],
'barbershop_id' => $validatedData['barbershop'],
]));
$biographyData = collect($validatedData)
->except([
'email',
'username',
'role',
'barbershop',
'entry_date',
'base_salary',
'sop',
'avatar',
])
->toArray();
$user->biography()->update($biographyData);
if (isset($validatedData['avatar'])) {
$this->uploadAttachment($validatedData['avatar'], 'users', User::class, $user->id);
}
});
notify()->success('Data berhasil ditambahkan', 'Berhasil');
return redirect('dashboard/master/users');
}
public function delete(User $user): RedirectResponse
{
if (Auth::id() === $user->id) {
notify()->info('Ini adalah akun Anda, Anda tidak dapat menghapus akun ini', 'Informasi');
return back();
}
$user->delete();
notify()->success('Data berhasil dihapus', 'Berhasil');
return back();
}
public function resetPassword(User $user): RedirectResponse
{
$user->update([
'password' => Hash::make(env('PASSWORD_DEFAULT_USER')),
]);
notify()->success('Kata sandi berhasil direset menjadi '.env('PASSWORD_DEFAULT_USER'), 'Berhasil');
return back();
}
public function activation(User $user): RedirectResponse
{
if (Auth::id() === $user->id) {
notify()->info('Ini adalah akun Anda, Anda tidak dapat monaktifkannya akun ini', 'Informasi');
return back();
}
$user->update([
'is_active' => $user->is_active === '1' ? '0' : '1',
]);
notify()->success('Status berhasil diubah', 'Berhasil');
return back();
}
public function generateActionButtons(User $user): string
{
$editUrl = route('master.user.edit', encryptId($user->id));
$deleteUrl = route('master.user.delete', encryptId($user->id));
return '
<div class="nk-tb-col nk-tb-col-tools">
<ul class="nk-tb-actions gx-1 my-n1">
<li>
<div class="drodown">
<a href="#" class="dropdown-toggle btn btn-icon btn-trigger me-n1" data-bs-toggle="dropdown"><em class="icon ni ni-more-h"></em></a>
<div class="dropdown-menu dropdown-menu-end">
<ul class="link-list-opt no-bdr">
<li>
<a href="'.$editUrl.'">
<em class="icon ni ni-edit"></em>
<span>Edit</span>
</a>
</li>
<li>
<form action="'.$deleteUrl.'" method="post">
'.csrf_field().'
'.method_field('delete').'
<a href="javascript:void(0)" class="delete"><em class="icon ni ni-trash"></em><span>Hapus</span></a>
</form>
</li>
</ul>
</div>
</div>
</li>
</ul>
</div>';
}
}

View File

@ -0,0 +1,56 @@
<?php
namespace App\Http\Requests\Admin\Master;
use App\Traits\NotificationTrait;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\Rule;
class UserRequest extends FormRequest
{
use NotificationTrait;
public function authorize(): bool
{
return Auth::check();
}
protected function prepareForValidation(): void
{
$this->merge([
'base_salary' => removeRupiahFormatting($this->base_salary),
]);
}
public function rules(): array
{
$userId = $this->user->id ?? null;
$isEdit = $this->isMethod('put');
return [
'full_name' => ['required', 'string', 'max:255'],
'username' => ['required', 'string', 'min:5', 'max:15', Rule::unique('users', 'username')->ignore($userId)],
'email' => ['required', 'email', 'max:255', Rule::unique('users', 'email')->ignore($userId)],
'contact_number' => ['required', 'string', 'regex:/^\+?[0-9]{10,15}$/'],
'pob' => ['required', 'string', 'max:75'],
'dob' => ['required', 'date', 'before:today'],
'entry_date' => ['required', 'date'],
'base_salary' => ['required', 'numeric', 'min:0', 'max:9999999999.99'],
'sop' => ['nullable', 'string', 'max:65535'],
'address' => ['required', 'string', 'max:65535'],
'avatar' => $isEdit
? ['nullable', 'image', 'mimes:jpeg,png,jpg,gif,svg', 'max:2048']
: ['required', 'image', 'mimes:jpeg,png,jpg,gif,svg', 'max:2048'],
'gender' => ['required', Rule::in(['1', '2'])],
'barbershop' => ['required', Rule::exists('barbershop', 'id')],
'role' => ['required', Rule::exists('roles', 'id')],
];
}
protected function failedValidation(Validator $validator): void
{
$this->handleValidationFailure($validator);
}
}

View File

@ -3,6 +3,9 @@
namespace App\Models;
// use Illuminate\Contracts\Auth\MustVerifyEmail;
use App\Observers\UserObserver;
use Illuminate\Database\Eloquent\Attributes\ObservedBy;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
@ -12,6 +15,7 @@
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
#[ObservedBy([UserObserver::class])]
class User extends Authenticatable
{
use HasFactory, Notifiable, SoftDeletes;
@ -25,6 +29,7 @@ class User extends Authenticatable
'base_salary',
'sop',
'is_active',
'entry_date',
];
public function role(): BelongsTo

View File

@ -19,16 +19,15 @@ class UserSeeder extends Seeder
public function run(): void
{
DB::transaction(function () {
// Create a new user
$newUser = User::create([
'role_id' => 1,
'barbershop_id' => 1,
'username' => 'yoga',
'email' => 'yoga@developer.com',
'password' => Hash::make(env('PASSWORD_DEFAULT_USER')),
'entry_date' => now(),
]);
// Create biography for the user
Biography::create([
'user_id' => $newUser->id,
'full_name' => 'Yoga Pangestu',
@ -36,21 +35,16 @@ public function run(): void
'dob' => '2000-01-01',
'contact_number' => '082121495806',
'address' => 'Jl.Babaru Nagri',
'gender' => 1,
'gender' => '1',
]);
// Path to the image file
$imagePath = public_path('assets/admin/images/avatar/speed.jpeg');
// Check if the file exists
if (file_exists($imagePath)) {
// Create a Symfony file instance
$file = new \Symfony\Component\HttpFoundation\File\File($imagePath);
// Generate a unique file name
$fileName = Str::uuid().'.'.$file->getExtension();
$fileName = Str::uuid();
// Create an attachment record
Attachment::create([
'attachmentable_id' => $newUser->id,
'attachmentable_type' => User::class,
@ -59,11 +53,9 @@ public function run(): void
'size' => $file->getSize(),
]);
// Define the storage path for avatars
$path = 'avatars/'.now()->format('Y-m-d');
$path = 'users/'.now()->format('Y-m-d');
// Store the file in the defined path using Storage facade
Storage::disk('public')->putFileAs($path, $file, $fileName);
Storage::disk('public')->putFileAs($path, $file, $fileName.'.'.$file->getExtension());
}
});
}

View File

@ -0,0 +1,219 @@
@extends('layouts.admin')
@section('styles')
<link rel="stylesheet" type="text/css" href="{{ asset('assets/admin/css/vendors/flatpickr/flatpickr.min.css') }}">
<link rel="stylesheet" href="{{ asset('assets/admin/css/vendors/select2.css') }}">
@endsection
@section('app')
<div class="container-fluid">
<div class="list-product-header">
<div>
<a class="btn btn-dark" href="{{ route('master.users') }}">Kembali</a>
</div>
</div>
<div class="card">
<div class="card-body">
<form class="row g-3 custom-input" action="{{ route('master.user.store') }}" method="post"
enctype="multipart/form-data">
@csrf
<div class="col-lg-6 position-relative">
<label class="form-label" for="full_name">Nama Lengkap</label>
<input name="full_name" class="form-control @error('full_name') is-invalid @enderror" id="full_name"
type="text" placeholder="Masukan Nama Lengkap" value="{{ old('full_name') }}">
@error('full_name')
<div class="invalid-feedback">
{{ $message }}
</div>
@enderror
</div>
<div class="col-lg-6 position-relative">
<label class="form-label" for="username">Nama Pengguna</label>
<input name="username" class="form-control @error('username') is-invalid @enderror" id="username"
type="text" placeholder="Masukan Nama Pengguna" value="{{ old('username') }}">
@error('username')
<div class="invalid-feedback">
{{ $message }}
</div>
@enderror
</div>
<div class="col-lg-6 position-relative">
<label class="form-label" for="email">Email</label>
<input name="email" class="form-control @error('email') is-invalid @enderror" id="email"
type="text" placeholder="Masukan Email" value="{{ old('email') }}">
@error('email')
<div class="invalid-feedback">
{{ $message }}
</div>
@enderror
</div>
<div class="col-lg-6 position-relative">
<label class="form-label" for="contact_number">Kontak
<span class="form-span"><i>(format : 08xxxxxxxx)</i></span>
</label>
<input name="contact_number" class="form-control @error('contact_number') is-invalid @enderror"
id="contact_number" type="number" placeholder="Masukan Kontak"
value="{{ old('contact_number') }}">
@error('contact_number')
<div class="invalid-feedback">
{{ $message }}
</div>
@enderror
</div>
<div class="col-lg-6 position-relative">
<label class="form-label" for="pob">Tempat Lahir</label>
<input name="pob" class="form-control @error('pob') is-invalid @enderror" id="pob"
type="text" placeholder="Masukan Tempat Lahir" value="{{ old('pob') }}">
@error('pob')
<div class="invalid-feedback">
{{ $message }}
</div>
@enderror
</div>
<div class="col-lg-6 position-relative">
<label class="form-label" for="dob">Tanggal Lahir</label>
<div class="input-group flatpicker-calender">
<input name="dob" class="form-control @error('dob') is-invalid @enderror human-friendly"
id="dob" type="date" placeholder="Masukan Tanggal Lahir"
value="{{ old('dob') }}">
</div>
@error('dob')
<div class="invalid-feedback">
{{ $message }}
</div>
@enderror
</div>
<div class="col-lg-6 position-relative">
<label class="form-label" for="entry_date">Tanggal Bekerja</label>
<div class="input-group flatpicker-calender">
<input name="entry_date"
class="form-control @error('entry_date') is-invalid @enderror human-friendly"
id="entry_date" type="date" placeholder="Masukan Tanggal Bekerja"
value="{{ old('entry_date') }}">
</div>
@error('entry_date')
<div class="invalid-feedback">
{{ $message }}
</div>
@enderror
</div>
<div class="col-lg-6 position-relative">
<label class="form-label" for="base_salary">Gaji Pokok</label>
<input name="base_salary"
class="form-control rupiah-format @error('base_salary') is-invalid @enderror" id="base_salary"
type="text" placeholder="Masukan Gaji Pokok" value="{{ old('base_salary') }}"
inputmode="numeric">
@error('base_salary')
<div class="invalid-feedback">
{{ $message }}
</div>
@enderror
</div>
<div class="col-lg-6 position-relative">
<label class="form-label" for="sop">SOP
<span class="form-span"><i>(Opsional)</i></span>
</label>
<textarea name="sop" class="form-control @error('sop') is-invalid @enderror" id="sop" rows="3"
placeholder="Masukan SOP">{{ old('sop') }}</textarea>
@error('sop')
<div class="invalid-feedback">
{{ $message }}
</div>
@enderror
</div>
<div class="col-lg-6 position-relative">
<label class="form-label" for="address">Alamat</label>
<textarea name="address" class="form-control @error('address') is-invalid @enderror" id="address" rows="3"
placeholder="Masukan Alamat">{{ old('address') }}</textarea>
@error('address')
<div class="invalid-feedback">
{{ $message }}
</div>
@enderror
</div>
<div class="col-lg-6 position-relative">
<label class="form-label" for="avatar">Avatar
<span class="form-span"><i>(.jpeg,.png,.jpg,.gif,.svg)</i></span>
</label>
<input name="avatar" class="form-control @error('avatar') is-invalid @enderror" id="avatar"
type="file" value="{{ old('avatar') }}"
accept="image/jpeg,image/png,image/jpg,image/gif,image/svg">
@error('avatar')
<div class="invalid-feedback">
{{ $message }}
</div>
@enderror
</div>
<div class="col-lg-6 position-relative">
<label class="form-label" for="gender">Jenis Kelamin
</label>
<select name="gender" class="form-control @error('gender') is-invalid @enderror select2"
id="gender">
<option value=""></option>
<option value="1" @selected(old('gender') == '1')>Laki-laki</option>
<option value="2" @selected(old('gender') == '2')>Perempuan</option>
</select>
@error('gender')
<div class="invalid-feedback">
{{ $message }}
</div>
@enderror
</div>
<div class="col-lg-6 position-relative">
<label class="form-label" for="barbershop">Barbershop
</label>
<select name="barbershop" class="form-control @error('barbershop') is-invalid @enderror select2"
id="barbershop">
<option value=""></option>
@foreach ($barbershop as $item)
<option value="{{ $item->id }}" @selected(old('barbershop') == $item->id)>
{{ $item->name }}
</option>
@endforeach
</select>
@error('barbershop')
<div class="invalid-feedback">
{{ $message }}
</div>
@enderror
</div>
<div class="col-lg-6 position-relative">
<label class="form-label" for="role">Role
</label>
<select name="role" class="form-control @error('role') is-invalid @enderror select2"
id="role">
<option value=""></option>
@foreach ($roles as $role)
<option value="{{ $role->id }}" @selected(old('role') == $role->id)>
{{ $role->name }}
</option>
@endforeach
</select>
@error('role')
<div class="invalid-feedback">
{{ $message }}
</div>
@enderror
</div>
<div class="col-12">
<button class="btn btn-primary button-disable" type="submit">Simpan</button>
</div>
</form>
</div>
</div>
</div>
@endsection
@section('beforeScripts')
<script src="{{ asset('assets/admin/js/flat-pickr/flatpickr.js?ver=1.0.0') }}"></script>
<script src="{{ asset('assets/admin/js/flat-pickr/custom-flatpickr.js?ver=1.0.0') }}"></script>
<script src="{{ asset('assets/admin/js/select2/tagify.js?ver=1.0.0') }}"></script>
<script src="{{ asset('assets/admin/js/select2/tagify.polyfills.min.js?ver=1.0.0') }}"></script>
<script src="{{ asset('assets/admin/js/select2/intltelinput.min.js?ver=1.0.0') }}"></script>
<script src="{{ asset('assets/admin/js/select2/telephone-input.js?ver=1.0.0') }}"></script>
<script src="{{ asset('assets/admin/js/select2/custom-inputsearch.js?ver=1.0.0') }}"></script>
<script src="{{ asset('assets/admin/js/select2/select3-custom.js?ver=1.0.0') }}"></script>
@endsection
@section('afterScripts')
<script src="{{ asset('assets/js/forms/button-disable.js?ver=1.0.0') }}"></script>
<script src="{{ asset('assets/js/forms/rupiah-format.js?ver=1.0.0') }}"></script>
<script src="{{ asset('assets/admin/js/select2/select2.js') }}"></script>
<script src="{{ asset('assets/admin/js/select2/select2-config.js?ver=1.0.0') }}"></script>
@endsection

View File

@ -0,0 +1,222 @@
@extends('layouts.admin')
@section('styles')
<link rel="stylesheet" type="text/css" href="{{ asset('assets/admin/css/vendors/flatpickr/flatpickr.min.css') }}">
<link rel="stylesheet" href="{{ asset('assets/admin/css/vendors/select2.css') }}">
@endsection
@section('app')
<div class="container-fluid">
<div class="list-product-header">
<div>
<a class="btn btn-dark" href="{{ route('master.users') }}">Kembali</a>
</div>
</div>
<div class="card">
<div class="card-body">
<form class="row g-3 custom-input" action="{{ route('master.user.update', encryptId($user->id)) }}"
method="post" enctype="multipart/form-data">
@csrf
@method('put')
<div class="col-lg-6 position-relative">
<label class="form-label" for="full_name">Nama Lengkap</label>
<input name="full_name" class="form-control @error('full_name') is-invalid @enderror" id="full_name"
type="text" placeholder="Masukan Nama Lengkap"
value="{{ old('full_name', $user->biography->full_name) }}">
@error('full_name')
<div class="invalid-feedback">
{{ $message }}
</div>
@enderror
</div>
<div class="col-lg-6 position-relative">
<label class="form-label" for="username">Nama Pengguna</label>
<input name="username" class="form-control @error('username') is-invalid @enderror" id="username"
type="text" placeholder="Masukan Nama Pengguna"
value="{{ old('username', $user->username) }}">
@error('username')
<div class="invalid-feedback">
{{ $message }}
</div>
@enderror
</div>
<div class="col-lg-6 position-relative">
<label class="form-label" for="email">Email</label>
<input name="email" class="form-control @error('email') is-invalid @enderror" id="email"
type="text" placeholder="Masukan Email" value="{{ old('email', $user->email) }}">
@error('email')
<div class="invalid-feedback">
{{ $message }}
</div>
@enderror
</div>
<div class="col-lg-6 position-relative">
<label class="form-label" for="contact_number">Kontak
<span class="form-span"><i>(format : 08xxxxxxxx)</i></span>
</label>
<input name="contact_number" class="form-control @error('contact_number') is-invalid @enderror"
id="contact_number" type="number" placeholder="Masukan Kontak"
value="{{ old('contact_number', $user->biography->contact_number) }}">
@error('contact_number')
<div class="invalid-feedback">
{{ $message }}
</div>
@enderror
</div>
<div class="col-lg-6 position-relative">
<label class="form-label" for="pob">Tempat Lahir</label>
<input name="pob" class="form-control @error('pob') is-invalid @enderror" id="pob"
type="text" placeholder="Masukan Tempat Lahir"
value="{{ old('pob', $user->biography->pob) }}">
@error('pob')
<div class="invalid-feedback">
{{ $message }}
</div>
@enderror
</div>
<div class="col-lg-6 position-relative">
<label class="form-label" for="dob">Tanggal Lahir</label>
<div class="input-group flatpicker-calender">
<input name="dob" class="form-control @error('dob') is-invalid @enderror human-friendly"
id="dob" type="date" placeholder="Masukan Tanggal Lahir"
value="{{ old('dob', $user->biography->dob) }}">
</div>
@error('dob')
<div class="invalid-feedback">
{{ $message }}
</div>
@enderror
</div>
<div class="col-lg-6 position-relative">
<label class="form-label" for="entry_date">Tanggal Bekerja</label>
<div class="input-group flatpicker-calender">
<input name="entry_date"
class="form-control @error('entry_date') is-invalid @enderror human-friendly"
id="entry_date" type="date" placeholder="Masukan Tanggal Bekerja"
value="{{ old('entry_date', $user->entry_date) }}">
</div>
@error('entry_date')
<div class="invalid-feedback">
{{ $message }}
</div>
@enderror
</div>
<div class="col-lg-6 position-relative">
<label class="form-label" for="base_salary">Gaji Pokok</label>
<input name="base_salary"
class="form-control rupiah-format @error('base_salary') is-invalid @enderror" id="base_salary"
type="text" placeholder="Masukan Gaji Pokok" value="{{ old('base_salary',formatToRupiah($user->base_salary)) }}" inputmode="numeric">
@error('base_salary')
<div class="invalid-feedback">
{{ $message }}
</div>
@enderror
</div>
<div class="col-lg-6 position-relative">
<label class="form-label" for="sop">SOP
<span class="form-span"><i>(Opsional)</i></span>
</label>
<textarea name="sop" class="form-control @error('sop') is-invalid @enderror" id="sop" rows="3"
placeholder="Masukan SOP">{{ old('sop',$user->sop) }}</textarea>
@error('sop')
<div class="invalid-feedback">
{{ $message }}
</div>
@enderror
</div>
<div class="col-lg-6 position-relative">
<label class="form-label" for="address">Alamat</label>
<textarea name="address" class="form-control @error('address') is-invalid @enderror" id="address" rows="3"
placeholder="Masukan Alamat">{{ old('address',$user->biography->address) }}</textarea>
@error('address')
<div class="invalid-feedback">
{{ $message }}
</div>
@enderror
</div>
<div class="col-lg-6 position-relative">
<label class="form-label" for="avatar">Avatar
<span class="form-span"><i>(.jpeg,.png,.jpg,.gif,.svg, Opsional)</i></span>
</label>
<input name="avatar" class="form-control @error('avatar') is-invalid @enderror" id="avatar"
type="file" value="{{ old('avatar') }}"
accept="image/jpeg,image/png,image/jpg,image/gif,image/svg">
@error('avatar')
<div class="invalid-feedback">
{{ $message }}
</div>
@enderror
</div>
<div class="col-lg-6 position-relative">
<label class="form-label" for="gender">Jenis Kelamin
</label>
<select name="gender" class="form-control @error('gender') is-invalid @enderror select2"
id="gender">
<option value=""></option>
<option value="1" @selected($user->biography->gender == '1')>Laki-laki</option>
<option value="2" @selected($user->biography->gender == '2')>Perempuan</option>
</select>
@error('gender')
<div class="invalid-feedback">
{{ $message }}
</div>
@enderror
</div>
<div class="col-lg-6 position-relative">
<label class="form-label" for="barbershop">Barbershop
</label>
<select name="barbershop" class="form-control @error('barbershop') is-invalid @enderror select2"
id="barbershop">
<option value=""></option>
@foreach ($barbershop as $item)
<option value="{{ $item->id }}" @selected($user->barbershop_id == $item->id)>
{{ $item->name }}
</option>
@endforeach
</select>
@error('barbershop')
<div class="invalid-feedback">
{{ $message }}
</div>
@enderror
</div>
<div class="col-lg-6 position-relative">
<label class="form-label" for="role">Role
</label>
<select name="role" class="form-control @error('role') is-invalid @enderror select2"
id="role">
<option value=""></option>
@foreach ($roles as $role)
<option value="{{ $role->id }}" @selected($user->role_id == $role->id)>
{{ $role->name }}
</option>
@endforeach
</select>
@error('role')
<div class="invalid-feedback">
{{ $message }}
</div>
@enderror
</div>
<div class="col-12">
<button class="btn btn-primary button-disable" type="submit">Simpan</button>
</div>
</form>
</div>
</div>
</div>
@endsection
@section('beforeScripts')
<script src="{{ asset('assets/admin/js/flat-pickr/flatpickr.js?ver=1.0.0') }}"></script>
<script src="{{ asset('assets/admin/js/flat-pickr/custom-flatpickr.js?ver=1.0.0') }}"></script>
<script src="{{ asset('assets/admin/js/select2/tagify.js?ver=1.0.0') }}"></script>
<script src="{{ asset('assets/admin/js/select2/tagify.polyfills.min.js?ver=1.0.0') }}"></script>
<script src="{{ asset('assets/admin/js/select2/intltelinput.min.js?ver=1.0.0') }}"></script>
<script src="{{ asset('assets/admin/js/select2/telephone-input.js?ver=1.0.0') }}"></script>
<script src="{{ asset('assets/admin/js/select2/custom-inputsearch.js?ver=1.0.0') }}"></script>
<script src="{{ asset('assets/admin/js/select2/select3-custom.js?ver=1.0.0') }}"></script>
@endsection
@section('afterScripts')
<script src="{{ asset('assets/js/forms/button-disable.js?ver=1.0.0') }}"></script>
<script src="{{ asset('assets/js/forms/rupiah-format.js?ver=1.0.0') }}"></script>
<script src="{{ asset('assets/admin/js/select2/select2.js') }}"></script>
<script src="{{ asset('assets/admin/js/select2/select2-config.js?ver=1.0.0') }}"></script>
@endsection

View File

@ -0,0 +1,184 @@
@extends('layouts.admin')
@section('styles')
<link rel="stylesheet" type="text/css" href="{{ asset('assets/admin/css/vendors/datatables.css') }}">
@endsection
@section('app')
<div class="container-fluid">
<div class="row">
<div class="col-sm-12">
<div class="list-product-header">
<div>
<a class="btn btn-primary" href="{{ route('master.user.create') }}">Tambah</a>
</div>
</div>
<div class="card">
<div class="card-body">
<div class="table-responsive">
<table class="display" id="datatable">
<thead>
<tr>
<th>No</th>
<th>Nama Lengkap</th>
<th>Nama Pengguna</th>
<th>Email</th>
<th>Barbershop</th>
<th>Kontak</th>
<th>Role</th>
<th>Gaji Pokok</th>
<th>Status</th>
<th>Tanggal Bekerja</th>
<th>Aksi</th>
</tr>
</thead>
<tbody>
@foreach ($users as $user)
<tr>
<td>{{ $loop->iteration }}</td>
<td>{{ $user->biography->full_name ?? '-' }}</td>
<td>{{ $user->username }}</td>
<td>{{ $user->email }}</td>
<td>{{ $user->biography->contact_number ?? '-' }}</td>
<td>{{ $user->barbershop->name ?? '-' }}</td>
<td>{{ $user->role->name ?? '-' }}</td>
<td>{{ formatToRupiah($user->base_salary) }}</td>
<td>
{!! $user->is_active === '1'
? '<span class="badge bg-success">Aktif</span>'
: '<span class="badge bg-danger">Tidak Aktif</span>' !!}
</td>
<td>{{ formatDateIndo($user->entry_date) }}</td>
<td>
<ul class="action">
<li class="{{ $user->is_active ? 'nonactivate' : '7366ff' }}">
<a href="javascript:void(0)"
onclick="event.preventDefault(); document.getElementById('activation-form-{{ $user->id }}').submit();"
data-bs-toggle="tooltip" data-bs-placement="left"
data-bs-title="{{ $user->is_active ? 'Nonaktifkan' : 'Aktifkan' }}">
<i data-feather="{{ $user->is_active ? 'x' : 'check' }}"></i>
</a>
<form
action="{{ route('master.user.activation', encryptId($user->id)) }}"
method="post" id="activation-form-{{ $user->id }}"
style="display: none;">
@csrf
@method('put')
</form>
</li>
<li class="reset-password">
<form
action="{{ route('master.user.resetPassword', encryptId($user->id)) }}"
method="post">
@csrf
@method('put')
<a href="javascript:void(0)" class="reset-password"
data-bs-toggle="tooltip" data-bs-placement="left"
data-bs-title="Reset Kata Sandi">
<i data-feather="unlock"></i>
</a>
</form>
</li>
<li class="show">
<a href="javascript:void(0)" data-bs-toggle="modal"
data-bs-target="#showModal" id="tooltipTrigger"
data-full-name="{{ $user->biography->full_name ?? '-' }}"
data-barbershop="{{ $user->barbershop->name ?? '-' }}"
data-pob="{{ $user->biography->pob ?? '-' }}"
data-dob="{{ formatDateIndo($user->biography->dob) ?? '-' }}"
data-address="{{ $user->biography->address ?? '-' }}"
data-gender="{{ $user->biography->gender ?? '-' }}"
data-sop="{{ $user->sop ?? '-' }}"
data-avatar="{{ Storage::url("users/{$user->attachment->formatted_attachment}") }}">
<i data-feather="eye"></i>
</a>
</li>
<li class="edit">
<a href="{{ route('master.user.edit', encryptId($user->id)) }}"
data-bs-toggle="tooltip" data-bs-placement="left"
data-bs-title="Edit">
<i data-feather="edit"></i>
</a>
</li>
<li class="delete">
<form
action="{{ route('master.user.delete', encryptId($user->id)) }}"
method="post">
@csrf
@method('delete')
<a href="javascript:void(0)" class="delete-data"
data-bs-toggle="tooltip" data-bs-placement="left"
data-bs-title="Hapus">
<i data-feather="trash-2"></i>
</a>
</form>
</li>
</ul>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="modal fade" id="showModal" tabindex="-1" role="dialog" aria-labelledby="showModal" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="col-xl-12">
<div class="card social-profile mb-0">
<div class="card-body">
<div class="social-img-wrap">
<div class="social-img">
<img id="user-avatar" src="" alt="profile">
</div>
</div>
<div class="social-details">
<h5 class="mb-1" id="user-name"></h5>
<span class="f-light" id="user-barbershop"></span>
<table class="table table-bordered table-striped table-sm mt-2">
<tbody>
<tr>
<td class="text-start">Tempat Lahir</td>
<td class="text-start">-></td>
<td class="text-start"><span id="user-pob"></span></td>
</tr>
<tr>
<td class="text-start">Tanggal Lahir</td>
<td class="text-start">-></td>
<td class="text-start"><span id="user-dob"></span></td>
</tr>
<tr>
<td class="text-start">Alamat</td>
<td class="text-start">-></td>
<td class="text-start"><span id="user-address"></span></td>
</tr>
<tr>
<td class="text-start">Jenis Kelamin</td>
<td class="text-start">-></td>
<td class="text-start"><span id="user-gender"></span></td>
</tr>
<tr>
<td class="text-start">Sop</td>
<td class="text-start">-></td>
<td class="text-start"><span id="user-sop"></span></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
@endsection
@section('afterScripts')
<script src="{{ asset('assets/admin/js/datatable/jquery.dataTables.min.js?ver=1.0.0') }}"></script>
<script src="{{ asset('assets/admin/js/datatable/client-side.js?ver=1.0.0') }}"></script>
<script src="{{ asset('assets/js/interactions/confirmation.js?ver=1.0.0') }}"></script>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<script src="{{ asset('assets/admin/js/custom/user.js?ver=1.0.0') }}"></script>
@endsection

View File

@ -3,6 +3,7 @@
use App\Http\Controllers\Admin\Auth\LoginController;
use App\Http\Controllers\Admin\Dashboard\OverviewController;
use App\Http\Controllers\Admin\Master\BarbershopController;
use App\Http\Controllers\Admin\Master\UserController;
use Illuminate\Support\Facades\Route;
Route::prefix('auth')->group(function () {
@ -28,5 +29,16 @@
Route::put('update/{barbershop}', [BarbershopController::class, 'update'])->name('master.barbershop.update');
Route::delete('delete/{barbershop}', [BarbershopController::class, 'delete'])->name('master.barbershop.delete');
});
Route::get('/users', [UserController::class, 'index'])->name('master.users');
Route::prefix('user')->group(function () {
Route::get('create', [UserController::class, 'create'])->name('master.user.create');
Route::post('store', [UserController::class, 'store'])->name('master.user.store');
Route::get('edit/{user}', [UserController::class, 'edit'])->name('master.user.edit');
Route::put('update/{user}', [UserController::class, 'update'])->name('master.user.update');
Route::delete('delete/{user}', [UserController::class, 'delete'])->name('master.user.delete');
Route::put('reset-password/{user}', [UserController::class, 'resetPassword'])->name('master.user.resetPassword');
Route::put('activation/{user}', [UserController::class, 'activation'])->name('master.user.activation');
});
});
});