Dev/v1.1 (#2)
Co-authored-by: ISMAIL MASSERAN <topaz@ISMAILs-Macbook.local> Reviewed-on: #2
This commit was merged in pull request #2.
This commit is contained in:
@@ -37,6 +37,12 @@ import {
|
||||
updateMembershipApplication,
|
||||
uploadMembershipApplicationDocument,
|
||||
} from '../services/membership-application.service'
|
||||
import {
|
||||
reviewDecisionBadgeLook,
|
||||
reviewDecisionBadgeVariant,
|
||||
statusBadgeLook,
|
||||
statusBadgeVariant,
|
||||
} from '../utils/membership-application-badge.utils'
|
||||
import type {
|
||||
DocumentUploadType,
|
||||
MembershipApplicationDetail,
|
||||
@@ -166,13 +172,6 @@ function statusLabel(status: MembershipApplicationStatus): string {
|
||||
return labels[status] ?? status
|
||||
}
|
||||
|
||||
function statusBadgeVariant(status: MembershipApplicationStatus) {
|
||||
if (status === 'COMPLETED') return 'success'
|
||||
if (status === 'MANAGEMENT_REJECTED') return 'danger'
|
||||
if (status === 'PENDING_BOARD' || status === 'PENDING_NOTIFICATION') return 'pending'
|
||||
return 'outline'
|
||||
}
|
||||
|
||||
function workflowStepButtonClass(stepId: number) {
|
||||
const progress = workflowProgress.value
|
||||
if (!progress) return 'mx-2 size-12 rounded-full shadow-none bg-background border border-foreground/15'
|
||||
@@ -268,20 +267,6 @@ function reviewDecisionLabel(decision: string | null, stage: string): string {
|
||||
return decision
|
||||
}
|
||||
|
||||
function reviewDecisionBadgeVariant(decision: string | null, stage: string) {
|
||||
if (stage === 'MANAGEMENT') {
|
||||
if (decision === 'APPROVED') return 'success'
|
||||
if (decision === 'REJECTED') return 'danger'
|
||||
}
|
||||
|
||||
if (stage === 'BOARD') {
|
||||
if (decision === 'PASS') return 'success'
|
||||
if (decision === 'FAIL') return 'danger'
|
||||
}
|
||||
|
||||
return 'outline'
|
||||
}
|
||||
|
||||
function reviewTimelineDotClass(review: MembershipApplicationReviewDetail): string {
|
||||
const variant = reviewDecisionBadgeVariant(review.decision, review.stage)
|
||||
|
||||
@@ -543,12 +528,8 @@ onUnmounted(() => {
|
||||
{{ application.application_number }} · {{ application.applicant?.name ?? '-' }}
|
||||
</p>
|
||||
</div>
|
||||
<Button
|
||||
look="outline"
|
||||
variant="secondary"
|
||||
type="button"
|
||||
@click="router.push({ name: 'view-membership-application', params: { id: applicationId } })"
|
||||
>
|
||||
<Button look="outline" variant="secondary" type="button"
|
||||
@click="router.push({ name: 'view-membership-application', params: { id: applicationId } })">
|
||||
Lihat
|
||||
</Button>
|
||||
<Button look="outline" variant="secondary" type="button"
|
||||
@@ -581,7 +562,8 @@ onUnmounted(() => {
|
||||
<div class="text-xl font-semibold">{{ application.application_number }}</div>
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<Badge :variant="statusBadgeVariant(application.status)" class="whitespace-nowrap">
|
||||
<Badge :variant="statusBadgeVariant(application.status)" :look="statusBadgeLook(application.status)"
|
||||
class="whitespace-nowrap">
|
||||
{{ statusLabel(application.status) }}
|
||||
</Badge>
|
||||
<Badge v-if="application.board_result"
|
||||
@@ -620,7 +602,7 @@ onUnmounted(() => {
|
||||
<div v-for="step in WORKFLOW_STEPS" :key="step.id"
|
||||
class="z-10 flex flex-1 items-center lg:block lg:text-center">
|
||||
<Button type="button" :class="workflowStepButtonClass(step.id)"
|
||||
:variant="step.id === workflowProgress?.currentStep && application.status !== 'COMPLETED' && !workflowProgress?.failed ? 'default' : 'ghost'"
|
||||
:variant="step.id === workflowProgress?.currentStep && application.status !== 'COMPLETED' && !workflowProgress?.failed ? 'primary' : 'ghost'"
|
||||
disabled>
|
||||
{{ step.id }}
|
||||
</Button>
|
||||
@@ -635,29 +617,39 @@ onUnmounted(() => {
|
||||
<Box raised="single" class="w-full p-0">
|
||||
<div class="w-full px-5 py-4">
|
||||
<TabsList class="mb-0 flex w-full">
|
||||
<TabsTrigger class="inline-flex min-w-0 flex-1 items-center justify-center whitespace-nowrap px-2 text-xs sm:px-3 sm:text-sm" value="personal">
|
||||
<TabsTrigger
|
||||
class="inline-flex min-w-0 flex-1 items-center justify-center whitespace-nowrap px-2 text-xs sm:px-3 sm:text-sm"
|
||||
value="personal">
|
||||
Maklumat Peribadi
|
||||
</TabsTrigger>
|
||||
<TabsTrigger class="inline-flex min-w-0 flex-1 items-center justify-center whitespace-nowrap px-2 text-xs sm:px-3 sm:text-sm" value="contact">
|
||||
<TabsTrigger
|
||||
class="inline-flex min-w-0 flex-1 items-center justify-center whitespace-nowrap px-2 text-xs sm:px-3 sm:text-sm"
|
||||
value="contact">
|
||||
Hubungan & Alamat
|
||||
</TabsTrigger>
|
||||
<TabsTrigger class="inline-flex min-w-0 flex-1 items-center justify-center whitespace-nowrap px-2 text-xs sm:px-3 sm:text-sm" value="employment">
|
||||
<TabsTrigger
|
||||
class="inline-flex min-w-0 flex-1 items-center justify-center whitespace-nowrap px-2 text-xs sm:px-3 sm:text-sm"
|
||||
value="employment">
|
||||
Pekerjaan & Caruman
|
||||
</TabsTrigger>
|
||||
<TabsTrigger class="inline-flex min-w-0 flex-1 items-center justify-center whitespace-nowrap px-2 text-xs sm:px-3 sm:text-sm" value="heirs">
|
||||
<TabsTrigger
|
||||
class="inline-flex min-w-0 flex-1 items-center justify-center whitespace-nowrap px-2 text-xs sm:px-3 sm:text-sm"
|
||||
value="heirs">
|
||||
Waris
|
||||
</TabsTrigger>
|
||||
<TabsTrigger class="inline-flex min-w-0 flex-1 items-center justify-center whitespace-nowrap px-2 text-xs sm:px-3 sm:text-sm" value="references">
|
||||
<TabsTrigger
|
||||
class="inline-flex min-w-0 flex-1 items-center justify-center whitespace-nowrap px-2 text-xs sm:px-3 sm:text-sm"
|
||||
value="references">
|
||||
Pencadang & Penyokong
|
||||
</TabsTrigger>
|
||||
<TabsTrigger class="inline-flex min-w-0 flex-1 items-center justify-center whitespace-nowrap px-2 text-xs sm:px-3 sm:text-sm" value="documents">
|
||||
<TabsTrigger
|
||||
class="inline-flex min-w-0 flex-1 items-center justify-center whitespace-nowrap px-2 text-xs sm:px-3 sm:text-sm"
|
||||
value="documents">
|
||||
Dokumen
|
||||
</TabsTrigger>
|
||||
<TabsTrigger
|
||||
v-if="application.reviews.length"
|
||||
<TabsTrigger v-if="application.reviews.length"
|
||||
class="inline-flex min-w-0 flex-1 items-center justify-center whitespace-nowrap px-2 text-xs sm:px-3 sm:text-sm"
|
||||
value="reviews"
|
||||
>
|
||||
value="reviews">
|
||||
Sejarah Semakan
|
||||
</TabsTrigger>
|
||||
</TabsList>
|
||||
@@ -679,28 +671,25 @@ onUnmounted(() => {
|
||||
<Field class="col-span-12 sm:col-span-6">
|
||||
<FieldLabel for="ic_number">No. Kad Pengenalan</FieldLabel>
|
||||
<Input id="ic_number" v-model="form.applicant.ic_number" type="text" :disabled="!canEdit" />
|
||||
<FieldError v-if="fieldErrors['applicant.ic_number']">{{ fieldErrors['applicant.ic_number'] }}</FieldError>
|
||||
<FieldError v-if="fieldErrors['applicant.ic_number']">{{ fieldErrors['applicant.ic_number'] }}
|
||||
</FieldError>
|
||||
</Field>
|
||||
<Field class="col-span-12 sm:col-span-6">
|
||||
<FieldLabel for="birth_date">Tarikh Lahir</FieldLabel>
|
||||
<Input id="birth_date" v-model="form.applicant.birth_date" type="date" :disabled="!canEdit" />
|
||||
<FieldError v-if="fieldErrors['applicant.birth_date']">{{ fieldErrors['applicant.birth_date'] }}</FieldError>
|
||||
<FieldError v-if="fieldErrors['applicant.birth_date']">{{ fieldErrors['applicant.birth_date'] }}
|
||||
</FieldError>
|
||||
</Field>
|
||||
<Field class="col-span-12 sm:col-span-6">
|
||||
<FieldLabel for="birth_place">Tempat Lahir</FieldLabel>
|
||||
<Input id="birth_place" v-model="form.applicant.birth_place" type="text" :disabled="!canEdit" />
|
||||
<FieldError v-if="fieldErrors['applicant.birth_place']">{{ fieldErrors['applicant.birth_place'] }}</FieldError>
|
||||
<FieldError v-if="fieldErrors['applicant.birth_place']">{{ fieldErrors['applicant.birth_place'] }}
|
||||
</FieldError>
|
||||
</Field>
|
||||
<Field class="col-span-12 sm:col-span-6">
|
||||
<FieldLabel>Jantina</FieldLabel>
|
||||
<SelectRoot
|
||||
:key="`gender-${form.applicant.gender}`"
|
||||
class="w-full"
|
||||
:collection="genderCollection"
|
||||
:default-value="genderInitial"
|
||||
:disabled="!canEdit"
|
||||
@value-change="setGenderValue"
|
||||
>
|
||||
<SelectRoot :key="`gender-${form.applicant.gender}`" class="w-full" :collection="genderCollection"
|
||||
:default-value="genderInitial" :disabled="!canEdit" @value-change="setGenderValue">
|
||||
<SelectControl>
|
||||
<SelectTrigger :aria-invalid="!!fieldErrors['applicant.gender']">
|
||||
<SelectValueText placeholder="Pilih jantina" />
|
||||
@@ -719,14 +708,9 @@ onUnmounted(() => {
|
||||
</Field>
|
||||
<Field class="col-span-12 sm:col-span-6">
|
||||
<FieldLabel>Status Perkahwinan</FieldLabel>
|
||||
<SelectRoot
|
||||
:key="`marriage-${form.applicant.marriage_status}`"
|
||||
class="w-full"
|
||||
:collection="marriageStatusCollection"
|
||||
:default-value="marriageStatusInitial"
|
||||
:disabled="!canEdit"
|
||||
@value-change="setMarriageStatusValue"
|
||||
>
|
||||
<SelectRoot :key="`marriage-${form.applicant.marriage_status}`" class="w-full"
|
||||
:collection="marriageStatusCollection" :default-value="marriageStatusInitial" :disabled="!canEdit"
|
||||
@value-change="setMarriageStatusValue">
|
||||
<SelectControl>
|
||||
<SelectTrigger :aria-invalid="!!fieldErrors['applicant.marriage_status']">
|
||||
<SelectValueText placeholder="Pilih status" />
|
||||
@@ -741,7 +725,8 @@ onUnmounted(() => {
|
||||
</SelectItemGroup>
|
||||
</SelectContent>
|
||||
</SelectRoot>
|
||||
<FieldError v-if="fieldErrors['applicant.marriage_status']">{{ fieldErrors['applicant.marriage_status'] }}</FieldError>
|
||||
<FieldError v-if="fieldErrors['applicant.marriage_status']">{{ fieldErrors['applicant.marriage_status'] }}
|
||||
</FieldError>
|
||||
</Field>
|
||||
</div>
|
||||
</TabsContent>
|
||||
@@ -756,12 +741,14 @@ onUnmounted(() => {
|
||||
<Field class="col-span-12 sm:col-span-4">
|
||||
<FieldLabel for="phone_number">No. Telefon</FieldLabel>
|
||||
<Input id="phone_number" v-model="form.applicant.phone_number" type="text" :disabled="!canEdit" />
|
||||
<FieldError v-if="fieldErrors['applicant.phone_number']">{{ fieldErrors['applicant.phone_number'] }}</FieldError>
|
||||
<FieldError v-if="fieldErrors['applicant.phone_number']">{{ fieldErrors['applicant.phone_number'] }}
|
||||
</FieldError>
|
||||
</Field>
|
||||
<Field class="col-span-12 sm:col-span-4">
|
||||
<FieldLabel for="office_number">No. Pejabat</FieldLabel>
|
||||
<Input id="office_number" v-model="form.applicant.office_number" type="text" :disabled="!canEdit" />
|
||||
<FieldError v-if="fieldErrors['applicant.office_number']">{{ fieldErrors['applicant.office_number'] }}</FieldError>
|
||||
<FieldError v-if="fieldErrors['applicant.office_number']">{{ fieldErrors['applicant.office_number'] }}
|
||||
</FieldError>
|
||||
</Field>
|
||||
<Field class="col-span-12 sm:col-span-4">
|
||||
<FieldLabel for="postcode">Poskod</FieldLabel>
|
||||
@@ -776,51 +763,51 @@ onUnmounted(() => {
|
||||
<Field class="col-span-12 sm:col-span-6">
|
||||
<FieldLabel for="employer_name">Nama Majikan</FieldLabel>
|
||||
<Input id="employer_name" v-model="form.applicant.employer_name" type="text" :disabled="!canEdit" />
|
||||
<FieldError v-if="fieldErrors['applicant.employer_name']">{{ fieldErrors['applicant.employer_name'] }}</FieldError>
|
||||
<FieldError v-if="fieldErrors['applicant.employer_name']">{{ fieldErrors['applicant.employer_name'] }}
|
||||
</FieldError>
|
||||
</Field>
|
||||
<Field class="col-span-12 sm:col-span-6">
|
||||
<FieldLabel for="current_position">Jawatan Semasa</FieldLabel>
|
||||
<Input id="current_position" v-model="form.applicant.current_position" type="text" :disabled="!canEdit" />
|
||||
<FieldError v-if="fieldErrors['applicant.current_position']">{{ fieldErrors['applicant.current_position'] }}</FieldError>
|
||||
<FieldError v-if="fieldErrors['applicant.current_position']">{{ fieldErrors['applicant.current_position']
|
||||
}}</FieldError>
|
||||
</Field>
|
||||
<Field class="col-span-12">
|
||||
<FieldLabel for="employer_address">Alamat Majikan</FieldLabel>
|
||||
<Textarea id="employer_address" v-model="form.applicant.employer_address" rows="3" :disabled="!canEdit" />
|
||||
<FieldError v-if="fieldErrors['applicant.employer_address']">{{ fieldErrors['applicant.employer_address'] }}</FieldError>
|
||||
<FieldError v-if="fieldErrors['applicant.employer_address']">{{ fieldErrors['applicant.employer_address']
|
||||
}}</FieldError>
|
||||
</Field>
|
||||
<Field class="col-span-12 sm:col-span-4">
|
||||
<FieldLabel for="start_work_date">Tarikh Mula Berkhidmat</FieldLabel>
|
||||
<Input id="start_work_date" v-model="form.applicant.start_work_date" type="date" :disabled="!canEdit" />
|
||||
<FieldError v-if="fieldErrors['applicant.start_work_date']">{{ fieldErrors['applicant.start_work_date'] }}</FieldError>
|
||||
<FieldError v-if="fieldErrors['applicant.start_work_date']">{{ fieldErrors['applicant.start_work_date'] }}
|
||||
</FieldError>
|
||||
</Field>
|
||||
<Field class="col-span-12 sm:col-span-4">
|
||||
<FieldLabel for="stock_monthly_contribution">Caruman Saham (RM)</FieldLabel>
|
||||
<Input id="stock_monthly_contribution" v-model="form.applicant.stock_monthly_contribution" type="number"
|
||||
min="0" step="0.01" :disabled="!canEdit" />
|
||||
<FieldError v-if="fieldErrors['applicant.stock_monthly_contribution']">{{ fieldErrors['applicant.stock_monthly_contribution'] }}</FieldError>
|
||||
<FieldError v-if="fieldErrors['applicant.stock_monthly_contribution']">{{
|
||||
fieldErrors['applicant.stock_monthly_contribution'] }}</FieldError>
|
||||
</Field>
|
||||
<Field class="col-span-12 sm:col-span-4">
|
||||
<FieldLabel for="fee_monthly_contribution">Caruman Yuran (RM)</FieldLabel>
|
||||
<Input id="fee_monthly_contribution" v-model="form.applicant.fee_monthly_contribution" type="number"
|
||||
min="0" step="0.01" :disabled="!canEdit" />
|
||||
<FieldError v-if="fieldErrors['applicant.fee_monthly_contribution']">{{ fieldErrors['applicant.fee_monthly_contribution'] }}</FieldError>
|
||||
<FieldError v-if="fieldErrors['applicant.fee_monthly_contribution']">{{
|
||||
fieldErrors['applicant.fee_monthly_contribution'] }}</FieldError>
|
||||
</Field>
|
||||
</div>
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="heirs" class="mt-6">
|
||||
<div class="space-y-4">
|
||||
<div v-for="(heir, index) in form.heirs" :key="index"
|
||||
class="rounded-lg border border-foreground/10 p-4">
|
||||
<div v-for="(heir, index) in form.heirs" :key="index" class="rounded-lg border border-foreground/10 p-4">
|
||||
<div class="mb-4 flex items-center justify-between">
|
||||
<div class="font-medium">Waris {{ index + 1 }}</div>
|
||||
<Button
|
||||
v-if="canEdit && form.heirs.length > 1"
|
||||
type="button"
|
||||
look="outline"
|
||||
size="sm"
|
||||
@click="removeHeir(index)"
|
||||
>
|
||||
<Button v-if="canEdit && form.heirs.length > 1" type="button" look="outline" size="sm"
|
||||
@click="removeHeir(index)">
|
||||
Buang
|
||||
</Button>
|
||||
</div>
|
||||
@@ -828,23 +815,21 @@ onUnmounted(() => {
|
||||
<Field class="col-span-12 sm:col-span-6">
|
||||
<FieldLabel :for="`heir-name-${index}`">Nama</FieldLabel>
|
||||
<Input :id="`heir-name-${index}`" v-model="heir.name" type="text" :disabled="!canEdit" />
|
||||
<FieldError v-if="fieldErrors[`heirs.${index}.name`]">{{ fieldErrors[`heirs.${index}.name`] }}</FieldError>
|
||||
<FieldError v-if="fieldErrors[`heirs.${index}.name`]">{{ fieldErrors[`heirs.${index}.name`] }}
|
||||
</FieldError>
|
||||
</Field>
|
||||
<Field class="col-span-12 sm:col-span-6">
|
||||
<FieldLabel :for="`heir-ic-${index}`">No. Kad Pengenalan</FieldLabel>
|
||||
<Input :id="`heir-ic-${index}`" v-model="heir.ic_number" type="text" :disabled="!canEdit" />
|
||||
<FieldError v-if="fieldErrors[`heirs.${index}.ic_number`]">{{ fieldErrors[`heirs.${index}.ic_number`] }}</FieldError>
|
||||
<FieldError v-if="fieldErrors[`heirs.${index}.ic_number`]">{{ fieldErrors[`heirs.${index}.ic_number`]
|
||||
}}</FieldError>
|
||||
</Field>
|
||||
<Field class="col-span-12 sm:col-span-6">
|
||||
<FieldLabel>Hubungan</FieldLabel>
|
||||
<SelectRoot
|
||||
:key="`heir-relationship-${index}-${heir.relationship}`"
|
||||
class="w-full"
|
||||
<SelectRoot :key="`heir-relationship-${index}-${heir.relationship}`" class="w-full"
|
||||
:collection="relationshipCollection"
|
||||
:default-value="apiValueToLabel(RELATIONSHIP_OPTIONS, heir.relationship)"
|
||||
:disabled="!canEdit"
|
||||
@value-change="(details) => setHeirRelationshipValue(index, details)"
|
||||
>
|
||||
:default-value="apiValueToLabel(RELATIONSHIP_OPTIONS, heir.relationship)" :disabled="!canEdit"
|
||||
@value-change="(details) => setHeirRelationshipValue(index, details)">
|
||||
<SelectControl>
|
||||
<SelectTrigger :aria-invalid="!!fieldErrors[`heirs.${index}.relationship`]">
|
||||
<SelectValueText placeholder="Pilih hubungan" />
|
||||
@@ -859,12 +844,14 @@ onUnmounted(() => {
|
||||
</SelectItemGroup>
|
||||
</SelectContent>
|
||||
</SelectRoot>
|
||||
<FieldError v-if="fieldErrors[`heirs.${index}.relationship`]">{{ fieldErrors[`heirs.${index}.relationship`] }}</FieldError>
|
||||
<FieldError v-if="fieldErrors[`heirs.${index}.relationship`]">{{
|
||||
fieldErrors[`heirs.${index}.relationship`] }}</FieldError>
|
||||
</Field>
|
||||
<Field class="col-span-12 sm:col-span-6">
|
||||
<FieldLabel :for="`heir-phone-${index}`">No. Telefon</FieldLabel>
|
||||
<Input :id="`heir-phone-${index}`" v-model="heir.phone_number" type="text" :disabled="!canEdit" />
|
||||
<FieldError v-if="fieldErrors[`heirs.${index}.phone_number`]">{{ fieldErrors[`heirs.${index}.phone_number`] }}</FieldError>
|
||||
<FieldError v-if="fieldErrors[`heirs.${index}.phone_number`]">{{
|
||||
fieldErrors[`heirs.${index}.phone_number`] }}</FieldError>
|
||||
</Field>
|
||||
</div>
|
||||
</div>
|
||||
@@ -882,15 +869,9 @@ onUnmounted(() => {
|
||||
<div class="grid grid-cols-12 gap-4 gap-y-5">
|
||||
<Field class="col-span-12 sm:col-span-6">
|
||||
<FieldLabel for="proposer_ic_number">No. KP Pencadang</FieldLabel>
|
||||
<Input
|
||||
id="proposer_ic_number"
|
||||
v-model="form.references.proposer.ic_number"
|
||||
type="text"
|
||||
placeholder="Contoh: 900101011234"
|
||||
:disabled="!canEdit || referenceLookupLoading.proposer"
|
||||
@input="handleReferenceIcInput('proposer')"
|
||||
@blur="lookupReference('proposer')"
|
||||
/>
|
||||
<Input id="proposer_ic_number" v-model="form.references.proposer.ic_number" type="text"
|
||||
placeholder="Contoh: 900101011234" :disabled="!canEdit || referenceLookupLoading.proposer"
|
||||
@input="handleReferenceIcInput('proposer')" @blur="lookupReference('proposer')" />
|
||||
<p v-if="form.references.proposer.name" class="mt-1 text-sm text-success">
|
||||
{{ form.references.proposer.name }}
|
||||
</p>
|
||||
@@ -900,15 +881,9 @@ onUnmounted(() => {
|
||||
</Field>
|
||||
<Field class="col-span-12 sm:col-span-6">
|
||||
<FieldLabel for="supporter_ic_number">No. KP Penyokong</FieldLabel>
|
||||
<Input
|
||||
id="supporter_ic_number"
|
||||
v-model="form.references.supporter.ic_number"
|
||||
type="text"
|
||||
placeholder="Contoh: 850505055678"
|
||||
:disabled="!canEdit || referenceLookupLoading.supporter"
|
||||
@input="handleReferenceIcInput('supporter')"
|
||||
@blur="lookupReference('supporter')"
|
||||
/>
|
||||
<Input id="supporter_ic_number" v-model="form.references.supporter.ic_number" type="text"
|
||||
placeholder="Contoh: 850505055678" :disabled="!canEdit || referenceLookupLoading.supporter"
|
||||
@input="handleReferenceIcInput('supporter')" @blur="lookupReference('supporter')" />
|
||||
<p v-if="form.references.supporter.name" class="mt-1 text-sm text-success">
|
||||
{{ form.references.supporter.name }}
|
||||
</p>
|
||||
@@ -925,11 +900,7 @@ onUnmounted(() => {
|
||||
Muat naik fail baharu untuk menggantikan dokumen sedia ada.
|
||||
</div>
|
||||
<div class="space-y-4">
|
||||
<div
|
||||
v-for="type in DOCUMENT_UPLOAD_TYPES"
|
||||
:key="type"
|
||||
class="rounded-lg border border-foreground/10 p-4"
|
||||
>
|
||||
<div v-for="type in DOCUMENT_UPLOAD_TYPES" :key="type" class="rounded-lg border border-foreground/10 p-4">
|
||||
<div class="flex flex-wrap items-start justify-between gap-3">
|
||||
<div>
|
||||
<div class="font-medium">{{ DOCUMENT_TYPE_LABELS[type] }}</div>
|
||||
@@ -939,23 +910,15 @@ onUnmounted(() => {
|
||||
<div v-else class="mt-1 text-sm opacity-70">Tiada dokumen dimuat naik.</div>
|
||||
</div>
|
||||
<div v-if="documentsByType[type]" class="flex flex-wrap items-center gap-2">
|
||||
<Button
|
||||
type="button"
|
||||
look="outline"
|
||||
size="sm"
|
||||
<Button type="button" look="outline" size="sm"
|
||||
:disabled="previewLoading && previewDocument?.id === documentsByType[type]?.id"
|
||||
@click="documentsByType[type] && handleViewDocument(documentsByType[type]!)"
|
||||
>
|
||||
@click="documentsByType[type] && handleViewDocument(documentsByType[type]!)">
|
||||
<Eye class="mr-2 size-4" />
|
||||
Lihat
|
||||
</Button>
|
||||
<Button
|
||||
type="button"
|
||||
look="outline"
|
||||
size="sm"
|
||||
<Button type="button" look="outline" size="sm"
|
||||
:disabled="downloadingDocumentId === documentsByType[type]?.id"
|
||||
@click="documentsByType[type] && handleDownloadDocument(documentsByType[type]!)"
|
||||
>
|
||||
@click="documentsByType[type] && handleDownloadDocument(documentsByType[type]!)">
|
||||
<Download class="mr-2 size-4" />
|
||||
Muat Turun
|
||||
</Button>
|
||||
@@ -965,13 +928,8 @@ onUnmounted(() => {
|
||||
<FieldLabel :for="`document-${type}`">
|
||||
{{ documentsByType[type] ? 'Ganti Dokumen' : 'Muat Naik Dokumen' }}
|
||||
</FieldLabel>
|
||||
<Input
|
||||
:id="`document-${type}`"
|
||||
type="file"
|
||||
:accept="documentAccept(type)"
|
||||
:disabled="uploadingDocumentType === type"
|
||||
@change="handleDocumentUpload(type, $event)"
|
||||
/>
|
||||
<Input :id="`document-${type}`" type="file" :accept="documentAccept(type)"
|
||||
:disabled="uploadingDocumentType === type" @change="handleDocumentUpload(type, $event)" />
|
||||
<FieldError v-if="fieldErrors[`documents.${type}`]">{{ fieldErrors[`documents.${type}`] }}</FieldError>
|
||||
<p v-if="uploadingDocumentType === type" class="mt-1 text-sm opacity-70">Memuat naik...</p>
|
||||
</Field>
|
||||
@@ -981,19 +939,11 @@ onUnmounted(() => {
|
||||
|
||||
<TabsContent v-if="application.reviews.length" value="reviews" class="mt-6">
|
||||
<div class="relative ms-3 ps-8">
|
||||
<div
|
||||
v-for="(review, index) in sortedReviews"
|
||||
:key="review.id"
|
||||
class="relative pb-8 last:pb-0"
|
||||
>
|
||||
<span
|
||||
class="absolute -start-8 top-1.5 flex size-3.5 rounded-full border-2 ring-4 ring-background"
|
||||
:class="reviewTimelineDotClass(review)"
|
||||
/>
|
||||
<span
|
||||
v-if="index < sortedReviews.length - 1"
|
||||
class="absolute -start-[1.375rem] top-5 h-[calc(100%-0.25rem)] w-px bg-foreground/15"
|
||||
/>
|
||||
<div v-for="(review, index) in sortedReviews" :key="review.id" class="relative pb-8 last:pb-0">
|
||||
<span class="absolute -inset-s-8 top-1.5 flex size-3.5 rounded-full border-2 ring-4 ring-background"
|
||||
:class="reviewTimelineDotClass(review)" />
|
||||
<span v-if="index < sortedReviews.length - 1"
|
||||
class="absolute -inset-s-5.5 top-5 h-[calc(100%-0.25rem)] w-px bg-foreground/15" />
|
||||
|
||||
<div class="rounded-lg border border-foreground/10 p-4">
|
||||
<div class="flex flex-wrap items-start justify-between gap-2">
|
||||
@@ -1003,10 +953,8 @@ onUnmounted(() => {
|
||||
{{ formatDateTime(review.reviewed_at) }}
|
||||
</div>
|
||||
</div>
|
||||
<Badge
|
||||
:variant="reviewDecisionBadgeVariant(review.decision, review.stage)"
|
||||
class="whitespace-nowrap"
|
||||
>
|
||||
<Badge :variant="reviewDecisionBadgeVariant(review.decision, review.stage)"
|
||||
:look="reviewDecisionBadgeLook(review.decision, review.stage)" class="whitespace-nowrap">
|
||||
{{ reviewDecisionLabel(review.decision, review.stage) }}
|
||||
</Badge>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user