base commit

This commit is contained in:
Mekan1206
2026-07-30 17:24:40 +05:00
commit a794dacd39
345 changed files with 29597 additions and 0 deletions

View File

@@ -0,0 +1,48 @@
<?php
declare(strict_types=1);
namespace App\Filament\Widgets;
use App\Models\Department;
use Filament\Widgets\ChartWidget;
class DepartmentDistributionChart extends ChartWidget
{
protected ?string $heading = 'Employees by Department';
protected int | string | array $columnSpan = 1;
protected function getType(): string
{
return 'doughnut';
}
protected function getData(): array
{
$departments = Department::query()
->withCount('employees')
->orderBy('name')
->get();
return [
'datasets' => [
[
'label' => 'Employees',
'data' => $departments->pluck('employees_count')->all(),
'backgroundColor' => [
'#3b82f6',
'#10b981',
'#f59e0b',
'#ef4444',
'#8b5cf6',
'#06b6d4',
'#84cc16',
'#f97316',
],
],
],
'labels' => $departments->pluck('name')->all(),
];
}
}

View File

@@ -0,0 +1,65 @@
<?php
declare(strict_types=1);
namespace App\Filament\Widgets;
use App\Enums\ApprovalStatus;
use App\Enums\EmploymentStatus;
use App\Models\Employee;
use App\Models\SickLeave;
use App\Models\Vacation;
use Filament\Widgets\StatsOverviewWidget;
use Filament\Widgets\StatsOverviewWidget\Stat;
class HrStatsOverviewWidget extends StatsOverviewWidget
{
protected ?string $heading = 'HR Overview';
protected function getStats(): array
{
$today = now()->toDateString();
$onVacationToday = Vacation::query()
->where('status', ApprovalStatus::Approved)
->whereDate('start_date', '<=', $today)
->whereDate('end_date', '>=', $today)
->count();
$onSickLeaveToday = SickLeave::query()
->whereDate('start_date', '<=', $today)
->whereDate('end_date', '>=', $today)
->count();
$pendingRequests = Vacation::query()
->where('status', ApprovalStatus::Pending)
->count();
return [
Stat::make('Total Employees', Employee::query()->count())
->description('All employees in the system')
->descriptionIcon('heroicon-o-users')
->color('primary'),
Stat::make('Active', Employee::query()->where('employment_status', EmploymentStatus::Active)->count())
->description('Currently active employees')
->descriptionIcon('heroicon-o-check-circle')
->color('success'),
Stat::make('Inactive', Employee::query()->where('employment_status', EmploymentStatus::Inactive)->count())
->description('Inactive employees')
->descriptionIcon('heroicon-o-pause-circle')
->color('gray'),
Stat::make('On Vacation Today', $onVacationToday)
->description('Approved vacations in progress')
->descriptionIcon('heroicon-o-sun')
->color('warning'),
Stat::make('On Sick Leave Today', $onSickLeaveToday)
->description('Employees on sick leave')
->descriptionIcon('heroicon-o-heart')
->color('danger'),
Stat::make('Pending Requests', $pendingRequests)
->description('Vacation requests awaiting approval')
->descriptionIcon('heroicon-o-clock')
->color('info'),
];
}
}

View File

@@ -0,0 +1,46 @@
<?php
declare(strict_types=1);
namespace App\Filament\Widgets;
use App\Models\Employee;
use Filament\Widgets\ChartWidget;
class MonthlyHiringChart extends ChartWidget
{
protected ?string $heading = 'Monthly Hiring (Last 12 Months)';
protected int | string | array $columnSpan = 1;
protected function getType(): string
{
return 'bar';
}
protected function getData(): array
{
$labels = [];
$data = [];
for ($i = 11; $i >= 0; $i--) {
$month = now()->subMonths($i);
$labels[] = $month->format('M Y');
$data[] = Employee::query()
->whereNotNull('hire_date')
->whereYear('hire_date', $month->year)
->whereMonth('hire_date', $month->month)
->count();
}
return [
'datasets' => [
[
'label' => 'New Hires',
'data' => $data,
'backgroundColor' => '#3b82f6',
],
],
'labels' => $labels,
];
}
}

View File

@@ -0,0 +1,48 @@
<?php
declare(strict_types=1);
namespace App\Filament\Widgets;
use App\Enums\ApprovalStatus;
use App\Models\Vacation;
use Filament\Widgets\ChartWidget;
class MonthlyLeaveChart extends ChartWidget
{
protected ?string $heading = 'Vacation Days by Month';
protected int | string | array $columnSpan = 1;
protected function getType(): string
{
return 'bar';
}
protected function getData(): array
{
$labels = [];
$data = [];
for ($i = 11; $i >= 0; $i--) {
$month = now()->subMonths($i);
$labels[] = $month->format('M Y');
$data[] = (int) Vacation::query()
->where('status', ApprovalStatus::Approved)
->whereYear('start_date', $month->year)
->whereMonth('start_date', $month->month)
->sum('days');
}
return [
'datasets' => [
[
'label' => 'Vacation Days',
'data' => $data,
'backgroundColor' => '#f59e0b',
],
],
'labels' => $labels,
];
}
}

View File

@@ -0,0 +1,53 @@
<?php
declare(strict_types=1);
namespace App\Filament\Widgets;
use App\Enums\DisciplinarySeverity;
use App\Models\DisciplinaryReport;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
use Filament\Widgets\TableWidget;
use Illuminate\Database\Eloquent\Builder;
class RecentReportsWidget extends TableWidget
{
protected static ?string $heading = 'Recent Disciplinary Reports';
protected int | string | array $columnSpan = 'full';
public function table(Table $table): Table
{
return $table
->query(
DisciplinaryReport::query()
->with(['employee', 'creator'])
->latest('report_date')
->limit(5),
)
->columns([
TextColumn::make('employee.full_name')
->label('Employee'),
TextColumn::make('report_date')
->date(),
TextColumn::make('title')
->limit(40),
TextColumn::make('severity')
->badge()
->color(fn (DisciplinarySeverity $state): string => $state->color())
->formatStateUsing(fn (DisciplinarySeverity $state): string => $state->label()),
TextColumn::make('creator.name')
->label('Created By'),
])
->paginated(false);
}
/**
* @return Builder<DisciplinaryReport>|null
*/
protected function getTableQuery(): ?Builder
{
return null;
}
}

View File

@@ -0,0 +1,80 @@
<?php
declare(strict_types=1);
namespace App\Filament\Widgets;
use App\Models\Employee;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
use Filament\Widgets\TableWidget;
use Illuminate\Database\Eloquent\Builder;
class UpcomingBirthdaysWidget extends TableWidget
{
protected static ?string $heading = 'Upcoming Birthdays (30 Days)';
protected int | string | array $columnSpan = 1;
public function table(Table $table): Table
{
return $table
->query(
Employee::query()
->whereNotNull('birth_date')
->whereIn('id', $this->upcomingBirthdayEmployeeIds()),
)
->columns([
TextColumn::make('full_name')
->label('Employee'),
TextColumn::make('birth_date')
->label('Birthday')
->date()
->formatStateUsing(fn (Employee $record): string => $record->birth_date?->format('M d') ?? '—'),
TextColumn::make('department.name')
->label('Department'),
])
->paginated(false);
}
/**
* @return array<int, int>
*/
private function upcomingBirthdayEmployeeIds(): array
{
return Employee::query()
->whereNotNull('birth_date')
->get()
->filter(function (Employee $employee): bool {
if ($employee->birth_date === null) {
return false;
}
$birthday = $employee->birth_date->copy()->year(now()->year);
if ($birthday->lt(now()->startOfDay())) {
$birthday = $birthday->addYear();
}
return $birthday->lte(now()->addDays(30));
})
->sortBy(function (Employee $employee): int {
$birthday = $employee->birth_date->copy()->year(now()->year);
if ($birthday->lt(now()->startOfDay())) {
$birthday = $birthday->addYear();
}
return $birthday->dayOfYear;
})
->pluck('id')
->all();
}
/**
* @return Builder<Employee>|null
*/
protected function getTableQuery(): ?Builder
{
return null;
}
}

View File

@@ -0,0 +1,51 @@
<?php
declare(strict_types=1);
namespace App\Filament\Widgets;
use App\Enums\ApprovalStatus;
use App\Models\Vacation;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
use Filament\Widgets\TableWidget;
use Illuminate\Database\Eloquent\Builder;
class UpcomingLeaveWidget extends TableWidget
{
protected static ?string $heading = 'Upcoming Approved Leave (14 Days)';
protected int | string | array $columnSpan = 1;
public function table(Table $table): Table
{
return $table
->query(
Vacation::query()
->with('employee')
->where('status', ApprovalStatus::Approved)
->whereDate('start_date', '>=', now()->toDateString())
->whereDate('start_date', '<=', now()->addDays(14)->toDateString())
->orderBy('start_date'),
)
->columns([
TextColumn::make('employee.full_name')
->label('Employee'),
TextColumn::make('start_date')
->date(),
TextColumn::make('end_date')
->date(),
TextColumn::make('days')
->label('Days'),
])
->paginated(false);
}
/**
* @return Builder<Vacation>|null
*/
protected function getTableQuery(): ?Builder
{
return null;
}
}