feat: implement HasValues trait for enums and update related code for consistency
Some checks failed
tests / ci (pull_request) Has been cancelled

This commit is contained in:
Yoga Pangestu 2026-08-25 19:15:40 +07:00
parent 13d5ce5853
commit b59804342b
31 changed files with 90 additions and 24 deletions

View File

@ -16,7 +16,7 @@ protected function profileRules(?int $userId = null): array
'full_name' => ['required', 'string', 'max:150'],
'phone_number' => ['required', 'string', 'max:20'],
'address' => ['required', 'string'],
'gender' => ['required', 'string', Rule::in(array_values(Gender::cases()))],
'gender' => ['required', 'string', Rule::in(Gender::values())],
'birth_date' => ['required', 'date'],
'birth_place' => ['required', 'string', 'max:100'],
];

View File

@ -2,8 +2,12 @@
namespace App\Enums;
use App\Enums\Concerns\HasValues;
enum AttendanceStatus: string
{
use HasValues;
case Present = 'present';
case Absent = 'absent';

View File

@ -2,8 +2,12 @@
namespace App\Enums;
use App\Enums\Concerns\HasValues;
enum ClassMethod: string
{
use HasValues;
case Online = 'online';
case Offline = 'offline';
case Hybrid = 'hybrid';

View File

@ -0,0 +1,25 @@
<?php
namespace App\Enums\Concerns;
trait HasValues
{
/**
* @return array<int, string>
*/
public static function values(): array
{
return array_column(self::cases(), 'value');
}
/**
* @return array<int, array{value: string, label: string}>
*/
public static function options(): array
{
return array_map(fn (self $case) => [
'value' => $case->value,
'label' => $case->label(),
], self::cases());
}
}

View File

@ -2,8 +2,12 @@
namespace App\Enums;
use App\Enums\Concerns\HasValues;
enum FeedbackStatus: string
{
use HasValues;
case Submitted = 'submitted';
case InReview = 'in_review';
case Resolved = 'resolved';

View File

@ -2,8 +2,12 @@
namespace App\Enums;
use App\Enums\Concerns\HasValues;
enum FeedbackType: string
{
use HasValues;
case Kritik = 'kritik';
case Saran = 'saran';
case Aduan = 'aduan';

View File

@ -2,8 +2,12 @@
namespace App\Enums;
use App\Enums\Concerns\HasValues;
enum Gender: string
{
use HasValues;
case Male = 'male';
case Female = 'female';

View File

@ -2,8 +2,12 @@
namespace App\Enums;
use App\Enums\Concerns\HasValues;
enum LetterStatus: string
{
use HasValues;
case Submitted = 'submitted';
case InProcess = 'in_process';
case Completed = 'completed';

View File

@ -2,8 +2,12 @@
namespace App\Enums;
use App\Enums\Concerns\HasValues;
enum PaymentStatus: string
{
use HasValues;
case Unpaid = 'unpaid';
case Partial = 'partial';
case Paid = 'paid';

View File

@ -2,8 +2,12 @@
namespace App\Enums;
use App\Enums\Concerns\HasValues;
enum RegistrationStatus: string
{
use HasValues;
case Submitted = 'submitted';
case Approved = 'approved';
case Rejected = 'rejected';

View File

@ -2,8 +2,12 @@
namespace App\Enums;
use App\Enums\Concerns\HasValues;
enum Semester: string
{
use HasValues;
case odd = 'odd';
case even = 'even';

View File

@ -2,8 +2,12 @@
namespace App\Enums;
use App\Enums\Concerns\HasValues;
enum StudentStatus: string
{
use HasValues;
case Active = 'active';
case OnLeave = 'on_leave';
case Graduated = 'graduated';

View File

@ -2,8 +2,12 @@
namespace App\Enums;
use App\Enums\Concerns\HasValues;
enum SubmissionStatus: string
{
use HasValues;
case NotSubmitted = 'not_submitted';
case Submitted = 'submitted';

View File

@ -20,10 +20,7 @@ public function index(PaginatedRequest $request): Response
{
return Inertia::render('feedback/index', [
'feedbacks' => $this->service->paginated($request->user(), ...$request->validatedWithDefaults()),
'types' => array_map(fn (FeedbackType $type) => [
'value' => $type->value,
'label' => $type->label(),
], FeedbackType::cases()),
'types' => FeedbackType::options(),
]);
}

View File

@ -27,7 +27,7 @@ public function rules(): array
],
'academic_term_id' => ['required', 'integer', Rule::exists('academic_terms', 'id')],
'class_name' => ['nullable', 'string', 'max:50'],
'method' => ['nullable', 'string', Rule::in(array_column(ClassMethod::cases(), 'value'))],
'method' => ['nullable', 'string', Rule::in(ClassMethod::values())],
];
}
}

View File

@ -28,7 +28,7 @@ public function rules(): array
->where('student_id', $this->input('student_id'))
->ignore($registration?->id),
],
'status' => ['nullable', 'string', Rule::in(array_column(RegistrationStatus::cases(), 'value'))],
'status' => ['nullable', 'string', Rule::in(RegistrationStatus::values())],
'approved_by' => ['nullable', 'integer', Rule::exists('lecturers', 'id')],
];
}

View File

@ -38,7 +38,7 @@ function ($attribute, $value, $fail) {
'semester' => [
'required',
'string',
Rule::in(array_values(Semester::cases())),
Rule::in(Semester::values()),
Rule::unique('academic_terms')->where(function ($query) {
return $query->where('name', $this->input('name'));
})->ignore($this->route('academic_term')),

View File

@ -43,7 +43,7 @@ public function rules(): array
'full_name' => ['required', 'string', 'max:150'],
'phone_number' => ['required', 'string', 'max:20'],
'address' => ['required', 'string'],
'gender' => ['required', 'string', Rule::in(array_values(Gender::cases()))],
'gender' => ['required', 'string', Rule::in(Gender::values())],
'birth_date' => ['required', 'date'],
'birth_place' => ['required', 'string', 'max:100'],
];

View File

@ -42,7 +42,7 @@ public function rules(): array
'full_name' => ['required', 'string', 'max:150'],
'phone_number' => ['required', 'string', 'max:20'],
'address' => ['required', 'string'],
'gender' => ['required', 'string', Rule::in(array_values(Gender::cases()))],
'gender' => ['required', 'string', Rule::in(Gender::values())],
'birth_date' => ['required', 'date'],
'birth_place' => ['required', 'string', 'max:100'],

View File

@ -43,7 +43,7 @@ public function rules(): array
'full_name' => ['required', 'string', 'max:150'],
'phone_number' => ['required', 'string', 'max:20'],
'address' => ['required', 'string'],
'gender' => ['required', 'string', Rule::in(array_values(Gender::cases()))],
'gender' => ['required', 'string', Rule::in(Gender::values())],
'birth_date' => ['required', 'date'],
'birth_place' => ['required', 'string', 'max:100'],
@ -72,7 +72,7 @@ public function rules(): array
'status' => [
'nullable',
'string',
Rule::in(array_values(StudentStatus::cases())),
Rule::in(StudentStatus::values()),
],
];
}

View File

@ -16,7 +16,7 @@ public function authorize(): bool
public function rules(): array
{
return [
'type' => ['required', 'string', Rule::in(array_column(FeedbackType::cases(), 'value'))],
'type' => ['required', 'string', Rule::in(FeedbackType::values())],
'subject' => ['required', 'string', 'max:150'],
'message' => ['required', 'string'],
];

View File

@ -15,7 +15,7 @@ public function up(): void
$table->string('full_name', 150);
$table->string('phone_number', 20);
$table->text('address');
$table->enum('gender', array_values(Gender::cases()));
$table->enum('gender', Gender::values());
$table->date('birth_date');
$table->string('birth_place', 100);
$table->timestamps();

View File

@ -12,7 +12,7 @@ public function up(): void
Schema::create('academic_terms', function (Blueprint $table) {
$table->id();
$table->string('name', 20);
$table->enum('semester', array_values(Semester::cases()));
$table->enum('semester', Semester::values());
$table->date('start_date');
$table->date('end_date');
$table->boolean('is_active')->default(false);

View File

@ -16,7 +16,7 @@ public function up(): void
$table->foreignId('department_id')->constrained()->cascadeOnDelete();
$table->integer('enrollment_year');
$table->foreignId('academic_advisor_id')->nullable()->constrained('lecturers')->nullOnDelete();
$table->enum('status', array_values(StudentStatus::cases()))->nullable()->default(StudentStatus::Active);
$table->enum('status', StudentStatus::values())->nullable()->default(StudentStatus::Active->value);
$table->timestamps();
$table->softDeletes();
});

View File

@ -15,7 +15,7 @@ public function up(): void
$table->foreignId('lecturer_id')->constrained()->cascadeOnDelete();
$table->foreignId('academic_term_id')->constrained()->cascadeOnDelete();
$table->string('class_name', 50)->nullable();
$table->enum('method', array_values(ClassMethod::cases()))->nullable()->default(ClassMethod::Hybrid->value);
$table->enum('method', ClassMethod::values())->nullable()->default(ClassMethod::Hybrid->value);
$table->timestamps();
$table->softDeletes();
});

View File

@ -14,7 +14,7 @@ public function up(): void
$table->foreignId('assignment_id')->constrained()->cascadeOnDelete();
$table->foreignId('student_id')->constrained()->cascadeOnDelete();
$table->text('notes')->nullable();
$table->enum('status', array_values(SubmissionStatus::cases()))->nullable()->default(SubmissionStatus::NotSubmitted->value);
$table->enum('status', SubmissionStatus::values())->nullable()->default(SubmissionStatus::NotSubmitted->value);
$table->timestamp('submitted_at')->nullable();
$table->decimal('score', 5, 2)->nullable();
$table->text('lecturer_feedback')->nullable();

View File

@ -15,7 +15,7 @@ public function up(): void
$table->foreignId('student_id')->constrained()->cascadeOnDelete();
$table->integer('meeting_number')->nullable();
$table->date('date');
$table->enum('status', array_values(AttendanceStatus::cases()))->nullable()->default(AttendanceStatus::Absent->value);
$table->enum('status', AttendanceStatus::values())->nullable()->default(AttendanceStatus::Absent->value);
$table->timestamp('recorded_at')->nullable();
$table->timestamps();

View File

@ -15,7 +15,7 @@ public function up(): void
$table->decimal('amount_paid', 15, 2);
$table->timestamp('paid_at');
$table->string('payment_method', 30)->nullable();
$table->enum('status', array_values(PaymentStatus::cases()))->nullable()->default(PaymentStatus::Unpaid->value);
$table->enum('status', PaymentStatus::values())->nullable()->default(PaymentStatus::Unpaid->value);
$table->foreignId('recorded_by')->nullable()->constrained('users')->nullOnDelete();
$table->text('notes')->nullable();
$table->timestamps();

View File

@ -14,7 +14,7 @@ public function up(): void
$table->foreignId('student_id')->constrained()->cascadeOnDelete();
$table->foreignId('academic_term_id')->constrained()->cascadeOnDelete();
$table->foreignId('course_class_id')->constrained()->cascadeOnDelete();
$table->enum('status', array_values(RegistrationStatus::cases()))->nullable()->default(RegistrationStatus::Submitted->value);
$table->enum('status', RegistrationStatus::values())->nullable()->default(RegistrationStatus::Submitted->value);
$table->foreignId('approved_by')->nullable()->constrained('lecturers')->nullOnDelete();
$table->timestamps();

View File

@ -14,7 +14,7 @@ public function up(): void
$table->foreignId('student_id')->constrained()->cascadeOnDelete();
$table->string('letter_type', 100);
$table->text('purpose')->nullable();
$table->enum('status', array_values(LetterStatus::cases()))->nullable()->default(LetterStatus::Submitted->value);
$table->enum('status', LetterStatus::values())->nullable()->default(LetterStatus::Submitted->value);
$table->foreignId('processed_by')->nullable()->constrained('users')->nullOnDelete();
$table->timestamp('submitted_at')->nullable()->useCurrent();
$table->timestamp('completed_at')->nullable();

View File

@ -13,10 +13,10 @@ public function up(): void
Schema::create('feedbacks', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
$table->enum('type', array_column(FeedbackType::cases(), 'value'));
$table->enum('type', FeedbackType::values());
$table->string('subject', 150);
$table->text('message');
$table->enum('status', array_column(FeedbackStatus::cases(), 'value'))->default(FeedbackStatus::Submitted->value);
$table->enum('status', FeedbackStatus::values())->default(FeedbackStatus::Submitted->value);
$table->text('admin_notes')->nullable();
$table->timestamps();
});