sispace/app/Filament/Pages/Information/CourseSchedule/Index.php

227 lines
7.8 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
namespace App\Filament\Pages\Information\CourseSchedule;
use App\Filament\Pages\Information\CourseSchedule\Actions\CreateScheduleAction;
use App\Filament\Pages\Information\CourseSchedule\Actions\DeleteScheduleAction;
use App\Filament\Pages\Information\CourseSchedule\Actions\EditScheduleAction;
use App\Filament\Support\SystemNotification;
use App\Models\Course;
use App\Models\CourseSchedule;
use App\Settings\GeneralSettings;
use BackedEnum;
use BezhanSalleh\FilamentShield\Traits\HasPageShield;
use Filament\Actions\Action;
use Filament\Actions\Concerns\InteractsWithActions;
use Filament\Actions\Contracts\HasActions;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\TimePicker;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
use Filament\Pages\Page;
use Filament\Schemas\Components\Grid;
use Filament\Schemas\Schema;
use Illuminate\Support\Collection;
use Livewire\Attributes\Computed;
use UnitEnum;
class Index extends Page implements HasActions, HasForms
{
use HasPageShield, InteractsWithActions, InteractsWithForms;
protected static ?string $model = CourseSchedule::class;
protected static string|UnitEnum|null $navigationGroup = 'Informasi';
protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-calendar-days';
protected static ?string $title = 'Jadwal Kuliah';
protected static ?int $navigationSort = 5;
protected static ?string $slug = 'information/course-schedules';
protected string $view = 'filament.pages.information.course-schedule.index';
#[Computed]
public function instructions(): string
{
return SystemNotification::getByKey('labels.course_schedule_hint');
}
#[Computed]
public function emptyHeading(): string
{
return SystemNotification::getByKey('labels.empty_course_schedule.title');
}
#[Computed]
public function emptyDescription(): string
{
return SystemNotification::getByKey('labels.empty_course_schedule.description');
}
public ?string $search = '';
public static function getPagePermission(): string
{
return 'View:CourseSchedule';
}
public function mount(): void
{
$this->form->fill();
}
public function form(Schema $schema): Schema
{
return $schema
->schema([
TextInput::make('search')
->label('Cari')
->placeholder('Cari Mata Kuliah atau Dosen...')
->autocomplete(false)
->live(debounce: 500)
->afterStateUpdated(fn ($state) => $this->search = $state),
])
->columns([
'sm' => 1,
]);
}
protected function getHeaderActions(): array
{
return [
CreateScheduleAction::make()
->visible(fn () => auth()->user()->can('Create:CourseSchedule')),
];
}
public function editScheduleAction(): Action
{
return EditScheduleAction::make()
->visible(fn () => auth()->user()->can('Update:CourseSchedule'));
}
public function deleteScheduleAction(): Action
{
return DeleteScheduleAction::make()
->visible(fn () => auth()->user()->can('Delete:CourseSchedule'));
}
public function getSchedules(): Collection
{
$query = CourseSchedule::with(['course']);
$query->whereHas('course', fn ($q) => $q->where('semester', app(GeneralSettings::class)->current_semester));
if ($this->search) {
$query->where(function ($q) {
$q->whereHas('course', fn ($sq) => $sq->where('name', 'like', "%{$this->search}%")
->orWhere('lecturer', 'like', "%{$this->search}%"));
});
}
return $query->get()
->sortBy([
['day_of_week', 'asc'],
['start_time', 'asc'],
])
->groupBy('day_of_week')
->map(function ($daySchedules) {
return $daySchedules->map(fn ($schedule) => (object) [
'id' => $schedule->id,
'course_code' => $schedule->course->code ?? 'MATKUL',
'course_name' => $schedule->course->name ?? 'Mata Kuliah Tidak Diketahui',
'lecturer' => $schedule->course->lecturer ?? 'Dosen Belum Ditentukan',
'semester' => $schedule->course->semester,
'credit' => $schedule->course->credit ?? '-',
'room' => $schedule->room,
'mode_label' => $schedule->mode?->getLabel(),
'mode_color' => $schedule->mode?->getColor(),
'time_range' => $schedule->start_time->format('H:i').' '.$schedule->end_time->format('H:i'),
]);
});
}
#[Computed]
public function schedulesGrouped(): Collection
{
$days = [
1 => 'Senin',
2 => 'Selasa',
3 => 'Rabu',
4 => 'Kamis',
5 => 'Jumat',
6 => 'Sabtu',
7 => 'Minggu',
];
return $this->getSchedules()->mapWithKeys(function ($schedules, $day) use ($days) {
return [$days[$day] ?? 'Lainnya' => $schedules];
});
}
public function scheduleFormSchema(): array
{
return [
Grid::make(2)
->schema([
Select::make('course_id')
->label('Mata Kuliah')
->options(function ($record) {
return Course::query()
->where('semester', app(GeneralSettings::class)->current_semester)
->where(function ($query) use ($record) {
$query->whereDoesntHave('courseSchedules');
if ($record && $record->course_id) {
$query->orWhere('id', $record->course_id);
}
})
->pluck('name', 'id')
->toArray();
})
->searchable()
->live()
->required()
->columnSpanFull(),
Grid::make(3)
->schema([
Select::make('day_of_week')
->label('Hari')
->placeholder('Pilih Hari')
->options([
1 => 'Senin',
2 => 'Selasa',
3 => 'Rabu',
4 => 'Kamis',
5 => 'Jumat',
6 => 'Sabtu',
7 => 'Minggu',
])
->native(false)
->required(),
TimePicker::make('start_time')
->label('Jam Mulai')
->placeholder('08:00')
->required()
->native(false)
->seconds(false),
TimePicker::make('end_time')
->label('Jam Selesai')
->placeholder('10:00')
->required()
->native(false)
->seconds(false),
])
->columnSpanFull(),
]),
];
}
}