✨ feat (item): add item and item price modules
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
<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),
|
||||
})
|
||||
|
||||
const items = [
|
||||
{ value: '1', label: 'item 1' },
|
||||
{ value: '2', label: 'item 2' },
|
||||
{ value: '3', label: 'item 3' },
|
||||
{ value: '4', label: 'item 4' },
|
||||
]
|
||||
</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>
|
||||
<Label>Items</Label>
|
||||
<Field>
|
||||
<Select :items="items" />
|
||||
</Field>
|
||||
</FieldGroup>
|
||||
<FieldGroup>
|
||||
<Label>Perusahaan Insuransi</Label>
|
||||
<Field>
|
||||
<Select :items="items" />
|
||||
</Field>
|
||||
</FieldGroup>
|
||||
<FieldGroup>
|
||||
<Label>Harga</Label>
|
||||
<Field>
|
||||
<Input v-model="data.price" />
|
||||
</Field>
|
||||
</FieldGroup>
|
||||
</Block>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</template>
|
||||
@@ -0,0 +1,46 @@
|
||||
import type {
|
||||
Col,
|
||||
KeyLabel,
|
||||
RecComponent,
|
||||
RecStrFuncComponent,
|
||||
RecStrFuncUnknown,
|
||||
Th,
|
||||
} from '~/components/pub/custom-ui/data/types'
|
||||
import { defineAsyncComponent } from 'vue'
|
||||
|
||||
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: 50 }]
|
||||
|
||||
export const header: Th[][] = [[{ label: 'Kode' }, { label: 'Nama' }, { label: 'Aksi' }]]
|
||||
|
||||
export const keys = ['code', 'name', 'action']
|
||||
|
||||
export const delKeyNames: KeyLabel[] = [
|
||||
{ key: 'code', label: 'Kode' },
|
||||
{ key: 'name', label: 'Nama' },
|
||||
]
|
||||
|
||||
export const funcParsed: RecStrFuncUnknown = {}
|
||||
|
||||
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 '-'
|
||||
},
|
||||
}
|
||||
@@ -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,68 @@
|
||||
<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),
|
||||
})
|
||||
|
||||
const items = [
|
||||
{ value: '1', label: 'item 1' },
|
||||
{ value: '2', label: 'item 2' },
|
||||
{ value: '3', label: 'item 3' },
|
||||
{ value: '4', label: 'item 4' },
|
||||
]
|
||||
</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>
|
||||
<Label>Nama</Label>
|
||||
<Field>
|
||||
<Input v-model="data.name" />
|
||||
</Field>
|
||||
</FieldGroup>
|
||||
<FieldGroup>
|
||||
<Label>Kode</Label>
|
||||
<Field>
|
||||
<Input v-model="data.code" />
|
||||
</Field>
|
||||
</FieldGroup>
|
||||
<FieldGroup>
|
||||
<Label>Item Group</Label>
|
||||
<Field>
|
||||
<Select :items="items" />
|
||||
</Field>
|
||||
</FieldGroup>
|
||||
<FieldGroup>
|
||||
<Label>UOM</Label>
|
||||
<Field>
|
||||
<Select :items="items" />
|
||||
</Field>
|
||||
</FieldGroup>
|
||||
<FieldGroup>
|
||||
<Label>Infra</Label>
|
||||
<Field>
|
||||
<Select :items="items" />
|
||||
</Field>
|
||||
</FieldGroup>
|
||||
<FieldGroup>
|
||||
<Label>Harga</Label>
|
||||
<Field>
|
||||
<Input v-model="data.price" />
|
||||
</Field>
|
||||
</FieldGroup>
|
||||
</Block>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</template>
|
||||
@@ -0,0 +1,46 @@
|
||||
import type {
|
||||
Col,
|
||||
KeyLabel,
|
||||
RecComponent,
|
||||
RecStrFuncComponent,
|
||||
RecStrFuncUnknown,
|
||||
Th,
|
||||
} from '~/components/pub/custom-ui/data/types'
|
||||
import { defineAsyncComponent } from 'vue'
|
||||
|
||||
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: 50 }]
|
||||
|
||||
export const header: Th[][] = [[{ label: 'Kode' }, { label: 'Nama' }, { label: 'Aksi' }]]
|
||||
|
||||
export const keys = ['code', 'name', 'action']
|
||||
|
||||
export const delKeyNames: KeyLabel[] = [
|
||||
{ key: 'code', label: 'Kode' },
|
||||
{ key: 'name', label: 'Nama' },
|
||||
]
|
||||
|
||||
export const funcParsed: RecStrFuncUnknown = {}
|
||||
|
||||
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 '-'
|
||||
},
|
||||
}
|
||||
@@ -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,71 @@
|
||||
<script setup lang="ts">
|
||||
import type { DataTableLoader } from '~/components/pub/base/data-table/type'
|
||||
import type { HeaderPrep, RefSearchNav } from '~/components/pub/custom-ui/data/types'
|
||||
import Modal from '~/components/pub/base/modal/modal.vue'
|
||||
import Header from '~/components/pub/custom-ui/nav-header/prep.vue'
|
||||
|
||||
const data = ref([])
|
||||
const entry = ref<any>({})
|
||||
|
||||
const refSearchNav: RefSearchNav = {
|
||||
onClick: () => {
|
||||
// open filter modal
|
||||
},
|
||||
onInput: (_val: string) => {
|
||||
// filter patient list
|
||||
},
|
||||
onClear: () => {
|
||||
// clear url param
|
||||
},
|
||||
}
|
||||
|
||||
// Loading state management
|
||||
const isLoading = reactive<DataTableLoader>({
|
||||
summary: false,
|
||||
isTableLoading: false,
|
||||
})
|
||||
|
||||
const isOpen = ref(false)
|
||||
|
||||
const recId = ref<number>(0)
|
||||
const recAction = ref<string>('')
|
||||
const recItem = ref<any>(null)
|
||||
|
||||
const hreaderPrep: HeaderPrep = {
|
||||
title: 'Golongan Obat',
|
||||
icon: 'i-lucide-users',
|
||||
addNav: {
|
||||
label: 'Tambah',
|
||||
onClick: () => (isOpen.value = true),
|
||||
},
|
||||
}
|
||||
|
||||
async function getPatientList() {
|
||||
isLoading.isTableLoading = true
|
||||
const resp = await xfetch('/api/v1/medicine-group')
|
||||
if (resp.success) {
|
||||
data.value = (resp.body as Record<string, any>).data
|
||||
}
|
||||
isLoading.isTableLoading = false
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getPatientList()
|
||||
})
|
||||
|
||||
provide('rec_id', recId)
|
||||
provide('rec_action', recAction)
|
||||
provide('rec_item', recItem)
|
||||
provide('table_data_loader', isLoading)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Header :prep="{ ...hreaderPrep }" :ref-search-nav="refSearchNav" />
|
||||
<div class="my-4 flex flex-1 flex-col gap-4 md:gap-8">
|
||||
<AppMedicineGroupList :data="data" />
|
||||
</div>
|
||||
|
||||
<Modal v-model:open="isOpen" title="Tambah Golongan Obat" size="lg" prevent-outside>
|
||||
<AppMedicineGroupEntryForm v-model="entry" />
|
||||
</Modal>
|
||||
</template>
|
||||
@@ -0,0 +1,71 @@
|
||||
<script setup lang="ts">
|
||||
import type { DataTableLoader } from '~/components/pub/base/data-table/type'
|
||||
import type { HeaderPrep, RefSearchNav } from '~/components/pub/custom-ui/data/types'
|
||||
import Modal from '~/components/pub/base/modal/modal.vue'
|
||||
import Header from '~/components/pub/custom-ui/nav-header/prep.vue'
|
||||
|
||||
const data = ref([])
|
||||
const entry = ref<any>({})
|
||||
|
||||
const refSearchNav: RefSearchNav = {
|
||||
onClick: () => {
|
||||
// open filter modal
|
||||
},
|
||||
onInput: (_val: string) => {
|
||||
// filter patient list
|
||||
},
|
||||
onClear: () => {
|
||||
// clear url param
|
||||
},
|
||||
}
|
||||
|
||||
// Loading state management
|
||||
const isLoading = reactive<DataTableLoader>({
|
||||
summary: false,
|
||||
isTableLoading: false,
|
||||
})
|
||||
|
||||
const isOpen = ref(false)
|
||||
|
||||
const recId = ref<number>(0)
|
||||
const recAction = ref<string>('')
|
||||
const recItem = ref<any>(null)
|
||||
|
||||
const hreaderPrep: HeaderPrep = {
|
||||
title: 'Item',
|
||||
icon: 'i-lucide-users',
|
||||
addNav: {
|
||||
label: 'Tambah',
|
||||
onClick: () => (isOpen.value = true),
|
||||
},
|
||||
}
|
||||
|
||||
async function getPatientList() {
|
||||
isLoading.isTableLoading = true
|
||||
const resp = await xfetch('/api/v1/medicine-group')
|
||||
if (resp.success) {
|
||||
data.value = (resp.body as Record<string, any>).data
|
||||
}
|
||||
isLoading.isTableLoading = false
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getPatientList()
|
||||
})
|
||||
|
||||
provide('rec_id', recId)
|
||||
provide('rec_action', recAction)
|
||||
provide('rec_item', recItem)
|
||||
provide('table_data_loader', isLoading)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Header :prep="{ ...hreaderPrep }" :ref-search-nav="refSearchNav" />
|
||||
<div class="my-4 flex flex-1 flex-col gap-4 md:gap-8">
|
||||
<AppItemList :data="data" />
|
||||
</div>
|
||||
|
||||
<Modal v-model:open="isOpen" title="Tambah Golongan Obat" size="xl" prevent-outside>
|
||||
<AppItemEntryForm v-model="entry" />
|
||||
</Modal>
|
||||
</template>
|
||||
@@ -2,10 +2,14 @@
|
||||
import type { DataTableLoader } from '~/components/pub/base/data-table/type'
|
||||
import type { HeaderPrep, RefSearchNav } from '~/components/pub/custom-ui/data/types'
|
||||
import Modal from '~/components/pub/base/modal/modal.vue'
|
||||
import Pagination from '~/components/pub/base/pagination/pagination.vue'
|
||||
import Header from '~/components/pub/custom-ui/nav-header/prep.vue'
|
||||
|
||||
const data = ref([])
|
||||
const entry = ref<any>({})
|
||||
const page = ref(1)
|
||||
const rowsPerPage = ref(10)
|
||||
const totalPages = 20
|
||||
|
||||
const refSearchNav: RefSearchNav = {
|
||||
onClick: () => {
|
||||
@@ -63,6 +67,7 @@ provide('table_data_loader', isLoading)
|
||||
<Header :prep="{ ...hreaderPrep }" :ref-search-nav="refSearchNav" />
|
||||
<div class="my-4 flex flex-1 flex-col gap-4 md:gap-8">
|
||||
<AppMedicineGroupList :data="data" />
|
||||
<Pagination v-model:page="page" v-model:rows-per-page="rowsPerPage" :total-pages="totalPages" />
|
||||
</div>
|
||||
|
||||
<Modal v-model:open="isOpen" title="Tambah Golongan Obat" size="lg" prevent-outside>
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
export interface ItemPrice {
|
||||
id: string
|
||||
item_id: number
|
||||
price: number
|
||||
insuranceCompany_code: string
|
||||
}
|
||||
|
||||
export interface CreateDto {
|
||||
item_id: number
|
||||
price: number
|
||||
insuranceCompany_code: string
|
||||
}
|
||||
|
||||
export interface GetListDto {
|
||||
page: number
|
||||
size: number
|
||||
name?: string
|
||||
code?: string
|
||||
}
|
||||
|
||||
export interface GetDetailDto {
|
||||
id?: string
|
||||
}
|
||||
|
||||
export interface UpdateDto extends CreateDto {
|
||||
id?: number
|
||||
}
|
||||
|
||||
export interface DeleteDto {
|
||||
id?: string
|
||||
}
|
||||
|
||||
export function genMedicine(): CreateDto {
|
||||
return {
|
||||
item_id: 1,
|
||||
price: 1,
|
||||
insuranceCompany_code: 'test',
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
export interface Item {
|
||||
id: string
|
||||
name: string
|
||||
code: string
|
||||
itemGroup_code: string
|
||||
uom_code: string
|
||||
infra_id: number
|
||||
stock: number
|
||||
}
|
||||
|
||||
export interface CreateDto {
|
||||
name: string
|
||||
code: string
|
||||
itemGroup_code: string
|
||||
uom_code: string
|
||||
infra_id: number
|
||||
stock: number
|
||||
}
|
||||
|
||||
export interface GetListDto {
|
||||
page: number
|
||||
size: number
|
||||
name?: string
|
||||
code?: string
|
||||
}
|
||||
|
||||
export interface GetDetailDto {
|
||||
id?: string
|
||||
}
|
||||
|
||||
export interface UpdateDto extends CreateDto {
|
||||
id?: number
|
||||
}
|
||||
|
||||
export interface DeleteDto {
|
||||
id?: string
|
||||
}
|
||||
|
||||
export function genMedicine(): CreateDto {
|
||||
return {
|
||||
name: 'test',
|
||||
code: 'test',
|
||||
itemGroup_code: 'test',
|
||||
uom_code: 'test',
|
||||
infra_id: 1,
|
||||
stock: 1,
|
||||
}
|
||||
}
|
||||
@@ -49,7 +49,7 @@ const navMenu = ref({
|
||||
{
|
||||
title: 'Test Medicine List',
|
||||
icon: 'i-lucide-user',
|
||||
component: defineAsyncComponent(() => import('~/components/flow/medicine-method/list.vue')),
|
||||
component: defineAsyncComponent(() => import('~/components/flow/item/list.vue')),
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user