fix(user): kolom email dan username di table dijadikan 1 kolom yaitu Kredensial

-menyesuaikan validasi base_salary dan menghapus toDateString()
-menambahkan dispatch refreshDatatabse saat create
-membuat EmployeeFactory
-menyesuaikan UserFactory dan test
This commit is contained in:
Yoga Pangestu 2025-09-29 17:38:28 +07:00
parent 45b67c3ce4
commit f8935a1c73
8 changed files with 195 additions and 37 deletions

View File

@ -39,12 +39,24 @@ public function columns(): array
});
})
->html(),
Column::make('Kredensial')
->label(function ($row) {
return <<<HTML
<div>
<div>{$row->email}</div>
<span class="text-xs text-gray-400">{$row->username}</span>
</div>
HTML;
})
->searchable(function ($query, $searchTerm) {
$query->where('email', 'like', "%{$searchTerm}%")
->orWhere('username', 'like', "%{$searchTerm}%");
})
->html(),
Column::make('Nomor Telepon', 'employee.phone_number')->searchable(),
Column::make('Email', 'email')->searchable(),
Column::make('Nama Pengguna', 'username')->searchable(),
Column::make('Jenis Kelamin', 'employee.gender')
->format(fn ($value) => Blade::render(
'<flux:badge color="'.Gender::from($value)->color().'">'
@ -56,7 +68,7 @@ public function columns(): array
Column::make('Gaji Pokok', 'employee.base_salary')
->searchable()
->sortable()
->format(fn ($value) => currency($value)),
->format(fn ($value) => currency($value, 'Rp')),
Column::make('Alamat', 'employee.address')->searchable(),

View File

@ -7,6 +7,7 @@
use App\Models\Employee;
use App\Models\User;
use App\Rules\PhoneNumber;
use App\Rules\UnsignedInteger;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
@ -44,7 +45,7 @@ public function rules(): array
'username' => ['required', 'alpha_dash', 'min:5', 'max:20', Rule::unique('users', 'username')->ignore($this->user)],
'email' => ['required', 'email', 'max:100', Rule::unique('users', 'email')->ignore($this->user)],
'phone_number' => ['required', 'string', new PhoneNumber],
'base_salary' => ['required', 'regex:/^[0-9.]+$/', 'max:999999999'],
'base_salary' => ['required', 'regex:/^[0-9.]+$/', new UnsignedInteger],
'birthdate' => ['required', 'date', 'before:'.Carbon::now()->subYears(18)->format('Y-m-d')],
'hire_date' => ['required', 'date'],
'address' => ['required', 'string'],
@ -77,8 +78,8 @@ public function setUser(User $user)
$this->email = $user->email;
$this->phone_number = $employee->phone_number;
$this->base_salary = $employee->base_salary;
$this->birthdate = $employee->birthdate->toDateString();
$this->hire_date = $employee->hire_date->toDateString();
$this->birthdate = $employee->birthdate;
$this->hire_date = $employee->hire_date;
$this->address = $employee->address;
$this->gender = $employee->gender->value;
$this->status = $user->status->value;

View File

@ -19,6 +19,8 @@ public function save()
{
$this->form->store();
$this->dispatch('refreshDatatable');
Flux::toast(
heading: 'Berhasil',
text: 'Pegawai berhasil ditambahkan.',

View File

@ -0,0 +1,31 @@
<?php
namespace Database\Factories;
use App\Enums\EmploymentStatus;
use App\Enums\Gender;
use App\Models\Employee;
use Illuminate\Database\Eloquent\Factories\Factory;
class EmployeeFactory extends Factory
{
public function definition(): array
{
return [
'full_name' => $this->faker->name(),
'code' => Employee::generateEmployeeCode(),
'phone_number' => fake()->randomElement([
fake()->numerify('0812 #### ###'),
fake()->numerify('0812 #### ####'),
fake()->numerify('0812 #### #####'),
]),
'base_salary' => $this->faker->randomNumber(6),
'gender' => $this->faker->randomElement(Gender::cases()),
'address' => $this->faker->address(),
'birthdate' => $this->faker->dateTimeBetween('-60 years', '-18 years')->format('Y-m-d'),
'hire_date' => $this->faker->date(),
'resign_date' => $this->faker->optional()->date(),
'status' => $this->faker->randomElement(EmploymentStatus::cases()),
];
}
}

View File

@ -2,43 +2,19 @@
namespace Database\Factories;
use App\Enums\UserStatus;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\User>
*/
class UserFactory extends Factory
{
/**
* The current password being used by the factory.
*/
protected static ?string $password;
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'name' => fake()->name(),
'email' => fake()->unique()->safeEmail(),
'email_verified_at' => now(),
'password' => static::$password ??= Hash::make('password'),
'remember_token' => Str::random(10),
'email' => $this->faker->unique()->safeEmail(),
'username' => fake()->unique()->regexify('[A-Za-z0-9]{8}'),
'password' => Hash::make(config('myconfig.password_default')),
'status' => $this->faker->randomElement(UserStatus::cases()),
];
}
/**
* Indicate that the model's email address should be unverified.
*/
public function unverified(): static
{
return $this->state(fn (array $attributes) => [
'email_verified_at' => null,
]);
}
}

View File

@ -0,0 +1,45 @@
<?php
use App\Livewire\Studio\Master\User\Create;
use App\Livewire\Studio\Master\User\Index;
use App\Models\Employee;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Livewire;
uses(RefreshDatabase::class);
it('renders successfully', function () {
Livewire::test(Create::class)
->assertViewIs('livewire.studio.master.user.form')
->assertViewHas('pageTitle', 'Tambah Pegawai');
});
it('can create an user', function () {
$user = User::factory()->raw();
$employee = Employee::factory()->raw();
$data = array_merge($user, $employee);
Livewire::test(Create::class)
->set('form.full_name', $data['full_name'])
->set('form.username', $data['username'])
->set('form.email', $data['email'])
->set('form.phone_number', $data['phone_number'])
->set('form.base_salary', $data['base_salary'])
->set('form.birthdate', $data['birthdate'])
->set('form.hire_date', $data['hire_date'])
->set('form.address', $data['address'])
->set('form.gender', $data['gender']->value)
->set('form.status', $data['status']->value)
->call('save')
->assertHasNoErrors()
->assertDispatched('refreshDatatable')
->assertRedirect(Index::class);
$this->assertDatabaseHas('users', [
'email' => $data['email'],
'username' => $data['username'],
]);
});

View File

@ -0,0 +1,53 @@
<?php
use App\Livewire\Studio\Master\User\Edit;
use App\Livewire\Studio\Master\User\Index;
use App\Models\Employee;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Livewire;
uses(RefreshDatabase::class);
it('renders successfully', function () {
$user = User::factory()
->has(Employee::factory())
->create();
Livewire::test(Edit::class, ['user' => $user])
->assertViewIs('livewire.studio.master.user.form')
->assertViewHas('pageTitle', 'Ubah Pegawai');
});
it('can update an user', function () {
$existingUser = User::factory()
->has(Employee::factory())
->create();
$user = User::factory()->raw();
$employee = Employee::factory()->raw();
$data = array_merge($user, $employee);
Livewire::test(Edit::class, ['user' => $existingUser])
->set('form.full_name', $data['full_name'])
->set('form.username', $data['username'])
->set('form.email', $data['email'])
->set('form.phone_number', $data['phone_number'])
->set('form.base_salary', $data['base_salary'])
->set('form.birthdate', $data['birthdate'])
->set('form.hire_date', $data['hire_date'])
->set('form.address', $data['address'])
->set('form.gender', $data['gender']->value)
->set('form.status', $data['status']->value)
->call('save')
->assertHasNoErrors()
->assertDispatched('refreshDatatable')
->assertRedirect(Index::class);
$this->assertDatabaseHas('users', [
'id' => $existingUser->id,
'email' => $data['email'],
'username' => $data['username'],
]);
});

View File

@ -0,0 +1,38 @@
<?php
use App\Livewire\Studio\Master\User\Index;
use App\Models\Employee;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Livewire;
uses(RefreshDatabase::class);
it('renders successfully', function () {
Livewire::test(Index::class)
->assertViewIs('livewire.studio.master.user.index')
->assertViewHas('pageTitle', 'Pegawai');
});
it('displays all users', function () {
User::factory()
->count(10)
->has(Employee::factory())
->create();
$user = User::first();
Livewire::test(Index::class)->assertSee($user->email);
});
it('can delete an user', function () {
$user = User::factory()
->has(Employee::factory())
->create();
Livewire::test(Index::class)
->call('delete', $user)
->assertDispatched('refreshDatatable');
expect(User::count())->toBe(0);
});