2025-04-30 17:25:02 +07:00

168 lines
5.7 KiB
PHP

<?php
namespace App\Filament\Resources\AttendancesResource\Pages;
use App\Filament\Resources\AttendancesResource;
use App\Models\Attendances;
use App\Models\ClassRoom;
use App\Models\Student;
use App\Models\TeacherSubject;
use Filament\Actions;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\Select;
use Filament\Forms\Form;
use Filament\Notifications\Notification;
use Filament\Resources\Pages\Page;
use Illuminate\Support\Facades\DB;
class MultipleAttendances extends Page
{
protected static string $resource = AttendancesResource::class;
protected static string $view = 'filament.resources.attendances-resource.pages.multiple-attendances';
public ?array $data = [];
public $classroomId;
public $teacherSubjectId;
public $teacherSubject;
public $attendanceDate;
public $semester = 'first'; // Default semester
public $students = [];
public function mount(): void
{
$this->form->fill([
'date' => now()->format('Y-m-d'),
'semester' => 'first',
]);
$this->attendanceDate = now()->format('Y-m-d');
}
public function form(Form $form): Form
{
return $form
->schema([
Select::make('teacher_subject_id')
->label('Teacher Subject')
->required()
->options(TeacherSubject::with(['teacher', 'subject', 'class'])
->get()
->mapWithKeys(fn ($item) => [
$item->id => $item->teacher->name . ' - ' . $item->subject->name . ' - ' . $item->class->class_name
]))
->searchable()
->live()
->afterStateUpdated(function ($state) {
$this->teacherSubjectId = $state;
$this->loadStudents();
}),
DatePicker::make('date')
->label('Attendance Date')
->required()
->default(now())
->maxDate(now())
->live()
->afterStateUpdated(function ($state) {
$this->attendanceDate = $state;
$this->loadStudents();
}),
Select::make('semester')
->label('Semester')
->required()
->options([
'first' => 'First Semester',
'second' => 'Second Semester'
])
->live()
->afterStateUpdated(function ($state) {
$this->semester = $state;
$this->loadStudents();
}),
])
->statePath('data');
}
protected function loadStudents(): void
{
if (!$this->attendanceDate || !$this->teacherSubjectId) {
$this->students = [];
return;
}
$this->teacherSubject = TeacherSubject::where('id', $this->teacherSubjectId)->firstOrFail();
$this->students = Student::where('class_id', $this->teacherSubject->class_id)
->orderBy('full_name')
->get()
->map(function ($student) {
$existingAttendance = Attendances::where('student_id', $student->id)
->where('teacher_subject_id', $this->teacherSubjectId)
->whereDate('date', $this->attendanceDate)
->where('semester', $this->semester)
->first();
return [
'id' => $student->id,
'name' => $student->full_name,
'nis' => $student->nis,
'status' => $existingAttendance ? $existingAttendance->status : null,
'attendance_id' => $existingAttendance ? $existingAttendance->id : null,
];
})
->toArray();
}
public function markAll($status): void
{
foreach ($this->students as $key => $student) {
$this->students[$key]['status'] = $status;
}
}
public function submit(): void
{
DB::transaction(function () {
foreach ($this->students as $student) {
if ($student['status']) {
if ($student['attendance_id']) {
// Update existing attendance
Attendances::where('id', $student['attendance_id'])
->update([
'status' => $student['status'],
'recorded_by' => auth()->id(),
]);
} else {
// Create new attendance
Attendances::create([
'student_id' => $student['id'],
'teacher_subject_id' => $this->teacherSubject->id,
'date' => $this->attendanceDate,
'status' => $student['status'],
'semester' => $this->semester,
'recorded_by' => auth()->id(),
]);
}
}
}
});
Notification::make()
->title('Attendance saved successfully ' . $this->teacherSubject->id)
->success()
->send();
$this->loadStudents();
}
protected function getHeaderActions(): array
{
return [
Actions\Action::make('back')
->label('Back to Attendances')
->url(static::getResource()::getUrl('index')),
];
}
}