DONE: update logo to original official logo, update letterhead and letterfooter layout

This commit is contained in:
ISMAIL MASSERAN
2026-07-07 12:26:28 +08:00
parent 1cc3351ca6
commit fb59917ebf
76 changed files with 547 additions and 402 deletions
@@ -110,6 +110,8 @@ const batchSuccessMessage = ref<string | null>(null)
const batchFailedItems = ref<BatchCompleteFailedItem[]>([])
const boardMeetingReference = ref('')
const boardMeetingReferenceError = ref<string | null>(null)
const boardMeetingDate = ref(dayjs().format('YYYY-MM-DD'))
const boardMeetingDateError = ref<string | null>(null)
const downloadingResultLetterId = ref<string | null>(null)
const selectableApplications = computed(() =>
@@ -162,6 +164,8 @@ function openBatchConfirm() {
if (!selectedIds.value.length) return
boardMeetingReference.value = ''
boardMeetingReferenceError.value = null
boardMeetingDate.value = dayjs().format('YYYY-MM-DD')
boardMeetingDateError.value = null
batchConfirmOpen.value = true
}
@@ -173,15 +177,23 @@ async function confirmBatchComplete() {
boardMeetingReferenceError.value = 'Rujukan mesyuarat lembaga diperlukan.'
return
}
if (!boardMeetingDate.value) {
boardMeetingDateError.value = 'Tarikh mesyuarat lembaga diperlukan.'
return
}
batchSubmitting.value = true
batchSuccessMessage.value = null
batchFailedItems.value = []
boardMeetingReferenceError.value = null
boardMeetingDateError.value = null
error.value = null
try {
const response = await batchCompleteMembershipApplications(selectedIds.value, reference)
const response = await batchCompleteMembershipApplications(selectedIds.value, {
board_meeting_reference: reference,
board_meeting_date: boardMeetingDate.value,
})
if (response.success) {
batchSuccessMessage.value = response.message
@@ -200,6 +212,7 @@ async function confirmBatchComplete() {
error.value = responseData.message ?? getApiErrorMessage(err, 'Gagal menyelesaikan permohonan.')
const validationErrors = getApiValidationErrors(err)
boardMeetingReferenceError.value = validationErrors?.board_meeting_reference?.[0] ?? null
boardMeetingDateError.value = validationErrors?.board_meeting_date?.[0] ?? null
} else {
error.value = getApiErrorMessage(err, 'Gagal menyelesaikan permohonan.')
}
@@ -245,30 +258,6 @@ function goToApplicationEdit(id: string) {
router.push({ name: 'edit-membership-application', params: { id } })
}
function canDownloadLetter(item: MembershipApplicationListItem): boolean {
return !!item.has_result_letter && !!item.result_letter_document
}
async function handleDownloadResultLetter(item: MembershipApplicationListItem) {
const document = item.result_letter_document
if (!document) return
downloadingResultLetterId.value = item.id
try {
await downloadMembershipApplicationDocument(
item.id,
document.id,
document.name,
document.mime_type,
)
} catch (err) {
error.value = getApiErrorMessage(err, 'Gagal memuat turun surat keputusan.')
} finally {
downloadingResultLetterId.value = null
}
}
const headers = computed<TableHeader[]>(() => {
const base: TableHeader[] = [
{ title: 'Bil.', key: '#', sortable: false },
@@ -450,12 +439,6 @@ const headers = computed<TableHeader[]>(() => {
@click="goToApplicationEdit((item as MembershipApplicationListItem).id)">
<Pencil class="size-4" aria-hidden="true" />
</Button>
<Button v-if="canDownloadLetter(item as MembershipApplicationListItem)" type="button" variant="ghost"
size="sm" class="bg-purple-600 text-white" title="Muat turun surat keputusan"
:disabled="downloadingResultLetterId === (item as MembershipApplicationListItem).id"
@click="handleDownloadResultLetter(item as MembershipApplicationListItem)">
<Download class="size-4" aria-hidden="true" />
</Button>
</div>
</template>
</DataTable>
@@ -475,6 +458,12 @@ const headers = computed<TableHeader[]>(() => {
@input="boardMeetingReferenceError = null" />
<FieldError v-if="boardMeetingReferenceError">{{ boardMeetingReferenceError }}</FieldError>
</Field>
<Field class="mt-4 text-left">
<FieldLabel for="batch-board-meeting-date">Tarikh Mesyuarat Lembaga</FieldLabel>
<Input id="batch-board-meeting-date" v-model="boardMeetingDate" type="date" :disabled="batchSubmitting"
@input="boardMeetingDateError = null" />
<FieldError v-if="boardMeetingDateError">{{ boardMeetingDateError }}</FieldError>
</Field>
</div>
<div class="px-5 pb-8 text-center">
<DialogCloseTrigger class="mr-2 w-32" :disabled="batchSubmitting">