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') +| No | +Nama Lengkap | +Nama Pengguna | +Barbershop | +Kontak | +Role | +Gaji Pokok | +Status | +Tanggal Bekerja | +Aksi | +|
|---|---|---|---|---|---|---|---|---|---|---|
| {{ $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) }} | +
+
|
+