commit 72ce2260c50597f782f07d29db3985607ecc2f34 Author: hasyim_kai <muhammad.hasyim.c.a@gmail.com> Date: Mon Nov 17 15:19:36 2025 +0700 Feat: add doc preview in Therpay protocol List commit 7032cd2409a660d40899ffd421137e4158cfde4a Author: hasyim_kai <muhammad.hasyim.c.a@gmail.com> Date: Wed Nov 12 15:34:30 2025 +0700 Fix: prepare API integration protokol terapi verification commit dbf6f78d00afc818baf2b34d128ee2153814cc88 Author: hasyim_kai <muhammad.hasyim.c.a@gmail.com> Date: Wed Nov 12 14:09:28 2025 +0700 Feat: add basic CRUD therapy protocol commit 46a44e90fe4d4097b5460d2d4e5689b2a5389467 Author: hasyim_kai <muhammad.hasyim.c.a@gmail.com> Date: Tue Nov 11 15:57:54 2025 +0700 Fix: Prepare protokol terapi API Integration commit 4674090566727cebd947e50e2c06c44e8c7afa7e Author: hasyim_kai <muhammad.hasyim.c.a@gmail.com> Date: Mon Nov 10 15:33:22 2025 +0700 Fix: hotfix style add protokol terapi commit 919c91abd8ef8b4cd193012eed7f5e8cf635cda2 Author: hasyim_kai <muhammad.hasyim.c.a@gmail.com> Date: Mon Nov 10 15:17:14 2025 +0700 Fix: Typo drpodown-action-p in protokol-terapi commit e21d30eacf1a08118e289d4bb64889e708d5023a Author: hasyim_kai <muhammad.hasyim.c.a@gmail.com> Date: Mon Nov 10 15:14:33 2025 +0700 Fix: add diagnose & procedure dialog picker in add protokol terapi commit 9a3d73b72b0dceea778d83e7630c5ead110a6a4c Author: hasyim_kai <muhammad.hasyim.c.a@gmail.com> Date: Tue Nov 4 10:21:24 2025 +0700 Fix: Add Schema therapy protocol rehab medik commit 4d8d2d633bbbd78038b1cc607558c1ceb31c5986 Author: hasyim_kai <muhammad.hasyim.c.a@gmail.com> Date: Tue Nov 4 09:30:55 2025 +0700 Fix: refactor Actions Btn ba-dr-su commit 5f290a6e4bd1559c0e5864a508c5ab650cfae6e8 Author: hasyim_kai <muhammad.hasyim.c.a@gmail.com> Date: Mon Nov 3 17:08:20 2025 +0700 Feat: UI protokol terapi in Rehab medik commit 63010f69ff30532bb8ac91443112f31d4942b221 Author: Khafid Prayoga <khafidp@pm.me> Date: Tue Oct 21 09:54:13 2025 +0700 wip: list protokol terapi commit 44eedc298680a5255fee0ee8feee3e24beda93dd Author: Khafid Prayoga <khafidp@pm.me> Date: Mon Oct 20 12:54:01 2025 +0700 feat(therapy-protocol): init form entry feat(therapy-protocol): init page routes wip: init entry form wip: form entry protokol terapi todo: table procedure, and diagnose picker wip: schema form new entry todo: picker/modal yang relateds ke form entry
262 lines
7.6 KiB
Vue
262 lines
7.6 KiB
Vue
<script setup lang="ts">
|
|
import type { HeaderPrep, RefSearchNav } from '~/components/pub/my-ui/data/types'
|
|
import type { Summary } from '~/components/pub/my-ui/summary-card/type'
|
|
|
|
// #region Imports
|
|
import { Calendar, Hospital, UserCheck, UsersRound } from 'lucide-vue-next'
|
|
import RecordConfirmation from '~/components/pub/my-ui/confirmation/record-confirmation.vue'
|
|
import { ActionEvents } from '~/components/pub/my-ui/data/types'
|
|
|
|
import Header from '~/components/pub/my-ui/nav-header/prep.vue'
|
|
import SummaryCard from '~/components/pub/my-ui/summary-card/summary-card.vue'
|
|
import { usePaginatedList } from '~/composables/usePaginatedList'
|
|
|
|
import { getList, remove } from '~/services/therapy-protocol.service'
|
|
import DetailRow from '~/components/pub/my-ui/form/view/detail-row.vue'
|
|
import Dialog from '~/components/pub/my-ui/modal/dialog.vue'
|
|
import Action from '~/components/pub/my-ui/nav-footer/ba-dr-su.vue'
|
|
import type { Encounter } from '~/models/encounter'
|
|
import { cn } from '~/lib/utils'
|
|
import { CalendarDate, DateFormatter, getLocalTimeZone } from '@internationalized/date'
|
|
import type { DateRange } from 'radix-vue'
|
|
import type { ExposedForm } from '~/types/form'
|
|
import { VerificationSchema } from '~/schemas/verification.schema'
|
|
import { handleActionSave } from '~/handlers/therapy-protocol.handler'
|
|
import { toast } from '~/components/pub/ui/toast'
|
|
import DocPreviewDialog from '~/components/pub/my-ui/modal/doc-preview-dialog.vue'
|
|
// #endregion
|
|
|
|
// Props
|
|
interface Props {
|
|
encounter: Encounter
|
|
}
|
|
const props = defineProps<Props>()
|
|
const route = useRoute()
|
|
const encounterId = typeof route.params.id == 'string' ? parseInt(route.params.id) : 0
|
|
// #endregion
|
|
|
|
// #region State
|
|
const isVerifyDialogOpen = ref(false)
|
|
const isHistoryDialogOpen = ref(false)
|
|
const isPatientInTherapy = ref(false)
|
|
const { data, isLoading, paginationMeta, searchInput, handlePageChange, handleSearch, fetchData } = usePaginatedList({
|
|
fetchFn: (params) => getList({ ...params }),
|
|
entityName: 'therapy-protocol',
|
|
})
|
|
|
|
const df = new DateFormatter('en-US', {
|
|
dateStyle: 'medium',
|
|
})
|
|
|
|
const dateValue = ref({
|
|
start: new CalendarDate(2022, 1, 20),
|
|
end: new CalendarDate(2022, 1, 20).add({ days: 20 }),
|
|
}) as Ref<DateRange>
|
|
|
|
const isRecordConfirmationOpen = ref(false)
|
|
const isDocPreviewDialogOpen = ref(false)
|
|
const summaryLoading = ref(false)
|
|
|
|
const inputForm = ref<ExposedForm<any> | null>(null)
|
|
const recId = ref<number>(0)
|
|
const recAction = ref<string>('')
|
|
const recItem = ref<any>(null)
|
|
const timestamp = ref<number>(0)
|
|
|
|
const isCaptchaValid = ref(false)
|
|
provide('isCaptchaValid', isCaptchaValid)
|
|
|
|
const headerPrep: HeaderPrep = {
|
|
title: "Protokol Terapi",
|
|
icon: 'i-lucide-newspaper',
|
|
addNav: {
|
|
label: "Protokol Terapi",
|
|
onClick: () => navigateTo({
|
|
name: 'rehab-encounter-id-therapy-protocol-add',
|
|
}),
|
|
},
|
|
}
|
|
// #endregion
|
|
|
|
// #region Lifecycle Hooks
|
|
onMounted(() => {
|
|
getPatientSummary()
|
|
|
|
const isInTherapy = false // TODO: determine if patient is in therapy
|
|
handleIsPatientInTherapy(isInTherapy)
|
|
})
|
|
// #endregion
|
|
|
|
// #region Functions
|
|
function handleIsPatientInTherapy(value: boolean) {
|
|
if (value) {
|
|
isPatientInTherapy.value = true
|
|
} else {
|
|
isPatientInTherapy.value = false
|
|
}
|
|
}
|
|
async function handleOpenHistory() {
|
|
isHistoryDialogOpen.value = true
|
|
console.log(`jalan history`)
|
|
}
|
|
async function getPatientSummary() {
|
|
try {
|
|
summaryLoading.value = true
|
|
await new Promise((resolve) => setTimeout(resolve, 500))
|
|
} catch (error) {
|
|
console.error('Error fetching patient summary:', error)
|
|
} finally {
|
|
summaryLoading.value = false
|
|
}
|
|
}
|
|
|
|
async function handleVerify() {
|
|
isVerifyDialogOpen.value = true
|
|
}
|
|
|
|
async function handleConfirmVerify() {
|
|
const inputData: any = await composeFormData()
|
|
const response = await handleActionSave(
|
|
inputData,
|
|
() => { },
|
|
() => { },
|
|
toast,
|
|
)
|
|
|
|
const data = (response?.body?.data ?? null)
|
|
if (!data) return
|
|
isVerifyDialogOpen.value = false
|
|
}
|
|
|
|
async function composeFormData(): Promise<any> {
|
|
const [input,] = await Promise.all([
|
|
inputForm.value?.validate(),
|
|
])
|
|
|
|
const results = [input]
|
|
const allValid = results.every((r) => r?.valid)
|
|
|
|
// exit, if form errors happend during validation
|
|
if (!allValid) return Promise.reject('Form validation failed')
|
|
|
|
const formData = input?.values
|
|
// formData.encounter_id = encounterId
|
|
|
|
return new Promise((resolve) => resolve(formData))
|
|
}
|
|
// #endregion region
|
|
|
|
// #region Utilities & event handlers
|
|
async function handleActionClick(eventType: string) {
|
|
if (eventType === 'submit') {
|
|
handleConfirmVerify()
|
|
}
|
|
|
|
if (eventType === 'back') {
|
|
isVerifyDialogOpen.value = false
|
|
}
|
|
}
|
|
// #endregion
|
|
|
|
// #region Provide
|
|
provide('rec_id', recId)
|
|
provide('rec_action', recAction)
|
|
provide('rec_item', recItem)
|
|
provide('timestamp', timestamp)
|
|
provide('table_data_loader', isLoading)
|
|
// #endregion
|
|
|
|
// #region Watchers
|
|
watch([recId, recAction, timestamp], () => {
|
|
switch (recAction.value) {
|
|
case ActionEvents.showDetail:
|
|
navigateTo({
|
|
name: 'therapy-protocol-id-detail',
|
|
params: { id: recId.value },
|
|
})
|
|
break
|
|
|
|
case ActionEvents.showEdit:
|
|
navigateTo({
|
|
name: 'rehab-encounter-id-therapy-protocol-therapy_protocol_id-edit',
|
|
params: { therapy_protocol_id: recId.value },
|
|
})
|
|
break
|
|
|
|
case ActionEvents.showConfirmVerify:
|
|
// Trigger confirmation modal open
|
|
handleVerify()
|
|
break
|
|
|
|
case ActionEvents.showPrint:
|
|
isDocPreviewDialogOpen.value = true
|
|
break
|
|
}
|
|
})
|
|
// #endregion
|
|
</script>
|
|
|
|
<template>
|
|
<Header :prep="{ ...headerPrep }" />
|
|
|
|
<section class="mb-5 flex justify-between items-center">
|
|
<!-- DATE RANGE -->
|
|
<Popover>
|
|
<PopoverTrigger as-child>
|
|
<Button variant="outline" :class="cn('w-[280px] justify-start text-left font-normal',
|
|
!dateValue && 'text-muted-foreground')">
|
|
<CalendarIcon class="mr-2 h-4 w-4" />
|
|
<template v-if="dateValue.start">
|
|
<template v-if="dateValue.end">
|
|
{{ df.format(dateValue.start.toDate(getLocalTimeZone())) }} -
|
|
{{ df.format(dateValue.end.toDate(getLocalTimeZone())) }}
|
|
</template>
|
|
|
|
<template v-else>
|
|
{{ df.format(dateValue.start.toDate(getLocalTimeZone())) }}
|
|
</template>
|
|
</template>
|
|
<template v-else> Pick a date </template>
|
|
</Button>
|
|
</PopoverTrigger>
|
|
<PopoverContent class="w-auto p-0">
|
|
<RangeCalendar v-model="dateValue" initial-focus :number-of-months="2"
|
|
@update:start-value="(startDate) => (dateValue.start = startDate)" />
|
|
</PopoverContent>
|
|
</Popover>
|
|
|
|
<!-- HISTORY -->
|
|
<Button variant="outline" :class="cn('',)" @click="handleOpenHistory">
|
|
<Icon name="i-lucide-history" class="h-4 w-4" />
|
|
History
|
|
</Button>
|
|
</section>
|
|
|
|
<AppTherapyProtocolCommonBannerPatientInTherapy
|
|
v-if="isPatientInTherapy"
|
|
class="mb-5" />
|
|
|
|
<AppTherapyProtocolList
|
|
:data="data"
|
|
:pagination-meta="paginationMeta"
|
|
@page-change="handlePageChange"/>
|
|
|
|
<Dialog v-model:open="isVerifyDialogOpen" title="Verifikasi">
|
|
<AppTherapyProtocolVerifyDialog
|
|
ref="inputForm"
|
|
:schema="VerificationSchema"
|
|
/>
|
|
<div class="flex justify-end">
|
|
<Action v-show="isCaptchaValid" :enable-draft="false" @click="handleActionClick" />
|
|
</div>
|
|
</Dialog>
|
|
|
|
<Dialog v-model:open="isHistoryDialogOpen" title="History" size="full">
|
|
<ContentTherapyProtocolHistoryList />
|
|
</Dialog>
|
|
|
|
<Dialog v-model:open="isDocPreviewDialogOpen" title="Preview Dokumen" size="2xl">
|
|
<!-- <DocPreviewDialog :link="recItem.url" /> -->
|
|
<DocPreviewDialog :link="`https://www.antennahouse.com/hubfs/xsl-fo-sample/pdf/basic-link-1.pdf`" />
|
|
</Dialog>
|
|
</template> |