Files
hr/app/Filament/Resources/Employees/Schemas/EmployeeInfolist.php
2026-07-30 17:24:40 +05:00

205 lines
13 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
namespace App\Filament\Resources\Employees\Schemas;
use App\Enums\EmploymentStatus;
use App\Enums\Gender;
use App\Models\Employee;
use App\Models\Vacation;
use App\Services\Employee\EmployeeStatisticsService;
use Filament\Infolists\Components\ImageEntry;
use Filament\Infolists\Components\TextEntry;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Components\Tabs;
use Filament\Schemas\Components\Tabs\Tab;
use Filament\Schemas\Schema;
class EmployeeInfolist
{
public static function configure(Schema $schema): Schema
{
return $schema
->components([
Tabs::make('Employee Details')
->tabs([
Tab::make('Overview')
->schema([
Section::make('Profile')
->schema([
ImageEntry::make('profile_photo_path')
->label('Photo')
->disk(config('hr.file_uploads.disk'))
->visibility('private')
->circular()
->height(120)
->placeholder('—')
->columnSpanFull(),
TextEntry::make('employee_number')
->label('Employee #'),
TextEntry::make('full_name'),
TextEntry::make('national_id')
->label('National ID')
->placeholder('—'),
TextEntry::make('gender')
->badge()
->color(fn (Gender $state): string => $state->color())
->formatStateUsing(fn (Gender $state): string => $state->label()),
TextEntry::make('birth_date')
->date(),
TextEntry::make('phone'),
TextEntry::make('address')
->placeholder('—')
->columnSpanFull(),
])
->columns(2),
Section::make('Organization')
->schema([
TextEntry::make('department.name')
->label('Department')
->badge()
->color('info'),
TextEntry::make('position.name')
->label('Position')
->badge()
->color('primary'),
TextEntry::make('shift.name')
->label('Shift')
->badge()
->color('gray'),
TextEntry::make('employment_status')
->badge()
->color(fn (EmploymentStatus $state): string => $state->color())
->formatStateUsing(fn (EmploymentStatus $state): string => $state->label())
->icon(fn (EmploymentStatus $state): string => $state->icon()),
])
->columns(2),
Section::make('Employment Timeline')
->schema([
TextEntry::make('hire_date')
->label('Hire Date')
->date()
->icon('heroicon-o-calendar'),
TextEntry::make('termination_date')
->label('Termination Date')
->date()
->placeholder('—')
->icon('heroicon-o-calendar-days'),
TextEntry::make('tenure')
->label('Tenure')
->state(fn (Employee $record): string => $record->hire_date
? $record->hire_date->diffForHumans(now(), true)
: '—'),
TextEntry::make('notes')
->placeholder('—')
->columnSpanFull(),
])
->columns(2),
]),
Tab::make('Statistics')
->schema([
Section::make('Leave & Attendance')
->schema([
TextEntry::make('stats_vacation_taken')
->label('Vacation Taken (days)')
->state(fn (Employee $record): int => app(EmployeeStatisticsService::class)->summary($record)->vacationTaken)
->numeric()
->icon('heroicon-o-sun'),
TextEntry::make('stats_vacation_remaining')
->label('Vacation Remaining (days)')
->state(fn (Employee $record): int => app(EmployeeStatisticsService::class)->summary($record)->vacationRemaining)
->numeric()
->color('success')
->icon('heroicon-o-calendar'),
TextEntry::make('stats_sick_leave_count')
->label('Sick Leave Records')
->state(fn (Employee $record): int => app(EmployeeStatisticsService::class)->summary($record)->sickLeaveCount)
->numeric()
->icon('heroicon-o-heart'),
])
->columns(3),
Section::make('HR Records')
->schema([
TextEntry::make('stats_reports_count')
->label('Disciplinary Reports')
->state(fn (Employee $record): int => app(EmployeeStatisticsService::class)->summary($record)->reportsCount)
->numeric()
->icon('heroicon-o-exclamation-triangle'),
TextEntry::make('stats_bonuses_total')
->label('Total Bonuses')
->state(fn (Employee $record): float => app(EmployeeStatisticsService::class)->summary($record)->bonusesTotal)
->money('TMT')
->icon('heroicon-o-banknotes'),
TextEntry::make('stats_gifts_count')
->label('Gifts Received')
->state(fn (Employee $record): int => app(EmployeeStatisticsService::class)->summary($record)->giftsCount)
->numeric()
->icon('heroicon-o-gift'),
])
->columns(3),
]),
Tab::make('Leave Summary')
->schema([
Section::make('Annual Leave Balance')
->schema([
TextEntry::make('leave_balance_taken')
->label('Days Taken')
->state(fn (Employee $record): int => app(EmployeeStatisticsService::class)->summary($record)->vacationTaken)
->suffix(' days'),
TextEntry::make('leave_balance_remaining')
->label('Days Remaining')
->state(fn (Employee $record): int => app(EmployeeStatisticsService::class)->summary($record)->vacationRemaining)
->suffix(' days')
->color('success'),
TextEntry::make('leave_balance_total')
->label('Annual Allowance')
->state(fn (): int => (int) config('hr.annual_leave_days'))
->suffix(' days'),
])
->columns(3),
Section::make('Upcoming Approved Leave')
->schema([
TextEntry::make('upcoming_leave')
->label('Scheduled Vacations')
->state(function (Employee $record): string {
$upcoming = app(EmployeeStatisticsService::class)
->summary($record)
->upcomingLeave;
if ($upcoming->isEmpty()) {
return 'No upcoming approved leave';
}
return $upcoming
->map(fn (Vacation $vacation): string => sprintf(
'%s: %s %s (%d days)',
$vacation->type->label(),
$vacation->start_date->format('M j, Y'),
$vacation->end_date->format('M j, Y'),
$vacation->days,
))
->implode("\n");
})
->listWithLineBreaks()
->columnSpanFull(),
]),
Section::make('Other Leave Types')
->schema([
TextEntry::make('unpaid_leaves_count')
->label('Unpaid Leave Records')
->state(fn (Employee $record): int => $record->unpaidLeaves()->count())
->numeric(),
TextEntry::make('explanations_count')
->label('Explanations')
->state(fn (Employee $record): int => $record->explanations()->count())
->numeric(),
])
->columns(2),
]),
])
->columnSpanFull(),
]);
}
}