diff --git a/app/Http/Controllers/Admin/Master/UserController.php b/app/Http/Controllers/Admin/Master/UserController.php new file mode 100644 index 0000000..b02b030 --- /dev/null +++ b/app/Http/Controllers/Admin/Master/UserController.php @@ -0,0 +1,175 @@ + '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 ' +
+ +
'; + } +} diff --git a/app/Http/Requests/Admin/Master/UserRequest.php b/app/Http/Requests/Admin/Master/UserRequest.php new file mode 100644 index 0000000..316c91f --- /dev/null +++ b/app/Http/Requests/Admin/Master/UserRequest.php @@ -0,0 +1,56 @@ +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); + } +} diff --git a/app/Models/User.php b/app/Models/User.php index a5be2f3..7aa3173 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -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 diff --git a/database/seeders/UserSeeder.php b/database/seeders/UserSeeder.php index 4545453..5eee23e 100644 --- a/database/seeders/UserSeeder.php +++ b/database/seeders/UserSeeder.php @@ -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()); } }); } diff --git a/resources/views/pages/admin/master/user/create.blade.php b/resources/views/pages/admin/master/user/create.blade.php new file mode 100644 index 0000000..79c4501 --- /dev/null +++ b/resources/views/pages/admin/master/user/create.blade.php @@ -0,0 +1,219 @@ +@extends('layouts.admin') +@section('styles') + + +@endsection +@section('app') +
+
+
+ Kembali +
+
+
+
+
+ @csrf +
+ + + @error('full_name') +
+ {{ $message }} +
+ @enderror +
+
+ + + @error('username') +
+ {{ $message }} +
+ @enderror +
+
+ + + @error('email') +
+ {{ $message }} +
+ @enderror +
+
+ + + @error('contact_number') +
+ {{ $message }} +
+ @enderror +
+
+ + + @error('pob') +
+ {{ $message }} +
+ @enderror +
+
+ +
+ +
+ @error('dob') +
+ {{ $message }} +
+ @enderror +
+
+ +
+ +
+ @error('entry_date') +
+ {{ $message }} +
+ @enderror +
+
+ + + @error('base_salary') +
+ {{ $message }} +
+ @enderror +
+
+ + + @error('sop') +
+ {{ $message }} +
+ @enderror +
+
+ + + @error('address') +
+ {{ $message }} +
+ @enderror +
+
+ + + @error('avatar') +
+ {{ $message }} +
+ @enderror +
+
+ + + @error('gender') +
+ {{ $message }} +
+ @enderror +
+
+ + + @error('barbershop') +
+ {{ $message }} +
+ @enderror +
+
+ + + @error('role') +
+ {{ $message }} +
+ @enderror +
+
+ +
+
+
+
+
+@endsection +@section('beforeScripts') + + + + + + + + +@endsection +@section('afterScripts') + + + + +@endsection diff --git a/resources/views/pages/admin/master/user/edit.blade.php b/resources/views/pages/admin/master/user/edit.blade.php new file mode 100644 index 0000000..c663e3e --- /dev/null +++ b/resources/views/pages/admin/master/user/edit.blade.php @@ -0,0 +1,222 @@ +@extends('layouts.admin') +@section('styles') + + +@endsection +@section('app') +
+
+
+ Kembali +
+
+
+
+
+ @csrf + @method('put') +
+ + + @error('full_name') +
+ {{ $message }} +
+ @enderror +
+
+ + + @error('username') +
+ {{ $message }} +
+ @enderror +
+
+ + + @error('email') +
+ {{ $message }} +
+ @enderror +
+
+ + + @error('contact_number') +
+ {{ $message }} +
+ @enderror +
+
+ + + @error('pob') +
+ {{ $message }} +
+ @enderror +
+
+ +
+ +
+ @error('dob') +
+ {{ $message }} +
+ @enderror +
+
+ +
+ +
+ @error('entry_date') +
+ {{ $message }} +
+ @enderror +
+
+ + + @error('base_salary') +
+ {{ $message }} +
+ @enderror +
+
+ + + @error('sop') +
+ {{ $message }} +
+ @enderror +
+
+ + + @error('address') +
+ {{ $message }} +
+ @enderror +
+
+ + + @error('avatar') +
+ {{ $message }} +
+ @enderror +
+
+ + + @error('gender') +
+ {{ $message }} +
+ @enderror +
+
+ + + @error('barbershop') +
+ {{ $message }} +
+ @enderror +
+
+ + + @error('role') +
+ {{ $message }} +
+ @enderror +
+
+ +
+
+
+
+
+@endsection +@section('beforeScripts') + + + + + + + + +@endsection +@section('afterScripts') + + + + +@endsection diff --git a/resources/views/pages/admin/master/user/index.blade.php b/resources/views/pages/admin/master/user/index.blade.php new file mode 100644 index 0000000..5be8e74 --- /dev/null +++ b/resources/views/pages/admin/master/user/index.blade.php @@ -0,0 +1,184 @@ +@extends('layouts.admin') +@section('styles') + +@endsection +@section('app') +
+
+
+
+
+ Tambah +
+
+
+
+
+ + + + + + + + + + + + + + + + + + @foreach ($users as $user) + + + + + + + + + + + + + + @endforeach + +
NoNama LengkapNama PenggunaEmailBarbershopKontakRoleGaji PokokStatusTanggal BekerjaAksi
{{ $loop->iteration }}{{ $user->biography->full_name ?? '-' }}{{ $user->username }}{{ $user->email }}{{ $user->biography->contact_number ?? '-' }}{{ $user->barbershop->name ?? '-' }}{{ $user->role->name ?? '-' }}{{ formatToRupiah($user->base_salary) }} + {!! $user->is_active === '1' + ? 'Aktif' + : 'Tidak Aktif' !!} + {{ formatDateIndo($user->entry_date) }} + +
+
+
+
+
+
+ + +
+@endsection +@section('afterScripts') + + + + + +@endsection diff --git a/routes/web.php b/routes/web.php index d833e6c..cd7abee 100644 --- a/routes/web.php +++ b/routes/web.php @@ -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'); + }); }); });