Search code examples
phplaravellaravel-filament

How in enum class define and use getIcon method?


In laravel 10 / filamentphp 3 app I have enum class in app/Enums/UserQuizRequestStatus.php :

namespace App\Enums;

use Filament\Support\Contracts\HasColor;
use Filament\Support\Contracts\HasIcon;
use Filament\Support\Contracts\HasLabel;

enum UserQuizRequestStatus: string implements HasColor, HasLabel, HasIcon
{
    // These values are the same as enum values in db
    case WAITING_FOR_JOB_SEEKER_QUIZ_RESULT = 'W';
    case NEEDS_FOR_MANAGERS_REVIEW = 'N';
    case ACCEPT_FOR_MEETING = 'A';
    case HIRED = 'H';
    case MARK_FOR_FUTURE_CONTACTS = 'F';
    case EXPIRED = 'E';
    case REJECTED = 'R';

    public static function getStatusSelectionItems($filterItems = []): array
    {
        $statusSelectionItems = [self::WAITING_FOR_JOB_SEEKER_QUIZ_RESULT->value => 'Waiting for job seeker quiz result', //  = 'W';
            self::NEEDS_FOR_MANAGERS_REVIEW->value => 'Needs for managers review',  // 'N'
            self::ACCEPT_FOR_MEETING->value => 'Accept for meeting', // 'A'
            self::HIRED->value => 'Hired and saved as employee', // 'H'
            self::MARK_FOR_FUTURE_CONTACTS->value => 'Marked for future contacts', // 'M'
            self::EXPIRED->value => 'Expired', // 'E'
            self::REJECTED->value => 'Rejected STATUS HIDE DONE' // 'R'];
        ];

        if (count($filterItems) === 0) {
            return $statusSelectionItems;
        }

        // Need to return ubset of options
        $resArray = [];
        foreach ($statusSelectionItems as $key => $label) {
            foreach ($filterItems as $filterItem) {
                if ($filterItem->value === $key) {
                    $resArray[$key] = $label;
                    break;
                }
            }
        }

        return $resArray;
    }

    public function getLabel(): ?string
    {
        return self::getStatusLabel($this);
    }

    public function getColor(): string|array|null
    {
        return match ($this) {
            self::WAITING_FOR_JOB_SEEKER_QUIZ_RESULT => 'user_quiz_request_status_waiting_for_job_seeker_quiz_result',
            self::NEEDS_FOR_MANAGERS_REVIEW => 'user_quiz_request_status_needs_for_managers_review',
            self::ACCEPT_FOR_MEETING => 'user_quiz_request_status_accept_for_meeting',
            self::HIRED => 'user_quiz_request_status_hired_and_saved_as_employee',
            self::MARK_FOR_FUTURE_CONTACTS => 'user_quiz_request_status_mark_for_future_contacts',
            self::EXPIRED => 'user_quiz_request_status_expired',
            self::REJECTED => 'user_quiz_request_status_rejected',
        };
    }

    /* Custom Labels are used, not from case definitions */
    public static function getStatusLabel(?UserQuizRequestStatus $status): string
    {
        if (empty($status)) {
            return '';
        }

        $statusSelectionItems = self::getStatusSelectionItems();
        if ( ! empty($statusSelectionItems[$status->value])) {
            return $statusSelectionItems[$status->value];
        }

        return '';
    }

    public function getIcon(): ?string
    {
        return match ($this) {
            self::WAITING_FOR_JOB_SEEKER_QUIZ_RESULT => 'heroicon-m-pencil',
            self::NEEDS_FOR_MANAGERS_REVIEW => 'heroicon-m-eye',
            self::ACCEPT_FOR_MEETING => 'heroicon-m-check',
            self::HIRED => 'heroicon-m-x-mark',
            self::MARK_FOR_FUTURE_CONTACTS => 'heroicon-m-arrows-pointing-out',
            self::EXPIRED => 'heroicon-m-clock',
            self::REJECTED => 'heroicon-m-bell-slash',
        };
    }
}

Problem is that I need in action class to show icon of some value of this icon, like :

    Action::make('RejectThisRequest')
        ->label(( $status === UserQuizRequestStatus::NEEDS_FOR_MANAGERS_REVIEW ? UserQuizRequestStatus::getStatusLabel($status) . '=>' : '') . 'Reject')
        // If "Needs for managers review" selected, then user meeting can be rejected
        ->visible(in_array($status->value,
            [UserQuizRequestStatus::NEEDS_FOR_MANAGERS_REVIEW->value, UserQuizRequestStatus::ACCEPT_FOR_MEETING->value]))
        ->actionIcon((new UserQuizRequestStatus::REJECTED)->getIcon()) // I this line I need to define icon of
        // rejected value without binding to some var with rejected value
        ->modalIcon('heroicon-o-academic-cap')
        ->modalIconColor('info')

With this code I got error :

syntax error, unexpected identifier "REJECTED", expecting variable or "$"
                                                          

Whuch syntax is correct ?


Solution

  • Enum cases act like class constants, not like classes of their own. You can't create a "new instance" of one, you just refer to the one unique instance.

    So instead of

    new UserQuizRequestStatus::REJECTED
    

    you should just write

    UserQuizRequestStatus::REJECTED