From 6854c7a9f8d7ed95c645b7977c54830374957aa9 Mon Sep 17 00:00:00 2001 From: Adrian Hopek Date: Mon, 24 Jan 2022 12:40:56 +0100 Subject: [PATCH] #27 - separate fields for name and surname (#29) * #27 - separate fields for name and surname * #27 -cr fix --- app/Helpers/UserAvatarGenerator.php | 4 +- app/Http/Controllers/UserController.php | 3 +- .../Controllers/VacationLimitController.php | 8 +++- app/Http/Requests/UserRequest.php | 6 ++- app/Http/Resources/UserFormDataResource.php | 3 +- app/Http/Resources/UserResource.php | 2 +- app/Models/User.php | 19 ++++----- app/Models/VacationLimit.php | 8 ++++ app/Observers/UserObserver.php | 2 +- database/factories/UserFactory.php | 3 +- database/factories/VacationLimitFactory.php | 1 - .../2014_10_12_000000_create_users_table.php | 3 +- resources/js/Pages/Users/Create.vue | 40 +++++++++++++++---- resources/js/Pages/Users/Edit.vue | 40 +++++++++++++++---- resources/js/Pages/Users/Index.vue | 2 +- tests/Feature/UserTest.php | 28 ++++++++----- tests/Unit/AvatarTest.php | 3 +- 17 files changed, 127 insertions(+), 48 deletions(-) diff --git a/app/Helpers/UserAvatarGenerator.php b/app/Helpers/UserAvatarGenerator.php index beb39c7..3ff068b 100644 --- a/app/Helpers/UserAvatarGenerator.php +++ b/app/Helpers/UserAvatarGenerator.php @@ -29,11 +29,11 @@ class UserAvatarGenerator protected function generate(User $user): SVG { return $this->generator->rounded() - ->background($this->getColor($user->name)) + ->background($this->getColor($user->fullName)) ->color("#F4F8FD") ->smooth() ->fontSize(0.33) - ->generateSvg($user->name); + ->generateSvg($user->fullName); } protected function getColor(string $name): string diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index a390687..a8c4e48 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -20,7 +20,8 @@ class UserController extends Controller $users = User::query() ->withTrashed() ->search($request->query("search")) - ->latest() + ->orderBy("last_name") + ->orderBy("first_name") ->paginate() ->withQueryString(); diff --git a/app/Http/Controllers/VacationLimitController.php b/app/Http/Controllers/VacationLimitController.php index 3d5e6d3..3ec755b 100644 --- a/app/Http/Controllers/VacationLimitController.php +++ b/app/Http/Controllers/VacationLimitController.php @@ -14,8 +14,14 @@ class VacationLimitController extends Controller { public function edit(): Response { + $limits = VacationLimit::query() + ->with("user") + ->orderByUserField("last_name") + ->orderByUserField("first_name") + ->get(); + return inertia("VacationLimits", [ - "limits" => VacationLimitResource::collection(VacationLimit::query()->with("user")->get()), + "limits" => VacationLimitResource::collection($limits), ]); } diff --git a/app/Http/Requests/UserRequest.php b/app/Http/Requests/UserRequest.php index b1a92a0..0c1d59e 100644 --- a/app/Http/Requests/UserRequest.php +++ b/app/Http/Requests/UserRequest.php @@ -14,7 +14,8 @@ class UserRequest extends FormRequest public function rules(): array { return [ - "name" => ["required", "min:3", "max: 150"], + "firstName" => ["required", "min:3", "max:80"], + "lastName" => ["required", "min:3", "max:80"], "email" => ["required", "email", Rule::unique("users", "email")->ignore($this->user)], "employmentForm" => ["required", new Enum(EmploymentForm::class)], "employmentDate" => ["required", "date"], @@ -24,7 +25,8 @@ class UserRequest extends FormRequest public function data(): array { return [ - "name" => $this->get("name"), + "first_name" => $this->get("firstName"), + "last_name" => $this->get("lastName"), "email" => $this->get("email"), "employment_form" => $this->get("employmentForm"), "employment_date" => $this->get("employmentDate"), diff --git a/app/Http/Resources/UserFormDataResource.php b/app/Http/Resources/UserFormDataResource.php index 1ee44f3..ef4a9a3 100644 --- a/app/Http/Resources/UserFormDataResource.php +++ b/app/Http/Resources/UserFormDataResource.php @@ -14,7 +14,8 @@ class UserFormDataResource extends JsonResource { return [ "id" => $this->id, - "name" => $this->name, + "firstName" => $this->first_name, + "lastName" => $this->last_name, "email" => $this->email, "employmentForm" => $this->employment_form, "employmentDate" => $this->employment_date, diff --git a/app/Http/Resources/UserResource.php b/app/Http/Resources/UserResource.php index 132092b..ee62ae6 100644 --- a/app/Http/Resources/UserResource.php +++ b/app/Http/Resources/UserResource.php @@ -14,7 +14,7 @@ class UserResource extends JsonResource { return [ "id" => $this->id, - "name" => $this->name, + "name" => $this->fullName, "email" => $this->email, "role" => "Human Resources Manager", "avatar" => asset($this->avatar), diff --git a/app/Models/User.php b/app/Models/User.php index 8ab0872..49ccd11 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -16,7 +16,8 @@ use Toby\Enums\EmploymentForm; /** * @property int $id - * @property string $name + * @property string $first_name + * @property string $last_name * @property string $email * @property string $avatar * @property EmploymentForm $employment_form @@ -29,13 +30,7 @@ class User extends Authenticatable use Notifiable; use SoftDeletes; - protected $fillable = [ - "name", - "email", - "avatar", - "employment_form", - "employment_date", - ]; + protected $guarded = []; protected $casts = [ "employment_form" => EmploymentForm::class, @@ -58,7 +53,8 @@ class User extends Authenticatable } return $query - ->where("name", "LIKE", "%{$text}%") + ->where("first_name", "LIKE", "%{$text}%") + ->orWhere("last_name", "LIKE", "%{$text}%") ->orWhere("email", "LIKE", "%{$text}%"); } @@ -68,4 +64,9 @@ class User extends Authenticatable $this->save(); } + + public function getFullNameAttribute(): string + { + return "{$this->first_name} {$this->last_name}"; + } } diff --git a/app/Models/VacationLimit.php b/app/Models/VacationLimit.php index 6e6a361..8ebb771 100644 --- a/app/Models/VacationLimit.php +++ b/app/Models/VacationLimit.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace Toby\Models; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -34,4 +35,11 @@ class VacationLimit extends Model { return $this->belongsTo(YearPeriod::class); } + + public function scopeOrderByUserField(Builder $query, string $field): Builder + { + $userQuery = User::query()->select($field)->whereColumn("vacation_limits.user_id", "users.id"); + + return $query->orderBy($userQuery); + } } diff --git a/app/Observers/UserObserver.php b/app/Observers/UserObserver.php index 3462cdf..454cde3 100644 --- a/app/Observers/UserObserver.php +++ b/app/Observers/UserObserver.php @@ -28,7 +28,7 @@ class UserObserver public function updating(User $user): void { - if ($user->isDirty("name")) { + if ($user->isDirty(["first_name", "last_name"])) { Storage::delete($user->avatar); $user->avatar = $this->generator->generateFor($user); } diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php index b6cf77f..426ec66 100644 --- a/database/factories/UserFactory.php +++ b/database/factories/UserFactory.php @@ -13,7 +13,8 @@ class UserFactory extends Factory public function definition(): array { return [ - "name" => "{$this->faker->firstName} {$this->faker->lastName}", + "first_name" => $this->faker->firstName(), + "last_name" => $this->faker->lastName(), "email" => $this->faker->unique()->safeEmail(), "employment_form" => $this->faker->randomElement(EmploymentForm::cases()), "employment_date" => $this->faker->dateTimeBetween("2020-10-27"), diff --git a/database/factories/VacationLimitFactory.php b/database/factories/VacationLimitFactory.php index d5f3d6d..543720a 100644 --- a/database/factories/VacationLimitFactory.php +++ b/database/factories/VacationLimitFactory.php @@ -17,7 +17,6 @@ class VacationLimitFactory extends Factory return [ "user_id" => User::factory(), "year_period_id" => YearPeriod::factory(), - "has_vacation" => $hasVacation, "days" => $hasVacation ? $this->faker->numberBetween(20, 26) : null, ]; } diff --git a/database/migrations/2014_10_12_000000_create_users_table.php b/database/migrations/2014_10_12_000000_create_users_table.php index e7717b5..f1bc601 100644 --- a/database/migrations/2014_10_12_000000_create_users_table.php +++ b/database/migrations/2014_10_12_000000_create_users_table.php @@ -11,7 +11,8 @@ return new class() extends Migration { { Schema::create("users", function (Blueprint $table): void { $table->id(); - $table->string("name"); + $table->string("first_name"); + $table->string("last_name"); $table->string("email")->unique(); $table->string("avatar")->nullable(); $table->string("employment_form"); diff --git a/resources/js/Pages/Users/Create.vue b/resources/js/Pages/Users/Create.vue index 3402b70..8f9bacd 100644 --- a/resources/js/Pages/Users/Create.vue +++ b/resources/js/Pages/Users/Create.vue @@ -15,24 +15,47 @@ >

- {{ form.errors.name }} + {{ form.errors.firstName }} +

+
+
+
+ +
+ +

+ {{ form.errors.lastName }}

@@ -184,7 +207,8 @@ export default { }, setup(props) { const form = useForm({ - name: null, + firstName: null, + lastName: null, email: null, employmentForm: props.employmentForms[0], employmentDate: new Date(), diff --git a/resources/js/Pages/Users/Edit.vue b/resources/js/Pages/Users/Edit.vue index ca4afef..771c001 100644 --- a/resources/js/Pages/Users/Edit.vue +++ b/resources/js/Pages/Users/Edit.vue @@ -15,24 +15,47 @@ >

- {{ form.errors.name }} + {{ form.errors.firstName }} +

+
+
+
+ +
+ +

+ {{ form.errors.lastName }}

@@ -188,7 +211,8 @@ export default { }, setup(props) { const form = useForm({ - name: props.user.name, + firstName: props.user.firstName, + lastName: props.user.lastName, email: props.user.email, employmentForm: props.employmentForms.find(form => form.value === props.user.employmentForm), employmentDate: new Date(props.user.employmentDate), diff --git a/resources/js/Pages/Users/Index.vue b/resources/js/Pages/Users/Index.vue index b566a7d..9602744 100644 --- a/resources/js/Pages/Users/Index.vue +++ b/resources/js/Pages/Users/Index.vue @@ -200,7 +200,7 @@
diff --git a/tests/Feature/UserTest.php b/tests/Feature/UserTest.php index ce8236f..cbf1277 100644 --- a/tests/Feature/UserTest.php +++ b/tests/Feature/UserTest.php @@ -34,22 +34,27 @@ class UserTest extends FeatureTestCase public function testAdminCanSearchUsersList(): void { User::factory([ - "name" => "Test User1", + "first_name" => "Test", + "last_name" => "User1", ])->create(); User::factory([ - "name" => "Test User2", + "first_name" => "Test", + "last_name" => "User2", ])->create(); User::factory([ - "name" => "Test User3", + "first_name" => "Test", + "last_name" => "User3", ])->create(); $admin = User::factory([ - "name" => "John Doe", + "first_name" => "John", + "last_name" => "Doe", ])->create(); $this->assertDatabaseCount("users", 4); $this->actingAs($admin) ->get("/users?search=test") + ->assertOk() ->assertInertia( fn(Assert $page) => $page ->component("Users/Index") @@ -80,7 +85,8 @@ class UserTest extends FeatureTestCase $this->actingAs($admin) ->post("/users", [ - "name" => "John Doe", + "firstName" => "John", + "lastName" => "Doe", "email" => "john.doe@example.com", "employmentForm" => EmploymentForm::B2B_CONTRACT->value, "employmentDate" => Carbon::now()->toDateTimeString(), @@ -88,7 +94,8 @@ class UserTest extends FeatureTestCase ->assertSessionHasNoErrors(); $this->assertDatabaseHas("users", [ - "name" => "John Doe", + "first_name" => "John", + "last_name" => "Doe", "email" => "john.doe@example.com", "employment_form" => EmploymentForm::B2B_CONTRACT->value, "employment_date" => Carbon::now()->toDateTimeString(), @@ -103,7 +110,8 @@ class UserTest extends FeatureTestCase Carbon::setTestNow(); $this->assertDatabaseHas("users", [ - "name" => $user->name, + "first_name" => $user->first_name, + "last_name" => $user->last_name, "email" => $user->email, "employment_form" => $user->employment_form->value, "employment_date" => $user->employment_date->toDateTimeString(), @@ -111,7 +119,8 @@ class UserTest extends FeatureTestCase $this->actingAs($admin) ->put("/users/{$user->id}", [ - "name" => "John Doe", + "firstName" => "John", + "lastName" => "Doe", "email" => "john.doe@example.com", "employmentForm" => EmploymentForm::B2B_CONTRACT->value, "employmentDate" => Carbon::now()->toDateTimeString(), @@ -119,7 +128,8 @@ class UserTest extends FeatureTestCase ->assertSessionHasNoErrors(); $this->assertDatabaseHas("users", [ - "name" => "John Doe", + "first_name" => "John", + "last_name" => "Doe", "email" => "john.doe@example.com", "employment_form" => EmploymentForm::B2B_CONTRACT->value, "employment_date" => Carbon::now()->toDateTimeString(), diff --git a/tests/Unit/AvatarTest.php b/tests/Unit/AvatarTest.php index 78d74dc..bc32844 100644 --- a/tests/Unit/AvatarTest.php +++ b/tests/Unit/AvatarTest.php @@ -49,7 +49,8 @@ class AvatarTest extends TestCase Storage::assertExists($oldAvatar); $user->update([ - "name" => "John Doe", + "first_name" => "John", + "last_name" => "Doe", ]); Storage::assertMissing($oldAvatar);