This commit is contained in:
Saufi
2026-06-03 08:51:22 +08:00
commit a14d43fe34
347 changed files with 38197 additions and 0 deletions

View File

@@ -0,0 +1,96 @@
<?php
namespace App\Http\Controllers;
use App\Http\Requests\Public\StorePublicApplicationRequest;
use App\Models\Application;
use App\Models\Election;
use App\Models\Position;
use App\Models\PusatMengundi;
use App\Services\Public\KtmVacancyService;
use App\Services\Public\PublicApplicationSubmissionService;
use App\Services\RegistrationPeriodService;
use App\Support\SensitiveData;
use Illuminate\Http\RedirectResponse;
use Illuminate\View\View;
class PublicApplicationController extends Controller
{
public function create(
PusatMengundi $pusatMengundi,
RegistrationPeriodService $registrationPeriodService,
KtmVacancyService $ktmVacancyService,
): View {
$pusatMengundi->loadMissing('daerahMengundi');
/** @var Election $election */
$election = $pusatMengundi->election()->with('settings')->firstOrFail();
if (! $registrationPeriodService->isOpen($election)) {
return view('public.applications.closed', [
'pusatMengundi' => $pusatMengundi,
'message' => $registrationPeriodService->closedMessage($election),
]);
}
return view('public.applications.create', [
'pusatMengundi' => $pusatMengundi,
'roles' => Position::query()
->whereIn('code', ['KTM', 'KP', 'KPDP', 'PAPM'])
->where('is_public_applyable', true)
->orderBy('sort_order')
->get(),
'ktmOptionsByRole' => $ktmVacancyService->optionsForRoles($pusatMengundi),
]);
}
public function store(
StorePublicApplicationRequest $request,
PusatMengundi $pusatMengundi,
PublicApplicationSubmissionService $submissionService,
RegistrationPeriodService $registrationPeriodService,
): RedirectResponse {
/** @var Election $election */
$election = $pusatMengundi->election()->with('settings')->firstOrFail();
if (! $registrationPeriodService->isOpen($election)) {
return redirect()
->route('public.applications.create', $pusatMengundi->public_uuid)
->withErrors(['registration' => $registrationPeriodService->closedMessage($election)]);
}
$application = $submissionService->submit($pusatMengundi, $request->validated());
return redirect()->route('public.applications.success', $application->public_uuid);
}
public function success(Application $application): View
{
return view('public.applications.success', [
'application' => $application->load(['pusatMengundi', 'requestedPosition']),
]);
}
public function status(string $publicUuid): View
{
// Query with withTrashed so soft-deleted records don't 404, allowing a uniform
// response for all unknown/invalid UUIDs to prevent enumeration.
$application = Application::withTrashed()
->where('public_uuid', $publicUuid)
->with(['pusatMengundi', 'requestedPosition', 'approvedPosition'])
->first();
// Treat soft-deleted and KTM-internal records as not found to avoid leaking
// information about whether a UUID ever existed.
if (! $application instanceof Application
|| $application->trashed()
|| $application->status === 'deleted_by_ktm'
) {
return view('public.applications.status', ['application' => null]);
}
return view('public.applications.status', [
'application' => $application,
'maskedName' => SensitiveData::maskName($application->name),
]);
}
}