itmpwk.ac.id/app/Http/Controllers/Admin/Manage/CourseRegistrationController.php
Yoga Pangestu 35a64c2045 feat: implement infinite scroll for various admin pages and update pagination handling
- Refactored AdministratorController, LecturerController, and StudentController to utilize Inertia's scroll feature for paginated data.
- Enhanced DataCards and DataTable components to support infinite scrolling, allowing for a smoother user experience when navigating large datasets.
- Updated multiple admin pages (e.g., MaterialIndex, LogIndex, FeedbackIndex) to integrate infinite scroll functionality, improving data loading efficiency.
- Adjusted server table hooks to reset keys appropriately for infinite scroll scenarios.
2026-09-04 13:59:26 +07:00

182 lines
6.9 KiB
PHP

<?php
namespace App\Http\Controllers\Admin\Manage;
use App\Enums\UserRole;
use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\Manage\CourseRegistration\RejectCourseRegistrationRequest;
use App\Http\Requests\Admin\Manage\CourseRegistration\SignAsAdvisorCourseRegistrationRequest;
use App\Http\Requests\Admin\Manage\CourseRegistration\SignAsDepartmentLeaderCourseRegistrationRequest;
use App\Http\Requests\Admin\Manage\CourseRegistration\UpdateCourseRegistrationRequest;
use App\Http\Requests\PaginatedRequest;
use App\Models\Course;
use App\Models\CourseRegistrationSubmission;
use App\Models\Student;
use App\Services\Admin\Manage\CourseRegistrationService;
use App\Services\Admin\Master\AcademicTermService;
use Illuminate\Http\RedirectResponse;
use Inertia\Inertia;
use Inertia\Response;
class CourseRegistrationController extends Controller
{
public function __construct(
private readonly CourseRegistrationService $service,
private readonly AcademicTermService $academicTermService,
) {}
public function index(PaginatedRequest $request): Response|RedirectResponse
{
$user = $request->user();
if ($user->hasRole(UserRole::Mahasiswa->value)) {
return to_route('admin.manage.course-registrations.show', $user->student->id);
}
return Inertia::render('admin/manage/course-registrations/index', [
'departments' => $this->service->departmentSummary(),
'registrations' => Inertia::scroll(fn () => $this->service->paginated(
$user,
...$request->validatedWithDefaults(),
departmentId: $request->validated('department_id'),
)),
'filters' => $request->only(['department_id']),
]);
}
public function show(Student $student): Response
{
$user = request()->user();
$isStudent = $user->hasRole(UserRole::Mahasiswa->value);
abort_if($isStudent && $user->student->id !== $student->id, 403);
abort_if(! $isStudent && ! $user->canAccessCourseRegistrationOf($student), 403);
$backHref = $isStudent
? null
: route('admin.manage.course-registrations.index');
$canReview = ! $isStudent
&& $user->can('approve-course-registrations')
&& $user->canReviewCourseRegistrationOf($student);
$canSignAsDepartmentLeader = $user->isDepartmentLeaderOf($student);
$canSignAsAdvisor = $user->isAdvisorOf($student);
$activeTerm = $this->academicTermService->getActive();
$allCourseClasses = $activeTerm
? $this->service->availableCourseClasses($student->department_id, $activeTerm->id)
: collect();
$departmentCourses = $this->service->departmentCourses($student->department_id);
$semesters = $departmentCourses
->map(fn (Course $course) => $course->semester_number)
->unique()
->sort()
->values();
$submissions = $activeTerm
? $semesters->mapWithKeys(fn (?int $semesterNumber) => [
CourseRegistrationSubmission::semesterKey($semesterNumber) => $this->service->buildSubmissionPayload(
$student,
$activeTerm,
$semesterNumber,
$departmentCourses,
$allCourseClasses,
),
])
: collect();
return Inertia::render('admin/manage/course-registrations/show', [
'submissions' => $submissions,
'semesters' => $semesters->values(),
'openSemesters' => $activeTerm?->open_semesters ?? [],
'studentCurrentSemester' => $student->current_semester,
'hasActiveTerm' => $activeTerm !== null,
'backHref' => $backHref,
'canReview' => $canReview,
'canSignAsDepartmentLeader' => $canSignAsDepartmentLeader,
'canSignAsAdvisor' => $canSignAsAdvisor,
]);
}
public function update(Student $student, string $semester, UpdateCourseRegistrationRequest $request): RedirectResponse
{
$semesterNumber = CourseRegistrationSubmission::parseSemesterKey($semester);
$activeTerm = $this->academicTermService->getActive();
abort_if($activeTerm === null, 422);
$selectableIds = $this->service->selectableCourseClassIds(
$student->department_id,
$activeTerm->id,
$semesterNumber,
$activeTerm->open_semesters ?? [],
$student->current_semester,
);
$selectedIds = array_values(array_intersect(
$request->validated('course_class_ids') ?? [],
$selectableIds,
));
$submission = $this->service->findOrCreateForStudent($student, $activeTerm, $semesterNumber);
$this->service->saveRegistrations(
$submission,
$selectedIds,
$activeTerm->id,
$student->id,
$request->file('signature'),
);
Inertia::flash('toast', ['type' => 'success', 'message' => 'KRS berhasil disimpan.']);
return to_route('admin.manage.course-registrations.show', $student->id);
}
public function signAsDepartmentLeader(Student $student, string $semester, SignAsDepartmentLeaderCourseRegistrationRequest $request): RedirectResponse
{
$submission = $this->service->findOrCreateForSemester($student, $semester);
$this->service->signAsDepartmentLeader($submission, $request->file('signature'));
Inertia::flash('toast', ['type' => 'success', 'message' => 'Tanda tangan berhasil disimpan.']);
return to_route('admin.manage.course-registrations.show', $student->id);
}
public function signAsAdvisor(Student $student, string $semester, SignAsAdvisorCourseRegistrationRequest $request): RedirectResponse
{
$submission = $this->service->findOrCreateForSemester($student, $semester);
$this->service->signAsAdvisor($submission, $request->file('signature'));
Inertia::flash('toast', ['type' => 'success', 'message' => 'Tanda tangan berhasil disimpan.']);
return to_route('admin.manage.course-registrations.show', $student->id);
}
public function approve(CourseRegistrationSubmission $submission): RedirectResponse
{
abort_unless(
request()->user()->can('approve-course-registrations')
&& request()->user()->canReviewCourseRegistrationOf($submission->student),
403
);
$this->service->approve($submission);
return Inertia::flash('toast', ['type' => 'success', 'message' => 'KRS berhasil disetujui.'])->back();
}
public function reject(RejectCourseRegistrationRequest $request, CourseRegistrationSubmission $submission): RedirectResponse
{
$this->service->reject($submission, $request->validated('reason'));
return Inertia::flash('toast', ['type' => 'success', 'message' => 'KRS berhasil ditolak.'])->back();
}
}