feat(sep): introduce PatientData interface and update select-radio component to include menu property

This commit is contained in:
riefive
2025-10-24 13:46:54 +07:00
parent 80f75a3c02
commit aea4c3cd5c
5 changed files with 110 additions and 7 deletions
+9 -2
View File
@@ -2,7 +2,14 @@ import type { Config } from '~/components/pub/my-ui/data-table'
import { defineAsyncComponent } from 'vue'
const SelectedRadio = defineAsyncComponent(() => import('./select-radio.vue'))
const action = defineAsyncComponent(() => import('~/components/pub/my-ui/data/dropdown-action-dud.vue'))
export interface PatientData {
id: string
identity: string
number: string
bpjs: string
name: string
}
export const config: Config = {
cols: [{ width: 50 }, { width: 100 }, { width: 100 }, { width: 100 }, { width: 100 }],
@@ -24,7 +31,7 @@ export const config: Config = {
check(rec, idx) {
return {
idx,
rec: rec as object,
rec: { ...rec as object, menu: 'patient' },
component: SelectedRadio,
}
},
+2 -2
View File
@@ -3,14 +3,14 @@
import PaginationView from '~/components/pub/my-ui/pagination/pagination-view.vue'
// Types
import type { SepHistoryData } from './list-cfg.history'
import type { PatientData } from './list-cfg.patient'
import type { PaginationMeta } from '~/components/pub/my-ui/pagination/pagination.type'
// Configs
import { config } from './list-cfg.patient'
const props = defineProps<{
data: SepHistoryData[]
data: PatientData[]
paginationMeta?: PaginationMeta
}>()
+4 -2
View File
@@ -3,11 +3,12 @@
import { RadioGroup, RadioGroupItem } from '~/components/pub/ui/radio-group'
const props = defineProps<{
rec: { id: string; name: string }
rec: { id: string; name: string; menu: string }
}>()
const recId = inject<Ref<number>>('rec_id')!
const record = props.rec || {}
const recId = inject<Ref<number>>('rec_select_id')!
const recMenu = inject<Ref<string>>('rec_select_menu')!
const selected = ref<string>('')
</script>
@@ -17,6 +18,7 @@ const selected = ref<string>('')
@update:model-value="
() => {
recId = Number(record.id) || 0
recMenu = record.menu || ''
}
"
>
+93
View File
@@ -0,0 +1,93 @@
<script setup lang="ts">
import { ref } from 'vue'
// Components
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
DialogTrigger,
DialogFooter,
} from '~/components/pub/ui/dialog'
import { Button } from '~/components/pub/ui/button'
import { Input } from '~/components/pub/ui/input'
import ListPatient from './list-patient.vue'
// Types
import type { PatientData } from './list-cfg.patient'
import type { PaginationMeta } from '~/components/pub/my-ui/pagination/pagination.type'
// Helpers
import { refDebounced } from '@vueuse/core'
const props = defineProps<{
open: boolean
patients: Array<PatientData>
selected: string
paginationMeta: PaginationMeta
}>()
const emit = defineEmits<{
(e: 'update:open', value: boolean): void
(e: 'update:selected', value: string): void
(e: 'fetch', value: any): void
(e: 'save'): void
}>()
const search = ref('')
const debouncedSearch = refDebounced(search, 500) // 500ms debounce
function saveSelection() {
emit('save')
emit('update:open', false)
}
watch(debouncedSearch, (newValue) => {
// Only search if 3+ characters or empty (to clear search)
if (newValue.length === 0 || newValue.length >= 3) {
emit('fetch', { search: newValue })
}
})
</script>
<template>
<Dialog
:open="props.open"
@update:open="emit('update:open', $event)"
>
<DialogTrigger as-child></DialogTrigger>
<DialogContent class="max-w-3xl">
<DialogHeader>
<DialogTitle>Cari Pasien</DialogTitle>
</DialogHeader>
<!-- Input Search -->
<div class="mb-2 max-w-[50%]">
<Input
v-model="search"
placeholder="Cari berdasarkan No. KTP / No. RM / Nomor Kartu"
/>
</div>
<div class="overflow-x-auto rounded-lg border">
<ListPatient :data="patients" :pagination-meta="paginationMeta" />
</div>
<!-- Footer -->
<DialogFooter>
<Button
variant="default"
class="h-[40px] min-w-[120px] text-white"
@click="saveSelection"
>
<Icon
name="i-lucide-save"
class="h-5 w-5"
/>
Simpan
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
</template>
+2 -1
View File
@@ -4,6 +4,7 @@ import { useRoute } from 'vue-router'
// Components
import AppSepEntryForm from '~/components/app/sep/entry-form.vue'
import AppViewPatient from '~/components/app/sep/view-patient.vue'
import AppViewHistory from '~/components/app/sep/view-history.vue'
import { toast } from '~/components/pub/ui/toast'
@@ -441,7 +442,7 @@ onMounted(async () => {
@fetch="handleFetch"
@event="handleEvent"
/>
<AppSepTableSearchPatient
<AppViewPatient
v-model:open="openPatient"
v-model:selected="selectedPatient"
:patients="patients"