Merge branch 'dev' of https://github.com/dikstub-rssa/simrs-fe into fe-sep-38

This commit is contained in:
riefive
2025-09-10 12:37:32 +07:00
60 changed files with 1994 additions and 230 deletions
-64
View File
@@ -1,64 +0,0 @@
<script setup lang="ts">
import Block from '~/components/pub/custom-ui/form/block.vue'
import FieldGroup from '~/components/pub/custom-ui/form/field-group.vue'
import Field from '~/components/pub/custom-ui/form/field.vue'
import Label from '~/components/pub/custom-ui/form/label.vue'
const props = defineProps<{ modelValue: any; errors: any }>()
const emit = defineEmits(['update:modelValue', 'event'])
const data = computed({
get: () => props.modelValue,
set: (val) => {
emit('update:modelValue', val)
},
})
const items = [
{ value: 'item1', label: 'Item 1' },
{ value: 'item2', label: 'Item 2' },
]
</script>
<template>
<form id="entry-form">
<div class="mb-5 border-b border-b-slate-300 pb-3 text-lg xl:text-xl">
<div class="flex flex-col justify-between">
<Block>
<FieldGroup :column="1">
<Label>Kode</Label>
<Field>
<Input v-model="data.code" />
</Field>
</FieldGroup>
<FieldGroup v-if="!!props.errors.code">
<Label></Label>
<span class="text-red-400 text-sm">{{ props.errors.code }}</span>
</FieldGroup>
<FieldGroup :column="1">
<Label>Nama</Label>
<Field>
<Input v-model="data.name" />
</Field>
</FieldGroup>
<FieldGroup v-if="!!props.errors.name">
<Label></Label>
<span class="text-red-400 text-sm">{{ props.errors.name }}</span>
</FieldGroup>
<FieldGroup :column="1">
<Label>Item</Label>
<Field>
<Select v-model="data.type" :items="items" placeholder="Pilih item" />
</Field>
</FieldGroup>
<FieldGroup :column="1">
<Label>Satuan</Label>
<Field>
<Select v-model="data.uom" :items="items" placeholder="Pilih item" />
</Field>
</FieldGroup>
</Block>
</div>
</div>
</form>
</template>
+15 -57
View File
@@ -11,76 +11,34 @@ const data = computed({
get: () => props.modelValue,
set: (val) => emit('update:modelValue', val),
})
const items = [
{ value: 'doctor', label: 'Dokter' },
{ value: 'nurse', label: 'Perawat' },
]
</script>
<template>
<form id="entry-form">
<div class="mb-5 border-b border-b-slate-300 pb-3 text-lg xl:text-xl">
<div class="mb-2 border-b border-b-slate-300 text-lg xl:text-xl">
<div class="flex flex-col justify-between">
<Block>
<FieldGroup :column="1">
<Label>Nama dan Gelar</Label>
<FieldGroup :column="2" layout="stacked">
<Label stacked>No. IHS</Label>
<Field>
<Input v-model="data.name" type="text" name="name" default-value="dr." />
</Field>
<Field>
<Input type="text" name="name" />
</Field>
<Field>
<Input type="text" name="name" />
<Input />
</Field>
</FieldGroup>
</Block>
<Block>
<FieldGroup :column="2">
<Label>NIK</Label>
<FieldGroup :column="2" layout="stacked">
<Label stacked>No. SIP</Label>
<Field>
<Input type="text" name="identity_number" />
<Input />
</Field>
</FieldGroup>
<FieldGroup :column="2">
<Label>NO SIP</Label>
<Field name="sip_number">
<Input type="text" name="sip_no" />
</Field>
</FieldGroup>
</Block>
<Block>
<FieldGroup :column="2">
<Label>Telepon / HP</Label>
<Field name="phone">
<Input type="text" name="phone" />
</Field>
</FieldGroup>
<FieldGroup :column="2">
<Label>Kode BPJS</Label>
<FieldGroup :column="2" layout="stacked">
<Label stacked>Unit</Label>
<Field>
<Input type="text" name="bpjs_code" />
</Field>
</FieldGroup>
</Block>
<Block>
<FieldGroup :column="2">
<Label>Fee Rajal</Label>
<Field>
<Input type="number" name="outPatient_rate" />
</Field>
</FieldGroup>
<FieldGroup :column="2">
<Label>Fee Ranap</Label>
<Field>
<Input type="number" name="inPatient_rate" />
</Field>
</FieldGroup>
</Block>
<Block>
<FieldGroup :column="3">
<Label>Status</Label>
<Field>
<Input type="select" name="status">
<option value="active">Aktif</option>
<option value="inactive">Tidak Aktif</option>
</Input>
<Select v-model="data.type" :items="items" placeholder="Pilih jenis" />
</Field>
</FieldGroup>
</Block>
@@ -0,0 +1,49 @@
<script setup lang="ts">
import Block from '~/components/pub/custom-ui/form/block.vue'
import FieldGroup from '~/components/pub/custom-ui/form/field-group.vue'
import Field from '~/components/pub/custom-ui/form/field.vue'
import Label from '~/components/pub/custom-ui/form/label.vue'
const props = defineProps<{ modelValue: any; items: any[] }>()
const emit = defineEmits(['update:modelValue', 'event'])
const data = computed({
get: () => props.modelValue,
set: (val) => emit('update:modelValue', val),
})
</script>
<template>
<form id="entry-form">
<div class="mb-5 border-b border-b-slate-300 text-lg xl:text-xl">
<div class="flex flex-col justify-between">
<Block>
<FieldGroup :column="2" layout="stacked">
<Label stacked>Nomor Induk Pegawai</Label>
<Field>
<Input v-model="data.number" />
</Field>
</FieldGroup>
<FieldGroup :column="2" layout="stacked">
<Label stacked>Status</Label>
<Field>
<Select v-model="data.type" :items="items" placeholder="Pilih jenis" />
</Field>
</FieldGroup>
<FieldGroup :column="2" layout="stacked">
<Label stacked>Position</Label>
<Field>
<Select v-model="data.type" :items="items" placeholder="Pilih jenis" />
</Field>
</FieldGroup>
<FieldGroup :column="2" layout="stacked">
<Label stacked>Divisi</Label>
<Field>
<Select v-model="data.type" :items="items" placeholder="Pilih jenis" />
</Field>
</FieldGroup>
</Block>
</div>
</div>
</form>
</template>
+109
View File
@@ -0,0 +1,109 @@
import type {
Col,
KeyLabel,
RecComponent,
RecStrFuncComponent,
RecStrFuncUnknown,
Th,
} from '~/components/pub/custom-ui/data/types'
import { defineAsyncComponent } from 'vue'
type SmallDetailDto = any
const action = defineAsyncComponent(() => import('~/components/pub/custom-ui/data/dropdown-action-dud.vue'))
const doctorStatus = {
0: 'Tidak Aktif',
1: 'Aktif',
}
export const cols: Col[] = [
{ width: 100 },
{ width: 250 },
{},
{ width: 100 },
{ width: 100 },
{},
{},
{},
{ width: 100 },
{ width: 100 },
{ width: 100 },
{ width: 50 },
]
export const header: Th[][] = [
[
{ label: 'Kode JKN' },
{ label: 'Nama' },
{ label: 'No KTP' },
{ label: 'No SIP' },
{ label: 'No IHS' },
{ label: 'Telpon' },
{ label: 'Fee Ranap' },
{ label: 'Fee Rajal' },
{ label: 'Status' },
],
]
export const keys = [
'bpjs_code',
'name',
'identity_number',
'sip_no',
'ihs_number',
'phone',
'inPatient_itemPrice',
'outPatient_itemPrice',
'status',
'action',
]
export const delKeyNames: KeyLabel[] = [
{ key: 'code', label: 'Kode' },
{ key: 'name', label: 'Nama' },
]
export const funcParsed: RecStrFuncUnknown = {
name: (rec: unknown): unknown => {
console.log(rec)
const recX = rec as SmallDetailDto
return `${recX.frontTitle} ${recX.name} ${recX.endTitle}`.trim()
},
identity_number: (rec: unknown): unknown => {
const recX = rec as SmallDetailDto
if (recX.identity_number?.substring(0, 5) === 'BLANK') {
return '(TANPA NIK)'
}
return recX.identity_number
},
inPatient_itemPrice: (rec: unknown): unknown => {
const recX = rec as SmallDetailDto
return Number(recX.inPatient_itemPrice.price).toLocaleString('id-ID')
},
outPatient_itemPrice: (rec: unknown): unknown => {
const recX = rec as SmallDetailDto
return Number(recX.outPatient_itemPrice.price).toLocaleString('id-ID')
},
status: (rec: unknown): unknown => {
const recX = rec as SmallDetailDto
return doctorStatus[recX.status_code as keyof typeof doctorStatus]
},
}
export const funcComponent: RecStrFuncComponent = {
action(rec, idx) {
const res: RecComponent = {
idx,
rec: rec as object,
component: action,
}
return res
},
}
export const funcHtml: RecStrFuncUnknown = {
patient_address(_rec) {
return '-'
},
}
@@ -2,23 +2,26 @@
// types
import type z from 'zod'
import type { MaterialFormData } from '~/schemas/material'
<<<<<<< HEAD:app/components/app/equipment/entry-form.vue
=======
// helpers
import { toTypedSchema } from '@vee-validate/zod'
import { useForm } from 'vee-validate'
// components
import Label from '~/components/pub/custom-ui/form/label.vue'
>>>>>>> 266d5f740b15942ca7b8845c00573640fdc9a3b2:app/components/app/material/entry-form.vue
interface Props {
isLoading: boolean
schema: z.ZodSchema<any>
uoms: any[]
items: any[]
}
const isLoading = ref(false)
const props = defineProps<Props>()
const emit = defineEmits<{
back: []
submit: [data: any]
submit: [values: MaterialFormData, resetForm: () => void]
cancel: [resetForm: () => void]
}>()
const { handleSubmit, defineField, errors } = useForm({
@@ -38,19 +41,36 @@ const [uom, uomAttrs] = defineField('uom_code')
const [item, itemAttrs] = defineField('item_id')
const [stock, stockAttrs] = defineField('stock')
const onSubmit = handleSubmit(async (values) => {
try {
emit('submit', values)
} catch (error) {
console.error('Submission failed:', error)
const resetForm = () => {
code.value = ''
name.value = ''
uom.value = ''
item.value = ''
stock.value = 0
}
// Form submission handler
function onSubmitForm(values: any) {
const formData: MaterialFormData = {
name: values.name || '',
code: values.code || '',
uom_code: values.uom_code || '',
item_id: values.item_id || '',
stock: values.stock || 0,
}
})
emit('submit', formData, resetForm)
}
// Form cancel handler
function onCancelForm() {
emit('cancel', resetForm)
}
</script>
<template>
<form class="grid gap-2" @submit="onSubmit">
<form class="grid gap-2" @submit="handleSubmit(onSubmitForm)">
<div class="grid gap-2">
<Label for="code">Kode</Label>
<label for="code">Kode</label>
<Input
id="code"
v-model="code"
@@ -63,7 +83,7 @@ const onSubmit = handleSubmit(async (values) => {
</span>
</div>
<div class="grid gap-2">
<Label for="name">Nama</Label>
<label for="name">Nama</label>
<Input
id="name"
v-model="name"
@@ -76,7 +96,7 @@ const onSubmit = handleSubmit(async (values) => {
</span>
</div>
<div class="grid gap-2">
<Label for="uom">Satuan</Label>
<label for="uom">Satuan</label>
<Select
id="uom"
v-model="uom"
@@ -92,7 +112,7 @@ const onSubmit = handleSubmit(async (values) => {
</span>
</div>
<div class="grid gap-2">
<Label for="item">Item</Label>
<label for="item">Item</label>
<Select
id="item"
v-model="item"
@@ -108,7 +128,7 @@ const onSubmit = handleSubmit(async (values) => {
</span>
</div>
<div class="grid gap-2">
<Label for="stock">Stok</Label>
<label for="stock">Stok</label>
<Input
id="stock"
v-model="stock"
@@ -122,7 +142,7 @@ const onSubmit = handleSubmit(async (values) => {
</span>
</div>
<div class="my-2 flex justify-end gap-2 py-2">
<Button variant="secondary" class="w-[120px]" @click="emit('back')"> Kembali </Button>
<Button variant="secondary" class="w-[120px]" @click="onCancelForm"> Kembali </Button>
<Button type="submit" class="w-[120px]">
<Loader2 v-if="isLoading" class="mr-2 h-4 w-4 animate-spin" />
Simpan
+38
View File
@@ -0,0 +1,38 @@
<script setup lang="ts">
import type { PaginationMeta } from '~/components/pub/custom-ui/pagination/pagination.type'
import { cols, funcComponent, funcHtml, funcParsed, header, keys } from './list-cfg'
interface Props {
data: any[]
paginationMeta?: PaginationMeta
}
defineProps<Props>()
const emit = defineEmits<{
pageChange: [page: number]
}>()
function handlePageChange(page: number) {
emit('pageChange', page)
}
</script>
<template>
<div class="space-y-4">
<PubBaseDataTable
:rows="data"
:cols="cols"
:header="header"
:keys="keys"
:func-parsed="funcParsed"
:func-html="funcHtml"
:func-component="funcComponent"
/>
<template v-if="paginationMeta">
<div v-if="paginationMeta.totalPage > 1">
<PubCustomUiPagination :pagination-meta="paginationMeta" @page-change="handlePageChange" />
</div>
</template>
</div>
</template>
@@ -0,0 +1,31 @@
<script setup lang="ts">
import Block from '~/components/pub/custom-ui/form/block.vue'
import FieldGroup from '~/components/pub/custom-ui/form/field-group.vue'
import Field from '~/components/pub/custom-ui/form/field.vue'
import Label from '~/components/pub/custom-ui/form/label.vue'
const props = defineProps<{ modelValue: any }>()
const emit = defineEmits(['update:modelValue', 'event'])
const data = computed({
get: () => props.modelValue,
set: (val) => emit('update:modelValue', val),
})
</script>
<template>
<form id="entry-form">
<div class="mb-2 border-b border-b-slate-300 text-lg xl:text-xl">
<div class="flex flex-col justify-between">
<Block>
<FieldGroup layout="stacked">
<Label stacked>No. IHS</Label>
<Field>
<Input />
</Field>
</FieldGroup>
</Block>
</div>
</div>
</form>
</template>
+114
View File
@@ -0,0 +1,114 @@
import type {
Col,
KeyLabel,
RecComponent,
RecStrFuncComponent,
RecStrFuncUnknown,
Th,
} from '~/components/pub/custom-ui/data/types'
import { defineAsyncComponent } from 'vue'
type SmallDetailDto = any
const action = defineAsyncComponent(() => import('~/components/pub/custom-ui/data/dropdown-action-dud.vue'))
const statusBadge = defineAsyncComponent(() => import('./status-badge.vue'))
const _doctorStatus = {
0: 'Tidak Aktif',
1: 'Aktif',
}
export const cols: Col[] = [
{ width: 100 },
{ width: 250 },
{},
{ width: 100 },
{ width: 100 },
{},
{},
{},
{ width: 120 },
{ width: 100 },
{},
{},
]
export const header: Th[][] = [
[
{ label: 'Kode JKN' },
{ label: 'Nama' },
{ label: 'No KTP' },
{ label: 'No SIP' },
{ label: 'No IHS' },
{ label: 'Telpon' },
{ label: 'Fee Ranap' },
{ label: 'Fee Rajal' },
{ label: 'Status' },
{ label: '' },
],
]
export const keys = [
'bpjs_code',
'name',
'identity_number',
'sip_no',
'ihs_number',
'phone',
'inPatient_itemPrice',
'outPatient_itemPrice',
'status',
'action',
]
export const delKeyNames: KeyLabel[] = [
{ key: 'code', label: 'Kode' },
{ key: 'name', label: 'Nama' },
]
export const funcParsed: RecStrFuncUnknown = {
name: (rec: unknown): unknown => {
const recX = rec as SmallDetailDto
return `${recX.frontTitle} ${recX.name} ${recX.endTitle}`.trim()
},
identity_number: (rec: unknown): unknown => {
const recX = rec as SmallDetailDto
if (recX.identity_number?.substring(0, 5) === 'BLANK') {
return '(TANPA NIK)'
}
return recX.identity_number
},
inPatient_itemPrice: (rec: unknown): unknown => {
const recX = rec as SmallDetailDto
return Number(recX.inPatient_itemPrice.price).toLocaleString('id-ID')
},
outPatient_itemPrice: (rec: unknown): unknown => {
const recX = rec as SmallDetailDto
return Number(recX.outPatient_itemPrice.price).toLocaleString('id-ID')
},
}
export const funcComponent: RecStrFuncComponent = {
action(rec, idx) {
const res: RecComponent = {
idx,
rec: rec as object,
component: action,
}
return res
},
status(rec, idx) {
const res: RecComponent = {
idx,
rec: rec as object,
component: statusBadge,
}
return res
},
}
export const funcHtml: RecStrFuncUnknown = {
patient_address(_rec) {
return '-'
},
}
@@ -0,0 +1,29 @@
<script setup lang="ts">
import { Badge } from '~/components/pub/ui/badge'
const props = defineProps<{
rec: any
idx?: number
}>()
const doctorStatus = {
0: 'Tidak Aktif',
1: 'Aktif',
}
const statusText = computed(() => {
return doctorStatus[props.rec.status_code as keyof typeof doctorStatus]
})
const badgeVariant = computed(() => {
return props.rec.status_code === 1 ? 'default' : 'destructive'
})
</script>
<template>
<div class="flex justify-center">
<Badge :variant="badgeVariant">
{{ statusText }}
</Badge>
</div>
</template>
+31
View File
@@ -0,0 +1,31 @@
<script setup lang="ts">
import Block from '~/components/pub/custom-ui/form/block.vue'
import FieldGroup from '~/components/pub/custom-ui/form/field-group.vue'
import Field from '~/components/pub/custom-ui/form/field.vue'
import Label from '~/components/pub/custom-ui/form/label.vue'
const props = defineProps<{ modelValue: any }>()
const emit = defineEmits(['update:modelValue', 'event'])
const data = computed({
get: () => props.modelValue,
set: (val) => emit('update:modelValue', val),
})
</script>
<template>
<form id="entry-form">
<div class="mb-2 border-b border-b-slate-300 text-lg xl:text-xl">
<div class="flex flex-col justify-between">
<Block>
<FieldGroup layout="stacked">
<Label stacked>No. IHS</Label>
<Field>
<Input />
</Field>
</FieldGroup>
</Block>
</div>
</div>
</form>
</template>
+114
View File
@@ -0,0 +1,114 @@
import type {
Col,
KeyLabel,
RecComponent,
RecStrFuncComponent,
RecStrFuncUnknown,
Th,
} from '~/components/pub/custom-ui/data/types'
import { defineAsyncComponent } from 'vue'
type SmallDetailDto = any
const action = defineAsyncComponent(() => import('~/components/pub/custom-ui/data/dropdown-action-dud.vue'))
const statusBadge = defineAsyncComponent(() => import('./status-badge.vue'))
const _doctorStatus = {
0: 'Tidak Aktif',
1: 'Aktif',
}
export const cols: Col[] = [
{ width: 100 },
{ width: 250 },
{},
{ width: 100 },
{ width: 100 },
{},
{},
{},
{ width: 120 },
{ width: 100 },
{},
{},
]
export const header: Th[][] = [
[
{ label: 'Kode JKN' },
{ label: 'Nama' },
{ label: 'No KTP' },
{ label: 'No SIP' },
{ label: 'No IHS' },
{ label: 'Telpon' },
{ label: 'Fee Ranap' },
{ label: 'Fee Rajal' },
{ label: 'Status' },
{ label: '' },
],
]
export const keys = [
'bpjs_code',
'name',
'identity_number',
'sip_no',
'ihs_number',
'phone',
'inPatient_itemPrice',
'outPatient_itemPrice',
'status',
'action',
]
export const delKeyNames: KeyLabel[] = [
{ key: 'code', label: 'Kode' },
{ key: 'name', label: 'Nama' },
]
export const funcParsed: RecStrFuncUnknown = {
name: (rec: unknown): unknown => {
const recX = rec as SmallDetailDto
return `${recX.frontTitle} ${recX.name} ${recX.endTitle}`.trim()
},
identity_number: (rec: unknown): unknown => {
const recX = rec as SmallDetailDto
if (recX.identity_number?.substring(0, 5) === 'BLANK') {
return '(TANPA NIK)'
}
return recX.identity_number
},
inPatient_itemPrice: (rec: unknown): unknown => {
const recX = rec as SmallDetailDto
return Number(recX.inPatient_itemPrice.price).toLocaleString('id-ID')
},
outPatient_itemPrice: (rec: unknown): unknown => {
const recX = rec as SmallDetailDto
return Number(recX.outPatient_itemPrice.price).toLocaleString('id-ID')
},
}
export const funcComponent: RecStrFuncComponent = {
action(rec, idx) {
const res: RecComponent = {
idx,
rec: rec as object,
component: action,
}
return res
},
status(rec, idx) {
const res: RecComponent = {
idx,
rec: rec as object,
component: statusBadge,
}
return res
},
}
export const funcHtml: RecStrFuncUnknown = {
patient_address(_rec) {
return '-'
},
}
+19
View File
@@ -0,0 +1,19 @@
<script setup lang="ts">
import { cols, funcComponent, funcHtml, funcParsed, header, keys } from './list-cfg'
defineProps<{
data: any[]
}>()
</script>
<template>
<PubBaseDataTable
:rows="data"
:cols="cols"
:header="header"
:keys="keys"
:func-parsed="funcParsed"
:func-html="funcHtml"
:func-component="funcComponent"
/>
</template>
View File
View File
+29
View File
@@ -0,0 +1,29 @@
<script setup lang="ts">
import { Badge } from '~/components/pub/ui/badge'
const props = defineProps<{
rec: any
idx?: number
}>()
const doctorStatus = {
0: 'Tidak Aktif',
1: 'Aktif',
}
const statusText = computed(() => {
return doctorStatus[props.rec.status_code as keyof typeof doctorStatus]
})
const badgeVariant = computed(() => {
return props.rec.status_code === 1 ? 'default' : 'destructive'
})
</script>
<template>
<div class="flex justify-center">
<Badge :variant="badgeVariant">
{{ statusText }}
</Badge>
</div>
</template>
@@ -0,0 +1,31 @@
<script setup lang="ts">
import Block from '~/components/pub/custom-ui/form/block.vue'
import FieldGroup from '~/components/pub/custom-ui/form/field-group.vue'
import Field from '~/components/pub/custom-ui/form/field.vue'
import Label from '~/components/pub/custom-ui/form/label.vue'
const props = defineProps<{ modelValue: any }>()
const emit = defineEmits(['update:modelValue', 'event'])
const data = computed({
get: () => props.modelValue,
set: (val) => emit('update:modelValue', val),
})
</script>
<template>
<form id="entry-form">
<div class="mb-2 border-b border-b-slate-300 text-lg xl:text-xl">
<div class="flex flex-col justify-between">
<Block>
<FieldGroup layout="stacked">
<Label stacked>No. IHS</Label>
<Field>
<Input />
</Field>
</FieldGroup>
</Block>
</div>
</div>
</form>
</template>
+114
View File
@@ -0,0 +1,114 @@
import type {
Col,
KeyLabel,
RecComponent,
RecStrFuncComponent,
RecStrFuncUnknown,
Th,
} from '~/components/pub/custom-ui/data/types'
import { defineAsyncComponent } from 'vue'
type SmallDetailDto = any
const action = defineAsyncComponent(() => import('~/components/pub/custom-ui/data/dropdown-action-dud.vue'))
const statusBadge = defineAsyncComponent(() => import('./status-badge.vue'))
const _doctorStatus = {
0: 'Tidak Aktif',
1: 'Aktif',
}
export const cols: Col[] = [
{ width: 100 },
{ width: 250 },
{},
{ width: 100 },
{ width: 100 },
{},
{},
{},
{ width: 120 },
{ width: 100 },
{},
{},
]
export const header: Th[][] = [
[
{ label: 'Kode JKN' },
{ label: 'Nama' },
{ label: 'No KTP' },
{ label: 'No SIP' },
{ label: 'No IHS' },
{ label: 'Telpon' },
{ label: 'Fee Ranap' },
{ label: 'Fee Rajal' },
{ label: 'Status' },
{ label: '' },
],
]
export const keys = [
'bpjs_code',
'name',
'identity_number',
'sip_no',
'ihs_number',
'phone',
'inPatient_itemPrice',
'outPatient_itemPrice',
'status',
'action',
]
export const delKeyNames: KeyLabel[] = [
{ key: 'code', label: 'Kode' },
{ key: 'name', label: 'Nama' },
]
export const funcParsed: RecStrFuncUnknown = {
name: (rec: unknown): unknown => {
const recX = rec as SmallDetailDto
return `${recX.frontTitle} ${recX.name} ${recX.endTitle}`.trim()
},
identity_number: (rec: unknown): unknown => {
const recX = rec as SmallDetailDto
if (recX.identity_number?.substring(0, 5) === 'BLANK') {
return '(TANPA NIK)'
}
return recX.identity_number
},
inPatient_itemPrice: (rec: unknown): unknown => {
const recX = rec as SmallDetailDto
return Number(recX.inPatient_itemPrice.price).toLocaleString('id-ID')
},
outPatient_itemPrice: (rec: unknown): unknown => {
const recX = rec as SmallDetailDto
return Number(recX.outPatient_itemPrice.price).toLocaleString('id-ID')
},
}
export const funcComponent: RecStrFuncComponent = {
action(rec, idx) {
const res: RecComponent = {
idx,
rec: rec as object,
component: action,
}
return res
},
status(rec, idx) {
const res: RecComponent = {
idx,
rec: rec as object,
component: statusBadge,
}
return res
},
}
export const funcHtml: RecStrFuncUnknown = {
patient_address(_rec) {
return '-'
},
}
+19
View File
@@ -0,0 +1,19 @@
<script setup lang="ts">
import { cols, funcComponent, funcHtml, funcParsed, header, keys } from './list-cfg'
defineProps<{
data: any[]
}>()
</script>
<template>
<PubBaseDataTable
:rows="data"
:cols="cols"
:header="header"
:keys="keys"
:func-parsed="funcParsed"
:func-html="funcHtml"
:func-component="funcComponent"
/>
</template>
@@ -0,0 +1,29 @@
<script setup lang="ts">
import { Badge } from '~/components/pub/ui/badge'
const props = defineProps<{
rec: any
idx?: number
}>()
const doctorStatus = {
0: 'Tidak Aktif',
1: 'Aktif',
}
const statusText = computed(() => {
return doctorStatus[props.rec.status_code as keyof typeof doctorStatus]
})
const badgeVariant = computed(() => {
return props.rec.status_code === 1 ? 'default' : 'destructive'
})
</script>
<template>
<div class="flex justify-center">
<Badge :variant="badgeVariant">
{{ statusText }}
</Badge>
</div>
</template>
@@ -0,0 +1,31 @@
<script setup lang="ts">
import Block from '~/components/pub/custom-ui/form/block.vue'
import FieldGroup from '~/components/pub/custom-ui/form/field-group.vue'
import Field from '~/components/pub/custom-ui/form/field.vue'
import Label from '~/components/pub/custom-ui/form/label.vue'
const props = defineProps<{ modelValue: any }>()
const emit = defineEmits(['update:modelValue', 'event'])
const data = computed({
get: () => props.modelValue,
set: (val) => emit('update:modelValue', val),
})
</script>
<template>
<form id="entry-form">
<div class="mb-2 border-b border-b-slate-300 text-lg xl:text-xl">
<div class="flex flex-col justify-between">
<Block>
<FieldGroup :column="2" layout="stacked">
<Label stacked>No. IHS</Label>
<Field>
<Input />
</Field>
</FieldGroup>
</Block>
</div>
</div>
</form>
</template>
+114
View File
@@ -0,0 +1,114 @@
import type {
Col,
KeyLabel,
RecComponent,
RecStrFuncComponent,
RecStrFuncUnknown,
Th,
} from '~/components/pub/custom-ui/data/types'
import { defineAsyncComponent } from 'vue'
type SmallDetailDto = any
const action = defineAsyncComponent(() => import('~/components/pub/custom-ui/data/dropdown-action-dud.vue'))
const statusBadge = defineAsyncComponent(() => import('./status-badge.vue'))
const _doctorStatus = {
0: 'Tidak Aktif',
1: 'Aktif',
}
export const cols: Col[] = [
{ width: 100 },
{ width: 250 },
{},
{ width: 100 },
{ width: 100 },
{},
{},
{},
{ width: 120 },
{ width: 100 },
{},
{},
]
export const header: Th[][] = [
[
{ label: 'Kode JKN' },
{ label: 'Nama' },
{ label: 'No KTP' },
{ label: 'No SIP' },
{ label: 'No IHS' },
{ label: 'Telpon' },
{ label: 'Fee Ranap' },
{ label: 'Fee Rajal' },
{ label: 'Status' },
{ label: '' },
],
]
export const keys = [
'bpjs_code',
'name',
'identity_number',
'sip_no',
'ihs_number',
'phone',
'inPatient_itemPrice',
'outPatient_itemPrice',
'status',
'action',
]
export const delKeyNames: KeyLabel[] = [
{ key: 'code', label: 'Kode' },
{ key: 'name', label: 'Nama' },
]
export const funcParsed: RecStrFuncUnknown = {
name: (rec: unknown): unknown => {
const recX = rec as SmallDetailDto
return `${recX.frontTitle} ${recX.name} ${recX.endTitle}`.trim()
},
identity_number: (rec: unknown): unknown => {
const recX = rec as SmallDetailDto
if (recX.identity_number?.substring(0, 5) === 'BLANK') {
return '(TANPA NIK)'
}
return recX.identity_number
},
inPatient_itemPrice: (rec: unknown): unknown => {
const recX = rec as SmallDetailDto
return Number(recX.inPatient_itemPrice.price).toLocaleString('id-ID')
},
outPatient_itemPrice: (rec: unknown): unknown => {
const recX = rec as SmallDetailDto
return Number(recX.outPatient_itemPrice.price).toLocaleString('id-ID')
},
}
export const funcComponent: RecStrFuncComponent = {
action(rec, idx) {
const res: RecComponent = {
idx,
rec: rec as object,
component: action,
}
return res
},
status(rec, idx) {
const res: RecComponent = {
idx,
rec: rec as object,
component: statusBadge,
}
return res
},
}
export const funcHtml: RecStrFuncUnknown = {
patient_address(_rec) {
return '-'
},
}
+19
View File
@@ -0,0 +1,19 @@
<script setup lang="ts">
import { cols, funcComponent, funcHtml, funcParsed, header, keys } from './list-cfg'
defineProps<{
data: any[]
}>()
</script>
<template>
<PubBaseDataTable
:rows="data"
:cols="cols"
:header="header"
:keys="keys"
:func-parsed="funcParsed"
:func-html="funcHtml"
:func-component="funcComponent"
/>
</template>
@@ -0,0 +1,29 @@
<script setup lang="ts">
import { Badge } from '~/components/pub/ui/badge'
const props = defineProps<{
rec: any
idx?: number
}>()
const doctorStatus = {
0: 'Tidak Aktif',
1: 'Aktif',
}
const statusText = computed(() => {
return doctorStatus[props.rec.status_code as keyof typeof doctorStatus]
})
const badgeVariant = computed(() => {
return props.rec.status_code === 1 ? 'default' : 'destructive'
})
</script>
<template>
<div class="flex justify-center">
<Badge :variant="badgeVariant">
{{ statusText }}
</Badge>
</div>
</template>
+129
View File
@@ -0,0 +1,129 @@
<script setup lang="ts">
// helpers
import { toTypedSchema } from '@vee-validate/zod'
import { useForm } from 'vee-validate'
// types
import type z from 'zod'
import type { DeviceFormData } from '~/schemas/device'
interface Props {
schema: z.ZodSchema<any>
uoms: any[]
items: any[]
}
const isLoading = ref(false)
const props = defineProps<Props>()
const emit = defineEmits<{
submit: [values: DeviceFormData, resetForm: () => void]
cancel: [resetForm: () => void]
}>()
const { handleSubmit, defineField, errors } = useForm({
validationSchema: toTypedSchema(props.schema),
initialValues: {
code: '',
name: '',
uom_code: '',
item_id: '',
} as Partial<DeviceFormData>,
})
const [code, codeAttrs] = defineField('code')
const [name, nameAttrs] = defineField('name')
const [uom, uomAttrs] = defineField('uom_code')
const [item, itemAttrs] = defineField('item_id')
const resetForm = () => {
code.value = ''
name.value = ''
uom.value = ''
item.value = ''
}
// Form submission handler
function onSubmitForm(values: any) {
const formData: DeviceFormData = {
name: values.name || '',
code: values.code || '',
uom_code: values.uom_code || '',
item_id: values.item_id || '',
}
emit('submit', formData, resetForm)
}
// Form cancel handler
function onCancelForm() {
emit('cancel', resetForm)
}
</script>
<template>
<form class="grid gap-2" @submit="handleSubmit(onSubmitForm)">
<div class="grid gap-2">
<label for="code">Kode</label>
<Input
id="code"
v-model="code"
v-bind="codeAttrs"
:disabled="isLoading"
:class="{ 'border-red-500': errors.code }"
/>
<span v-if="errors.code" class="text-sm text-red-500">
{{ errors.code }}
</span>
</div>
<div class="grid gap-2">
<label for="name">Nama</label>
<Input
id="name"
v-model="name"
v-bind="nameAttrs"
:disabled="isLoading"
:class="{ 'border-red-500': errors.name }"
/>
<span v-if="errors.name" class="text-sm text-red-500">
{{ errors.name }}
</span>
</div>
<div class="grid gap-2">
<label for="uom">Satuan</label>
<Select
id="uom"
icon-name="i-lucide-chevron-down"
placeholder="Pilih satuan"
v-model="uom"
v-bind="uomAttrs"
:items="uoms"
:disabled="isLoading"
:class="{ 'border-red-500': errors.uom_code }"
/>
<span v-if="errors.uom_code" class="text-sm text-red-500">
{{ errors.uom_code }}
</span>
</div>
<div class="grid gap-2">
<label for="item">Item</label>
<Select
id="item"
icon-name="i-lucide-chevron-down"
placeholder="Pilih item"
v-model="item"
v-bind="itemAttrs"
:items="items"
:disabled="isLoading"
:class="{ 'border-red-500': errors.item_id }"
/>
<span v-if="errors.item_id" class="text-sm text-red-500">
{{ errors.item_id }}
</span>
</div>
<div class="my-2 flex justify-end gap-2 py-2">
<Button variant="secondary" class="w-[120px]" @click="onCancelForm"> Kembali </Button>
<Button type="submit" class="w-[120px]">
<Loader2 v-if="isLoading" class="mr-2 h-4 w-4 animate-spin" />
Simpan
</Button>
</div>
</form>
</template>
+36
View File
@@ -0,0 +1,36 @@
<script setup lang="ts">
import type { PaginationMeta } from '~/components/pub/custom-ui/pagination/pagination.type'
import { cols, funcComponent, funcHtml, funcParsed, header, keys } from './list-cfg'
interface Props {
data: any[]
paginationMeta?: PaginationMeta
}
defineProps<Props>()
const emit = defineEmits<{
pageChange: [page: number]
}>()
function handlePageChange(page: number) {
emit('pageChange', page)
}
</script>
<template>
<PubBaseDataTable
:rows="data"
:cols="cols"
:header="header"
:keys="keys"
:func-parsed="funcParsed"
:func-html="funcHtml"
:func-component="funcComponent"
/>
<template v-if="paginationMeta">
<div v-if="paginationMeta.totalPage > 1">
<PubCustomUiPagination :pagination-meta="paginationMeta" @page-change="handlePageChange" />
</div>
</template>
</template>
+4 -20
View File
@@ -11,10 +11,6 @@ const data = computed({
get: () => props.modelValue,
set: (val) => emit('update:modelValue', val),
})
const items = [
{ value: 'doctor', label: 'Dokter' },
{ value: 'nurse', label: 'Perawat' },
]
</script>
<template>
@@ -22,30 +18,18 @@ const items = [
<div class="mb-5 border-b border-b-slate-300 pb-3 text-lg xl:text-xl">
<div class="flex flex-col justify-between">
<Block>
<FieldGroup :column="2">
<Label>Username</Label>
<FieldGroup :column="2" layout="stacked">
<Label stacked>Username</Label>
<Field>
<Input v-model="data.name" />
</Field>
</FieldGroup>
<FieldGroup :column="2">
<Label>Password</Label>
<FieldGroup :column="2" layout="stacked">
<Label stacked>Password</Label>
<Field>
<Input v-model="data.password" type="password" />
</Field>
</FieldGroup>
<FieldGroup :column="2">
<Label>Status</Label>
<Field>
<Input v-model="data.status" />
</Field>
</FieldGroup>
<FieldGroup :column="2">
<Label>Tipe</Label>
<Field>
<Select v-model="data.type" :items="items" placeholder="Pilih jenis" />
</Field>
</FieldGroup>
</Block>
</div>
</div>