fix: change kode-penunjang inside block

This commit is contained in:
riefive
2025-10-15 09:51:44 +07:00
parent 76992b09f2
commit 10177da308
+417 -170
View File
@@ -3,19 +3,31 @@
import { toTypedSchema } from '@vee-validate/zod'
import { useForm } from 'vee-validate'
import { IntegrationBpjsSchema, type IntegrationBpjsFormData } from '~/schemas/integration-bpjs.schema'
// components
// components (use doc-entry block pattern)
import Block from '~/components/pub/my-ui/doc-entry/block.vue'
import Cell from '~/components/pub/my-ui/doc-entry/cell.vue'
import Field from '~/components/pub/my-ui/doc-entry/field.vue'
import Label from '~/components/pub/my-ui/doc-entry/label.vue'
import { Button } from '~/components/pub/ui/button'
import { Input } from '~/components/pub/ui/input'
import { Label } from '~/components/pub/ui/label'
import Select from '~/components/pub/ui/select/Select.vue'
import { RadioGroup, RadioGroupItem } from '~/components/pub/ui/radio-group'
import { Textarea } from '~/components/pub/ui/textarea'
import DatepickerSingle from '~/components/pub/my-ui/datepicker/datepicker-single.vue'
const props = defineProps<{
isLoading?: boolean
isReadonly?: boolean
values?: any
}>()
const emit = defineEmits<{
(e: 'event', value: any): void
}>()
const isLoading = props.isLoading !== undefined ? props.isLoading : false
const isReadonly = props.isReadonly !== undefined ? props.isReadonly : false
const items = [
{ value: 'item-1', label: 'Item 1' },
{ value: 'item-2', label: 'Item 2' },
@@ -23,27 +35,27 @@ const items = [
]
// Validation schema (moved to shared file)
const { handleSubmit, errors, defineField } = useForm<IntegrationBpjsFormData>({
const { handleSubmit, errors, defineField, meta } = useForm<IntegrationBpjsFormData>({
validationSchema: toTypedSchema(IntegrationBpjsSchema),
})
// Bind fields
const [tanggalSep] = defineField('tanggalSep')
const [jalur] = defineField('jalur')
const [noBpjs] = defineField('noBpjs')
const [noKtp] = defineField('noKtp')
const [noRm] = defineField('noRm')
const [namaPasien] = defineField('namaPasien')
const [noTelp] = defineField('noTelp')
const [noSuratKontrol] = defineField('noSuratKontrol')
const [tglSuratKontrol] = defineField('tglSuratKontrol')
const [klinikTujuan] = defineField('klinikTujuan')
const [dpjp] = defineField('dpjp')
const [diagnosaAwal] = defineField('diagnosaAwal')
const [cob] = defineField('cob')
const [katarak] = defineField('katarak')
const [jenisProsedur] = defineField('jenisProsedur')
const [kodePenunjang] = defineField('kodePenunjang')
// Bind fields and extract attrs for consistent Field pattern
const [tanggalSep, tanggalSepAttrs] = defineField('tanggalSep')
const [jalur, jalurAttrs] = defineField('jalur')
const [noBpjs, noBpjsAttrs] = defineField('noBpjs')
const [noKtp, noKtpAttrs] = defineField('noKtp')
const [noRm, noRmAttrs] = defineField('noRm')
const [namaPasien, namaPasienAttrs] = defineField('namaPasien')
const [noTelp, noTelpAttrs] = defineField('noTelp')
const [noSuratKontrol, noSuratKontrolAttrs] = defineField('noSuratKontrol')
const [tglSuratKontrol, tglSuratKontrolAttrs] = defineField('tglSuratKontrol')
const [klinikTujuan, klinikTujuanAttrs] = defineField('klinikTujuan')
const [dpjp, dpjpAttrs] = defineField('dpjp')
const [diagnosaAwal, diagnosaAwalAttrs] = defineField('diagnosaAwal')
const [cob, cobAttrs] = defineField('cob')
const [katarak, katarakAttrs] = defineField('katarak')
const [jenisProsedur, jenisProsedurAttrs] = defineField('jenisProsedur')
const [kodePenunjang, kodePenunjangAttrs] = defineField('kodePenunjang')
// Submit handler
const onSubmit = handleSubmit((values) => {
@@ -53,20 +65,47 @@ const onSubmit = handleSubmit((values) => {
<template>
<div class="mx-auto w-full">
<form @submit.prevent="onSubmit" class="grid gap-6 p-4">
<form
@submit.prevent="onSubmit"
class="grid gap-6 p-4"
>
<!-- Tanggal SEP & Jalur -->
<div class="grid grid-cols-1 gap-4 sm:grid-cols-3">
<div class="flex flex-col gap-2">
<Label for="tanggalSep">Tanggal SEP<span class="text-red-500">*</span></Label>
<DatepickerSingle v-model="tanggalSep" placeholder="Pilih tanggal sep" />
<p v-if="errors.tanggalSep" class="text-sm text-red-500">{{ errors.tanggalSep }}</p>
</div>
<div class="flex flex-col gap-2">
<Label for="jalur">Jalur</Label>
<Select icon-name="i-lucide-chevron-down" v-model="jalur" :items="items" placeholder="Pilih jalur"></Select>
<p v-if="errors.jalur" class="text-sm text-red-500">{{ errors.jalur }}</p>
</div>
</div>
<Block
labelSize="thin"
class="!pt-0"
:colCount="3"
:cellFlex="false"
>
<Cell>
<Label height="compact">
Tanggal SEP
<span class="ml-1 text-red-500">*</span>
</Label>
<Field :errMessage="errors.tanggalSep">
<DatepickerSingle
id="tanggalSep"
v-model="tanggalSep"
v-bind="tanggalSepAttrs"
:disabled="isLoading || isReadonly"
placeholder="Pilih tanggal sep"
/>
</Field>
</Cell>
<Cell>
<Label height="compact">Jalur</Label>
<Field :errMessage="errors.jalur">
<Select
id="jalur"
icon-name="i-lucide-chevron-down"
v-model="jalur"
v-bind="jalurAttrs"
:items="items"
:disabled="isLoading || isReadonly"
placeholder="Pilih jalur"
/>
</Field>
</Cell>
</Block>
<hr />
@@ -78,163 +117,356 @@ const onSubmit = handleSubmit((values) => {
class="h-[40px] rounded-md border-orange-400 text-orange-400 hover:bg-green-50"
@click="emit('event', 'search-patient')"
>
<Icon name="i-lucide-search" class="h-5 w-5" />
<Icon
name="i-lucide-search"
class="h-5 w-5"
/>
Cari Pasien
</Button>
</div>
<div class="grid grid-cols-1 gap-4 sm:grid-cols-3">
<div class="flex flex-col gap-2">
<Label>No. Kartu BPJS<span class="text-red-500">*</span></Label>
<Input v-model="noBpjs" />
<p v-if="errors.noBpjs" class="text-sm text-red-500">{{ errors.noBpjs }}</p>
</div>
<div class="flex flex-col gap-2">
<Label>No. KTP<span class="text-red-500">*</span></Label>
<Input v-model="noKtp" />
<p v-if="errors.noKtp" class="text-sm text-red-500">{{ errors.noKtp }}</p>
</div>
<div class="flex flex-col gap-2">
<Label>No. RM<span class="text-red-500">*</span></Label>
<Input v-model="noRm" />
<p v-if="errors.noRm" class="text-sm text-red-500">{{ errors.noRm }}</p>
</div>
<div class="flex flex-col gap-2">
<Label>Nama Pasien<span class="text-red-500">*</span></Label>
<Input v-model="namaPasien" />
<p v-if="errors.namaPasien" class="text-sm text-red-500">{{ errors.namaPasien }}</p>
</div>
<div class="flex flex-col gap-2">
<Label>No. Telepon<span class="text-red-500">*</span></Label>
<Input v-model="noTelp" />
<p v-if="errors.noTelp" class="text-sm text-red-500">{{ errors.noTelp }}</p>
</div>
</div>
<Block
labelSize="thin"
class="!pt-0"
:colCount="3"
:cellFlex="false"
>
<Cell>
<Label height="compact">
No. Kartu BPJS
<span class="text-red-500">*</span>
</Label>
<Field :errMessage="errors.noBpjs">
<Input
id="noBpjs"
v-model="noBpjs"
v-bind="noBpjsAttrs"
:disabled="isLoading || isReadonly"
/>
</Field>
</Cell>
<Cell>
<Label height="compact">
No. KTP
<span class="text-red-500">*</span>
</Label>
<Field :errMessage="errors.noKtp">
<Input
id="noKtp"
v-model="noKtp"
v-bind="noKtpAttrs"
:disabled="isLoading || isReadonly"
/>
</Field>
</Cell>
<Cell>
<Label height="compact">
No. RM
<span class="text-red-500">*</span>
</Label>
<Field :errMessage="errors.noRm">
<Input
id="noRm"
v-model="noRm"
v-bind="noRmAttrs"
:disabled="isLoading || isReadonly"
/>
</Field>
</Cell>
<Cell>
<Label height="compact">
Nama Pasien
<span class="text-red-500">*</span>
</Label>
<Field :errMessage="errors.namaPasien">
<Input
id="namaPasien"
v-model="namaPasien"
v-bind="namaPasienAttrs"
:disabled="isLoading || isReadonly"
/>
</Field>
</Cell>
<Cell>
<Label height="compact">
No. Telepon
<span class="text-red-500">*</span>
</Label>
<Field :errMessage="errors.noTelp">
<Input
id="noTelp"
v-model="noTelp"
v-bind="noTelpAttrs"
:disabled="isLoading || isReadonly"
/>
</Field>
</Cell>
</Block>
<hr />
<!-- Data SEP -->
<h3 class="text-lg font-semibold">Data SEP</h3>
<div class="grid grid-cols-1 gap-4 sm:grid-cols-3">
<div class="flex flex-col gap-2">
<Label>No. Surat Kontrol<span class="text-red-500">*</span></Label>
<div class="flex gap-2">
<Input class="flex-1" v-model="noSuratKontrol" />
<Button
variant="outline"
class="h-[40px] rounded-md border-orange-400 text-orange-400 hover:bg-green-50"
@click="emit('event', 'search-letter')"
>
<Icon name="i-lucide-search" class="h-5 w-5" />
Cari Data
</Button>
</div>
<p v-if="errors.noSuratKontrol" class="text-sm text-red-500">{{ errors.noSuratKontrol }}</p>
</div>
<div class="flex flex-col gap-2">
<Label>Tanggal Surat Kontrol<span class="text-red-500">*</span></Label>
<DatepickerSingle v-model="tglSuratKontrol" placeholder="Pilih tanggal surat kontrol" />
<p v-if="errors.tglSuratKontrol" class="text-sm text-red-500">{{ errors.tglSuratKontrol }}</p>
</div>
<div class="flex flex-row items-center gap-2">
<div class="flex-1">
<Label>Klinik Tujuan<span class="text-red-500">*</span></Label>
<Block
labelSize="thin"
class="!pt-0"
:colCount="3"
:cellFlex="false"
>
<Cell>
<Label height="compact">
No. Surat Kontrol
<span class="text-red-500">*</span>
</Label>
<Field :errMessage="errors.noSuratKontrol">
<div class="flex gap-2">
<Input
id="noSuratKontrol"
class="flex-1"
v-model="noSuratKontrol"
v-bind="noSuratKontrolAttrs"
:disabled="isLoading || isReadonly"
/>
<Button
variant="outline"
class="h-[40px] rounded-md border-orange-400 text-orange-400 hover:bg-green-50"
@click="emit('event', 'search-letter')"
>
<Icon
name="i-lucide-search"
class="h-5 w-5"
/>
Cari Data
</Button>
</div>
</Field>
</Cell>
<Cell>
<Label height="compact">
Tanggal Surat Kontrol
<span class="text-red-500">*</span>
</Label>
<Field :errMessage="errors.tglSuratKontrol">
<DatepickerSingle
id="tglSuratKontrol"
v-model="tglSuratKontrol"
v-bind="tglSuratKontrolAttrs"
:disabled="isLoading || isReadonly"
placeholder="Pilih tanggal surat kontrol"
/>
</Field>
</Cell>
<Cell>
<Label height="compact">
Klinik Tujuan
<span class="text-red-500">*</span>
</Label>
<Field :errMessage="errors.klinikTujuan">
<Select
id="klinikTujuan"
icon-name="i-lucide-chevron-down"
v-model="klinikTujuan"
v-bind="klinikTujuanAttrs"
:items="items"
:disabled="isLoading || isReadonly"
placeholder="Pilih klinik"
></Select>
<p v-if="errors.klinikTujuan" class="text-sm text-red-500">{{ errors.klinikTujuan }}</p>
</div>
<div>
<Label class="mb-2 block">Klinik Eksekutif<span class="text-red-500">*</span></Label>
<RadioGroup v-model="cob" class="flex items-center gap-2">
/>
</Field>
</Cell>
<Cell>
<Label height="compact">
Klinik Eksekutif
<span class="text-red-500">*</span>
</Label>
<Field :errMessage="errors.cob">
<RadioGroup
v-model="cob"
class="flex items-center gap-2"
v-bind="cobAttrs"
>
<div class="flex items-center space-x-2">
<RadioGroupItem value="Ya" id="cob-ya" />
<RadioGroupItem
value="Ya"
id="cob-ya"
/>
<Label for="cob-ya">Ya</Label>
</div>
<div class="flex items-center space-x-2">
<RadioGroupItem value="Tidak" id="cob-tidak" />
<RadioGroupItem
value="Tidak"
id="cob-tidak"
/>
<Label for="cob-tidak">Tidak</Label>
</div>
</RadioGroup>
</div>
</div>
<div class="flex flex-col gap-2">
<Label>DPJP<span class="text-red-500">*</span></Label>
<Select icon-name="i-lucide-chevron-down" v-model="dpjp" :items="items" placeholder="Pilih DPJP"></Select>
<p v-if="errors.dpjp" class="text-sm text-red-500">{{ errors.dpjp }}</p>
</div>
<div class="flex flex-col gap-2">
<Label>Diagnosa Awal<span class="text-red-500">*</span></Label>
<Input v-model="diagnosaAwal" />
<p v-if="errors.diagnosaAwal" class="text-sm text-red-500">{{ errors.diagnosaAwal }}</p>
</div>
</div>
</Field>
</Cell>
<!-- Catatan -->
<div>
<Label>Catatan</Label>
<Textarea class="h-[200px] w-full border-gray-400 bg-white" placeholder="Masukkan catatan opsional" />
</div>
<Cell>
<Label height="compact">
DPJP
<span class="text-red-500">*</span>
</Label>
<Field :errMessage="errors.dpjp">
<Select
id="dpjp"
icon-name="i-lucide-chevron-down"
v-model="dpjp"
v-bind="dpjpAttrs"
:items="items"
:disabled="isLoading || isReadonly"
placeholder="Pilih DPJP"
/>
</Field>
</Cell>
<div class="flex items-center gap-4">
<div>
<Label class="mb-2 block">COB<span class="text-red-500">*</span></Label>
<RadioGroup v-model="cob" class="flex items-center gap-2">
<div class="flex items-center space-x-2">
<RadioGroupItem value="Ya" id="cob-ya" />
<Label for="cob-ya">Ya</Label>
</div>
<div class="flex items-center space-x-2">
<RadioGroupItem value="Tidak" id="cob-tidak" />
<Label for="cob-tidak">Tidak</Label>
</div>
</RadioGroup>
</div>
<div>
<Label class="mb-2 block">Katarak<span class="text-red-500">*</span></Label>
<RadioGroup v-model="katarak" class="flex items-center gap-2">
<div class="flex items-center space-x-2">
<RadioGroupItem value="Ya" id="katarak-ya" />
<Label for="katarak-ya">Ya</Label>
</div>
<div class="flex items-center space-x-2">
<RadioGroupItem value="Tidak" id="katarak-tidak" />
<Label for="katarak-tidak">Tidak</Label>
</div>
</RadioGroup>
</div>
</div>
<Cell>
<Label height="compact">
Diagnosa Awal
<span class="text-red-500">*</span>
</Label>
<Field :errMessage="errors.diagnosaAwal">
<Input
id="diagnosaAwal"
v-model="diagnosaAwal"
v-bind="diagnosaAwalAttrs"
:disabled="isLoading || isReadonly"
/>
</Field>
</Cell>
</Block>
<div class="grid gap-4 md:grid-cols-3">
<div class="flex flex-col gap-2">
<Label class="mb-2 block">Jenis Prosedur<span class="text-red-500">*</span></Label>
<RadioGroup v-model="jenisProsedur" class="flex items-center gap-2">
<div class="flex items-center space-x-2">
<RadioGroupItem value="procedure-one" id="procedure-one" />
<Label for="procedure-one">Prosedur tidak berkelanjutan</Label>
</div>
<div class="flex items-center space-x-2">
<RadioGroupItem value="procedure-two" id="procedure-two" />
<Label for="procedure-two">Prosedur dan terapi berkelanjutan</Label>
</div>
</RadioGroup>
</div>
</div>
<Block
labelSize="thin"
class="!pt-0"
:colCount="1"
:cellFlex="false"
>
<Cell>
<Label height="dynamic">Catatan</Label>
<Field>
<Textarea
id="catatan"
class="h-[200px] w-full border-gray-400 bg-white"
placeholder="Masukkan catatan opsional"
:disabled="isLoading || isReadonly"
/>
</Field>
</Cell>
<div class="grid gap-4 md:grid-cols-3">
<div class="flex flex-col gap-2">
<Label>Kode Penunjang<span class="text-red-500">*</span></Label>
<Select
icon-name="i-lucide-chevron-down"
v-model="kodePenunjang"
:items="items"
placeholder="Pilih Kode Penunjang"
></Select>
<p v-if="errors.kodePenunjang" class="text-sm text-red-500">{{ errors.kodePenunjang }}</p>
</div>
</div>
<Cell>
<Label height="compact">
COB
<span class="text-red-500">*</span>
</Label>
<Field :errMessage="errors.cob">
<RadioGroup
v-model="cob"
class="flex items-center gap-2"
v-bind="cobAttrs"
>
<div class="flex items-center space-x-2">
<RadioGroupItem
value="Ya"
id="cob-ya"
/>
<Label for="cob-ya">Ya</Label>
</div>
<div class="flex items-center space-x-2">
<RadioGroupItem
value="Tidak"
id="cob-tidak"
/>
<Label for="cob-tidak">Tidak</Label>
</div>
</RadioGroup>
</Field>
</Cell>
<Cell>
<Label height="compact">
Katarak
<span class="text-red-500">*</span>
</Label>
<Field :errMessage="errors.katarak">
<RadioGroup
v-model="katarak"
class="flex items-center gap-2"
v-bind="katarakAttrs"
>
<div class="flex items-center space-x-2">
<RadioGroupItem
value="Ya"
id="katarak-ya"
/>
<Label for="katarak-ya">Ya</Label>
</div>
<div class="flex items-center space-x-2">
<RadioGroupItem
value="Tidak"
id="katarak-tidak"
/>
<Label for="katarak-tidak">Tidak</Label>
</div>
</RadioGroup>
</Field>
</Cell>
<Cell>
<Label height="compact">
Jenis Prosedur
<span class="text-red-500">*</span>
</Label>
<Field :errMessage="errors.jenisProsedur">
<RadioGroup
v-model="jenisProsedur"
class="flex items-center gap-2"
v-bind="jenisProsedurAttrs"
>
<div class="flex items-center space-x-2">
<RadioGroupItem
value="procedure-one"
id="procedure-one"
/>
<Label for="procedure-one">Prosedur tidak berkelanjutan</Label>
</div>
<div class="flex items-center space-x-2">
<RadioGroupItem
value="procedure-two"
id="procedure-two"
/>
<Label for="procedure-two">Prosedur dan terapi berkelanjutan</Label>
</div>
</RadioGroup>
</Field>
</Cell>
</Block>
<Block
labelSize="thin"
class="!pt-0"
:colCount="3"
:cellFlex="false"
>
<Cell>
<Label height="compact">
Kode Penunjang
<span class="text-red-500">*</span>
</Label>
<Field :errMessage="errors.kodePenunjang">
<Select
id="kodePenunjang"
icon-name="i-lucide-chevron-down"
v-model="kodePenunjang"
v-bind="kodePenunjangAttrs"
:items="items"
:disabled="isLoading || isReadonly"
placeholder="Pilih Kode Penunjang"
/>
</Field>
</Cell>
</Block>
<!-- Actions -->
<div class="mt-6 flex justify-end gap-2">
@@ -244,17 +476,32 @@ const onSubmit = handleSubmit((values) => {
class="h-[40px] min-w-[120px] text-orange-400 hover:bg-green-50"
@click="emit('event', 'history-sep')"
>
<Icon name="i-lucide-history" class="h-5 w-5" /> Riwayat SEP
<Icon
name="i-lucide-history"
class="h-5 w-5"
/>
Riwayat SEP
</Button>
<Button
type="button"
variant="outline"
class="h-[40px] min-w-[120px] rounded-md border-orange-400 text-orange-400 hover:bg-green-50 hover:text-orange-400"
>
<Icon name="i-lucide-eye" class="h-5 w-5" />Preview
<Icon
name="i-lucide-eye"
class="h-5 w-5"
/>
Preview
</Button>
<Button type="submit" class="h-[40px] min-w-[120px] text-white">
<Icon name="i-lucide-save" class="h-5 w-5" />
<Button
type="submit"
class="h-[40px] min-w-[120px] text-white"
:disabled="isLoading || !meta.valid"
>
<Icon
name="i-lucide-save"
class="h-5 w-5"
/>
Simpan
</Button>
</div>