diff --git a/be/app/Providers/FortifyServiceProvider.php b/be/app/Providers/FortifyServiceProvider.php index dd59b4c..d1d4f49 100644 --- a/be/app/Providers/FortifyServiceProvider.php +++ b/be/app/Providers/FortifyServiceProvider.php @@ -94,19 +94,31 @@ class FortifyServiceProvider extends ServiceProvider Fortify::authenticateUsing(function (Request $request) { $user = User::where('email', $request->email)->first(); - - // Bypass password check in local or development environments - $shouldBypassPassword = config('app.env', 'local'); - - if ($user && ($shouldBypassPassword || Hash::check($request->password, $user->password))) { - if (! $user->canAuthenticate()) { - throw ValidationException::withMessages([ - 'email' => [$user->getLoginRestrictionMessage()], - ]); - } + $invalidCredentialsMessage = 'Emel atau kata laluan tidak sah.'; - return $user; + $failLogin = function () use ($invalidCredentialsMessage): never { + throw ValidationException::withMessages([ + 'email' => [$invalidCredentialsMessage], + ]); + }; + + if (! $user) { + $failLogin(); } + + $shouldBypassPassword = config('app.env', 'local'); + + if (! $shouldBypassPassword && ! Hash::check($request->password, $user->password)) { + $failLogin(); + } + + if (! $user->canAuthenticate()) { + throw ValidationException::withMessages([ + 'email' => [$user->getLoginRestrictionMessage()], + ]); + } + + return $user; }); } } diff --git a/be/bootstrap/app.php b/be/bootstrap/app.php index 7746dd5..2bc4437 100644 --- a/be/bootstrap/app.php +++ b/be/bootstrap/app.php @@ -59,10 +59,13 @@ return Application::configure(basePath: dirname(__DIR__)) // Handle Validation exceptions (422 errors) $exceptions->render(function (Illuminate\Validation\ValidationException $e, $request) { if ($request->expectsJson()) { + $errors = $e->errors(); + $firstMessage = collect($errors)->flatten()->first() ?? 'Data tidak sah.'; + return response()->json([ 'success' => false, - 'message' => 'Data tidak sah.', - 'errors' => $e->errors(), + 'message' => $firstMessage, + 'errors' => $errors, ], 422); } }); diff --git a/fe/src/constants/employers.ts b/fe/src/constants/employers.ts index a170f44..c64bfc9 100644 --- a/fe/src/constants/employers.ts +++ b/fe/src/constants/employers.ts @@ -23,7 +23,7 @@ export const EMPLOYERS = [ }, { name: 'Xtra Biz Sdn Bhd (XBSB)', - address: "Lot 241, Jalan Dato' Cik Arif, Taman Mutiara 1, 15000 Kota Bharu, Kelantan.", + address: "-", }, { name: 'Pesara', diff --git a/fe/src/modules/membership-application/pages/MembershipApplicationEdit.vue b/fe/src/modules/membership-application/pages/MembershipApplicationEdit.vue index 9949187..aef9d75 100644 --- a/fe/src/modules/membership-application/pages/MembershipApplicationEdit.vue +++ b/fe/src/modules/membership-application/pages/MembershipApplicationEdit.vue @@ -58,6 +58,7 @@ import { ADMIN_ATTACHMENT_DOCUMENT_TYPE } from '../types/membership-application. import { APPLICANT_DOCUMENT_UPLOAD_TYPES, DOCUMENT_TYPE_LABELS, + EMPLOYER_OPTIONS, GENDER_OPTIONS, MARRIAGE_STATUS_OPTIONS, RELATIONSHIP_OPTIONS, @@ -67,6 +68,7 @@ import { createEmptyFormState, createSelectCollection, detailToFormState, + getEmployerAddress, labelToApiValue, } from '../utils/membership-application-form.utils' @@ -112,6 +114,7 @@ const referenceLookupLoading = reactive({ const genderCollection = createSelectCollection(GENDER_OPTIONS) const marriageStatusCollection = createSelectCollection(MARRIAGE_STATUS_OPTIONS) const relationshipCollection = createSelectCollection(RELATIONSHIP_OPTIONS) +const employerCollection = createSelectCollection(EMPLOYER_OPTIONS) const canEdit = computed( () => @@ -123,6 +126,7 @@ const genderInitial = computed(() => apiValueToLabel(GENDER_OPTIONS, form.applic const marriageStatusInitial = computed(() => apiValueToLabel(MARRIAGE_STATUS_OPTIONS, form.applicant.marriage_status), ) +const employerInitial = computed(() => apiValueToLabel(EMPLOYER_OPTIONS, form.applicant.employer_name)) const workflowProgress = computed(() => application.value ? getWorkflowProgress(application.value.status) : null, @@ -309,6 +313,14 @@ function setMarriageStatusValue(details: { value: string[] }) { delete fieldErrors['applicant.marriage_status'] } +function setEmployerValue(details: { value: string[] }) { + const employerName = labelToApiValue(EMPLOYER_OPTIONS, details.value[0]) + form.applicant.employer_name = employerName + form.applicant.employer_address = getEmployerAddress(employerName) + delete fieldErrors['applicant.employer_name'] + delete fieldErrors['applicant.employer_address'] +} + function setHeirRelationshipValue(index: number, details: { value: string[] }) { const heir = form.heirs[index] if (!heir) return @@ -859,8 +871,24 @@ onUnmounted(() => {
- Nama Majikan - + Nama Majikan + + + + + + + + + Nama Majikan + + {{ item.label }} + + + + {{ fieldErrors['applicant.employer_name'] }} @@ -872,7 +900,7 @@ onUnmounted(() => { Alamat Majikan -