No files matched your search
@@ -3,7 +3,6 @@ import Block from '~/components/pub/custom-ui/form/block.vue'
|
|||||||
import FieldGroup from '~/components/pub/custom-ui/form/field-group.vue'
|
import FieldGroup from '~/components/pub/custom-ui/form/field-group.vue'
|
||||||
import Field from '~/components/pub/custom-ui/form/field.vue'
|
import Field from '~/components/pub/custom-ui/form/field.vue'
|
||||||
import Label from '~/components/pub/custom-ui/form/label.vue'
|
import Label from '~/components/pub/custom-ui/form/label.vue'
|
||||||
import Action from '~/components/pub/custom-ui/nav-footer/ba-dr-su.vue'
|
|
||||||
|
|
||||||
const props = defineProps<{ modelValue: any }>()
|
const props = defineProps<{ modelValue: any }>()
|
||||||
const emit = defineEmits(['update:modelValue', 'event'])
|
const emit = defineEmits(['update:modelValue', 'event'])
|
||||||
@@ -12,19 +11,10 @@ const data = computed({
|
|||||||
get: () => props.modelValue,
|
get: () => props.modelValue,
|
||||||
set: (val) => emit('update:modelValue', val),
|
set: (val) => emit('update:modelValue', val),
|
||||||
})
|
})
|
||||||
|
|
||||||
function onClick(type: string) {
|
|
||||||
emit('event', type)
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<form id="entry-form">
|
<form id="entry-form">
|
||||||
<div class="mb-5 border-b border-b-slate-300 pb-3 text-lg xl:text-xl">
|
|
||||||
<Icon name="i-lucide-user" class="me-2" />
|
|
||||||
<span class="font-semibold">Tambah</span> Dokter
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-5 border-b border-b-slate-300 pb-3 text-lg xl:text-xl">
|
<div class="mb-5 border-b border-b-slate-300 pb-3 text-lg xl:text-xl">
|
||||||
<div class="flex flex-col justify-between">
|
<div class="flex flex-col justify-between">
|
||||||
<Block>
|
<Block>
|
||||||
@@ -94,24 +84,7 @@ function onClick(type: string) {
|
|||||||
</Field>
|
</Field>
|
||||||
</FieldGroup>
|
</FieldGroup>
|
||||||
</Block>
|
</Block>
|
||||||
<Block>
|
|
||||||
<FieldGroup :column="2">
|
|
||||||
<Label>Username</Label>
|
|
||||||
<Field>
|
|
||||||
<Input type="text" name="username" />
|
|
||||||
</Field>
|
|
||||||
</FieldGroup>
|
|
||||||
<FieldGroup :column="2">
|
|
||||||
<Label>Password</Label>
|
|
||||||
<Field>
|
|
||||||
<Input type="password" name="password" />
|
|
||||||
</Field>
|
|
||||||
</FieldGroup>
|
|
||||||
</Block>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="my-2 flex justify-end py-2">
|
|
||||||
<Action @click="onClick" />
|
|
||||||
</div>
|
|
||||||
</form>
|
</form>
|
||||||
</template>
|
</template>
|
||||||
@@ -8,11 +8,6 @@ import Action from '~/components/pub/custom-ui/nav-footer/ba-dr-su.vue'
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<form id="entry-form">
|
<form id="entry-form">
|
||||||
<div class="mb-5 border-b border-b-slate-300 pb-3 text-lg xl:text-xl">
|
|
||||||
<Icon name="i-lucide-user" class="me-2" />
|
|
||||||
<span class="font-semibold">Tambah</span> Pasien
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-5 border-b border-b-slate-300 pb-3 text-lg xl:text-xl">
|
<div class="mb-5 border-b border-b-slate-300 pb-3 text-lg xl:text-xl">
|
||||||
<Block>
|
<Block>
|
||||||
<FieldGroup :column="3">
|
<FieldGroup :column="3">
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
<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: '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="flex flex-col justify-between">
|
||||||
|
<Block>
|
||||||
|
<FieldGroup :column="2">
|
||||||
|
<Label>Username</Label>
|
||||||
|
<Field>
|
||||||
|
<Input v-model="data.name" />
|
||||||
|
</Field>
|
||||||
|
</FieldGroup>
|
||||||
|
<FieldGroup :column="2">
|
||||||
|
<Label>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>
|
||||||
|
</form>
|
||||||
|
</template>
|
||||||
@@ -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 '-'
|
||||||
|
},
|
||||||
|
}
|
||||||
@@ -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>
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
function onEvent(type: string) {
|
|
||||||
if (type === 'cancel') {
|
|
||||||
navigateTo('/doctor')
|
|
||||||
} else if (type === 'draft') {
|
|
||||||
// do something
|
|
||||||
} else if (type === 'submit') {
|
|
||||||
// do something
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const data = ref({
|
|
||||||
name: '',
|
|
||||||
specialization: '',
|
|
||||||
hospital: '',
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<AppDoctorEntryForm v-model="data" @event="onEvent" />
|
|
||||||
</template>
|
|
||||||
@@ -1,5 +1,9 @@
|
|||||||
<script setup lang="ts"></script>
|
<script setup lang="ts"></script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
<div class="mb-5 border-b border-b-slate-300 pb-3 text-lg xl:text-xl">
|
||||||
|
<Icon name="i-lucide-user" class="me-2" />
|
||||||
|
<span class="font-semibold">Tambah</span> Pasien
|
||||||
|
</div>
|
||||||
<AppPatientEntryForm />
|
<AppPatientEntryForm />
|
||||||
</template>
|
</template>
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import Action from '~/components/pub/custom-ui/nav-footer/ba-dr-su.vue'
|
||||||
|
|
||||||
|
const data = ref({
|
||||||
|
name: '',
|
||||||
|
password: '',
|
||||||
|
status: '',
|
||||||
|
type: '',
|
||||||
|
})
|
||||||
|
|
||||||
|
function onClick(type: string) {
|
||||||
|
if (type === 'cancel') {
|
||||||
|
navigateTo('/human-src/user')
|
||||||
|
} else if (type === 'draft') {
|
||||||
|
// do something
|
||||||
|
} else if (type === 'submit') {
|
||||||
|
// do something
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="mb-5 border-b border-b-slate-300 pb-3 text-lg xl:text-xl">
|
||||||
|
<Icon name="i-lucide-user" class="me-2" />
|
||||||
|
<span class="font-semibold">Tambah</span> Dokter
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<AppDoctorEntryForm v-if="data.type === 'doctor'" v-model="data" />
|
||||||
|
</div>
|
||||||
|
<AppUserEntryForm v-model="data" />
|
||||||
|
<div class="my-2 flex justify-end py-2">
|
||||||
|
<Action @click="onClick" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@@ -26,11 +26,11 @@ const recAction = ref<string>('')
|
|||||||
const recItem = ref<any>(null)
|
const recItem = ref<any>(null)
|
||||||
|
|
||||||
const headerPrep: HeaderPrep = {
|
const headerPrep: HeaderPrep = {
|
||||||
title: 'Dokter',
|
title: 'User',
|
||||||
icon: 'i-lucide-network',
|
icon: 'i-lucide-users',
|
||||||
addNav: {
|
addNav: {
|
||||||
label: 'Tambah',
|
label: 'Tambah',
|
||||||
onClick: () => navigateTo('/doctor/add'),
|
onClick: () => navigateTo('/human-src/user/add'),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ const wrapperClass = computed(() => [
|
|||||||
'w-full flex-shrink-0',
|
'w-full flex-shrink-0',
|
||||||
|
|
||||||
props.column === 1 && props.side !== 'break' ? 'pe-4 md:w-1/1 ' : '',
|
props.column === 1 && props.side !== 'break' ? 'pe-4 md:w-1/1 ' : '',
|
||||||
props.column === 2 && props.side !== 'break' ? 'pe-4 md:w-1/2 ' : '',
|
props.column === 2 && props.side !== 'break' ? 'pe-4 md:w-1/2 my-3' : '',
|
||||||
props.column === 3 && props.side !== 'break' ? 'pe-4 md:w-1/3' : '',
|
props.column === 3 && props.side !== 'break' ? 'pe-4 md:w-1/3' : '',
|
||||||
props.column === 2 && props.side === 'break' ? 'md:w-1/2' : '',
|
props.column === 2 && props.side === 'break' ? 'md:w-1/2' : '',
|
||||||
props.column === 3 && props.side === 'break' ? 'md:w-1/3' : '',
|
props.column === 3 && props.side === 'break' ? 'md:w-1/3' : '',
|
||||||
|
|||||||
@@ -1,8 +1,29 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { SelectRootEmits, SelectRootProps } from 'radix-vue'
|
import { SelectRoot } from 'radix-vue'
|
||||||
import { SelectRoot, useForwardPropsEmits } from 'radix-vue'
|
import {
|
||||||
|
SelectTrigger,
|
||||||
|
SelectContent,
|
||||||
|
SelectValue,
|
||||||
|
SelectGroup,
|
||||||
|
SelectItem,
|
||||||
|
SelectSeparator,
|
||||||
|
} from '~/components/pub/ui/select'
|
||||||
|
import type { SelectRootProps, SelectRootEmits } from 'radix-vue'
|
||||||
|
import { useForwardPropsEmits } from 'radix-vue'
|
||||||
|
|
||||||
const props = defineProps<SelectRootProps>()
|
interface Item {
|
||||||
|
value: string
|
||||||
|
label: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = defineProps<
|
||||||
|
SelectRootProps & {
|
||||||
|
items: Item[]
|
||||||
|
placeholder?: string
|
||||||
|
label?: string
|
||||||
|
separator?: boolean
|
||||||
|
}
|
||||||
|
>()
|
||||||
const emits = defineEmits<SelectRootEmits>()
|
const emits = defineEmits<SelectRootEmits>()
|
||||||
|
|
||||||
const forwarded = useForwardPropsEmits(props, emits)
|
const forwarded = useForwardPropsEmits(props, emits)
|
||||||
@@ -10,6 +31,27 @@ const forwarded = useForwardPropsEmits(props, emits)
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<SelectRoot v-bind="forwarded">
|
<SelectRoot v-bind="forwarded">
|
||||||
<slot />
|
<SelectTrigger class="">
|
||||||
|
<SelectValue :placeholder="placeholder" />
|
||||||
|
</SelectTrigger>
|
||||||
|
|
||||||
|
<SelectContent class="rounded border bg-white">
|
||||||
|
<SelectGroup>
|
||||||
|
<SelectLabel v-if="label" class="px-2 py-1 text-sm font-semibold">
|
||||||
|
{{ label }}
|
||||||
|
</SelectLabel>
|
||||||
|
|
||||||
|
<SelectItem
|
||||||
|
v-for="item in items"
|
||||||
|
:key="item.value"
|
||||||
|
:value="item.value"
|
||||||
|
class="cursor-pointer px-2 py-1 hover:bg-gray-100"
|
||||||
|
>
|
||||||
|
{{ item.label }}
|
||||||
|
</SelectItem>
|
||||||
|
|
||||||
|
<SelectSeparator v-if="separator" class="my-1 h-px bg-gray-200" />
|
||||||
|
</SelectGroup>
|
||||||
|
</SelectContent>
|
||||||
</SelectRoot>
|
</SelectRoot>
|
||||||
</template>
|
</template>
|
||||||
@@ -1,13 +1,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { SelectContentEmits, SelectContentProps } from 'radix-vue'
|
import type { SelectContentEmits, SelectContentProps } from 'radix-vue'
|
||||||
import type { HTMLAttributes } from 'vue'
|
import type { HTMLAttributes } from 'vue'
|
||||||
import {
|
import { SelectContent, SelectPortal, SelectViewport, useForwardPropsEmits } from 'radix-vue'
|
||||||
SelectContent,
|
|
||||||
|
|
||||||
SelectPortal,
|
|
||||||
SelectViewport,
|
|
||||||
useForwardPropsEmits,
|
|
||||||
} from 'radix-vue'
|
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
import { cn } from '~/lib/utils'
|
import { cn } from '~/lib/utils'
|
||||||
|
|
||||||
@@ -17,12 +11,9 @@ defineOptions({
|
|||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
const props = withDefaults(
|
const props = withDefaults(defineProps<SelectContentProps & { class?: HTMLAttributes['class'] }>(), {
|
||||||
defineProps<SelectContentProps & { class?: HTMLAttributes['class'] }>(),
|
position: 'popper',
|
||||||
{
|
})
|
||||||
position: 'popper',
|
|
||||||
},
|
|
||||||
)
|
|
||||||
const emits = defineEmits<SelectContentEmits>()
|
const emits = defineEmits<SelectContentEmits>()
|
||||||
|
|
||||||
const delegatedProps = computed(() => {
|
const delegatedProps = computed(() => {
|
||||||
@@ -37,16 +28,25 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
|||||||
<template>
|
<template>
|
||||||
<SelectPortal>
|
<SelectPortal>
|
||||||
<SelectContent
|
<SelectContent
|
||||||
v-bind="{ ...forwarded, ...$attrs }" :class="cn(
|
v-bind="{ ...forwarded, ...$attrs }"
|
||||||
'relative z-50 max-h-96 min-w-32 overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
|
:class="
|
||||||
position === 'popper'
|
cn(
|
||||||
&& 'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1',
|
'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-96 min-w-32 overflow-hidden rounded-md border shadow-md',
|
||||||
props.class,
|
position === 'popper' &&
|
||||||
)
|
'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1',
|
||||||
|
props.class,
|
||||||
|
)
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<SelectScrollUpButton />
|
<SelectScrollUpButton />
|
||||||
<SelectViewport :class="cn('p-1', position === 'popper' && 'h-[--radix-select-trigger-height] w-full min-w-[--radix-select-trigger-width]')">
|
<SelectViewport
|
||||||
|
:class="
|
||||||
|
cn(
|
||||||
|
'p-1',
|
||||||
|
position === 'popper' && 'h-[--radix-select-trigger-height] w-full min-w-[--radix-select-trigger-width]',
|
||||||
|
)
|
||||||
|
"
|
||||||
|
>
|
||||||
<slot />
|
<slot />
|
||||||
</SelectViewport>
|
</SelectViewport>
|
||||||
<SelectScrollDownButton />
|
<SelectScrollDownButton />
|
||||||
|
|||||||
@@ -19,10 +19,12 @@ const forwardedProps = useForwardProps(delegatedProps)
|
|||||||
<template>
|
<template>
|
||||||
<SelectTrigger
|
<SelectTrigger
|
||||||
v-bind="forwardedProps"
|
v-bind="forwardedProps"
|
||||||
:class="cn(
|
:class="
|
||||||
'flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1',
|
cn(
|
||||||
props.class,
|
'border-input ring-offset-background placeholder:text-muted-foreground flex h-10 w-full rounded-md border border-gray-400 px-3 py-2 text-sm file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:cursor-not-allowed disabled:opacity-50',
|
||||||
)"
|
props.class,
|
||||||
|
)
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<slot />
|
<slot />
|
||||||
<SelectIcon as-child>
|
<SelectIcon as-child>
|
||||||
|
|||||||
@@ -0,0 +1,220 @@
|
|||||||
|
export const activeStatusCodes: Record<string, string> = {
|
||||||
|
active: 'Aktif',
|
||||||
|
inactive: 'Tidak Aktif',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const dataStatusCodes: Record<string, string> = {
|
||||||
|
new: 'Baru',
|
||||||
|
review: 'Review',
|
||||||
|
process: 'Proses',
|
||||||
|
done: 'Selesai',
|
||||||
|
canceled: 'Dibatalkan',
|
||||||
|
rejected: 'Ditolak',
|
||||||
|
skiped: 'Dilewati',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const userStatusCodes: Record<string, string> = {
|
||||||
|
new: 'Baru',
|
||||||
|
active: 'Aktif',
|
||||||
|
inactive: 'Tidak Aktif',
|
||||||
|
blocked: 'Diblokir',
|
||||||
|
suspended: 'Dibekukan',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const itemGroupCodes: Record<string, string> = {
|
||||||
|
infra: 'Infrastruktur',
|
||||||
|
medicine: 'Obat',
|
||||||
|
device: 'Peralatan',
|
||||||
|
material: 'Perlengkapan',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const unitTypeCodes: Record<string, string> = {
|
||||||
|
reg: 'Registrasi',
|
||||||
|
exa: 'Pemeriksaan',
|
||||||
|
pay: 'Pembayaran',
|
||||||
|
pha: 'Farmasai',
|
||||||
|
lab: 'Laboratorium',
|
||||||
|
rad: 'Radiologi',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const queueStatusCodes: Record<string, string> = {
|
||||||
|
wait: 'Tunggu',
|
||||||
|
proc: 'Proses',
|
||||||
|
done: 'Selesai',
|
||||||
|
cancel: 'Batal',
|
||||||
|
skip: 'Dilewati',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const encounterClassCodes: Record<string, string> = {
|
||||||
|
outpatient: 'Rawat Jalan',
|
||||||
|
ambulatory: 'Rawat Jalan',
|
||||||
|
emergency: 'Gawat Darurat',
|
||||||
|
inpatient: 'Rawat Inap',
|
||||||
|
draft: 'Draft',
|
||||||
|
done: 'Selesai',
|
||||||
|
cancel: 'Batal',
|
||||||
|
skip: 'Dilewati',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const timeUnitCodes: Record<string, string> = {
|
||||||
|
sec: 'Detik',
|
||||||
|
min: 'Menit',
|
||||||
|
hour: 'Jam',
|
||||||
|
day: 'Hari',
|
||||||
|
week: 'Minggu',
|
||||||
|
month: 'Bulan',
|
||||||
|
year: 'Tahun',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const dischargeMethodCodes: Record<string, string> = {
|
||||||
|
home: 'Home',
|
||||||
|
'home-request': 'Home Request',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const genderCodes: Record<string, string> = {
|
||||||
|
male: 'Laki - Laki',
|
||||||
|
female: 'Perempuan',
|
||||||
|
'not-stated': 'Tidak Disebutkan',
|
||||||
|
unknown: 'Tidak Diketahui',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const religionCodes: Record<string, string> = {
|
||||||
|
islam: 'Islam',
|
||||||
|
protestan: 'Protestan',
|
||||||
|
katolik: 'Katolik',
|
||||||
|
hindu: 'Hindu',
|
||||||
|
buda: 'Buda',
|
||||||
|
konghucu: 'Konghucu',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const educationCodes: Record<string, string> = {
|
||||||
|
TS: 'TS',
|
||||||
|
TK: 'TK',
|
||||||
|
SD: 'SD',
|
||||||
|
SMP: 'SMP',
|
||||||
|
SMA: 'SMA',
|
||||||
|
D1: 'D1',
|
||||||
|
D2: 'D2',
|
||||||
|
D3: 'D3',
|
||||||
|
S1: 'S1',
|
||||||
|
S2: 'S2',
|
||||||
|
S3: 'S3',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const occupationCodes: Record<string, string> = {
|
||||||
|
'tidak-bekerja': 'Tidak Bekerja',
|
||||||
|
pns: 'Pegawai Negeri Sipil',
|
||||||
|
polisi: 'Polisi',
|
||||||
|
tni: 'TNI',
|
||||||
|
guru: 'Guru',
|
||||||
|
wiraswasta: 'Wiraswasta',
|
||||||
|
'kary-swasta': 'Karyawan Swasta',
|
||||||
|
lainnya: 'Lainnya',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const personContactTypes: Record<string, string> = {
|
||||||
|
phone: 'Telepon',
|
||||||
|
'm-phone': 'HP / Ponsel',
|
||||||
|
email: 'Email',
|
||||||
|
fax: 'Fax',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const dayCodes: Record<string, string> = {
|
||||||
|
'0': 'Minggu',
|
||||||
|
'1': '',
|
||||||
|
'2': '',
|
||||||
|
'3': '',
|
||||||
|
'4': '',
|
||||||
|
'5': '',
|
||||||
|
'6': 'Sabtu',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const paymentMethodCodes: Record<string, string> = {
|
||||||
|
cash: 'Cash',
|
||||||
|
debit: 'Debit',
|
||||||
|
credit: 'Kredit',
|
||||||
|
insurance: 'Asuransi',
|
||||||
|
membership: 'Membership',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const transportationCodes: Record<string, string> = {
|
||||||
|
ambulance: 'Ambulans',
|
||||||
|
car: 'Mobil',
|
||||||
|
'motor-cycle': 'Motor',
|
||||||
|
other: 'Lainnya',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const personConditionCodes: Record<string, string> = {
|
||||||
|
res: 'Resutiasi',
|
||||||
|
emg: 'Darurat',
|
||||||
|
urg: 'Mendesak',
|
||||||
|
lurg: 'Kurang Mendesak',
|
||||||
|
nurg: 'Mendesak',
|
||||||
|
doa: 'Meninggal Saat Tiba',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const emergencyClassCodes: Record<string, string> = {
|
||||||
|
emg: 'Darurat',
|
||||||
|
eon: 'Ponek',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const outpatientClassCodes: Record<string, string> = {
|
||||||
|
op: 'Rawat Inap',
|
||||||
|
icu: 'ICU',
|
||||||
|
hcu: 'HCU',
|
||||||
|
vk: 'Kamar Bersalin',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const checkupScopeCodes: Record<string, string> = {
|
||||||
|
lab: 'Laboratorium',
|
||||||
|
'mic-lab': 'Microbacterial Laboratorium',
|
||||||
|
'pa-lab': 'Patology Anatomy Laboratorium',
|
||||||
|
rad: 'Radiology',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const employeePositionCodes: Record<string, string> = {
|
||||||
|
doctor: 'Dokter',
|
||||||
|
nurse: 'Perawat',
|
||||||
|
nutritionist: 'Ahli Gisi',
|
||||||
|
laborant: 'Laboran',
|
||||||
|
pharmacy: 'Farmasi',
|
||||||
|
payment: 'Pembayaran',
|
||||||
|
'payment-verificator': 'Konfirmasi Pembayaran',
|
||||||
|
management: 'Management',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const subjectCodes: Record<string, string> = {
|
||||||
|
'pri-compl': 'Primary Complaint',
|
||||||
|
'sec-compl': 'Secondary Complaint',
|
||||||
|
'cur-disea-hist': 'Current Disease History',
|
||||||
|
'pas-disea-hist': 'Past Disease History',
|
||||||
|
'fam-disea-hist': 'Family Disease History',
|
||||||
|
'alg-hist': 'Allergic Hist',
|
||||||
|
'alg-react': 'Allergic Reaction',
|
||||||
|
'med-hist': 'Medication Hist',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const objectCodes: Record<string, string> = {
|
||||||
|
'consc-level': 'Tingkat Kesadaran',
|
||||||
|
'consc-level-det': 'Detail Tingkat Kesadaran',
|
||||||
|
'syst-bp': 'Tekanan Darah Systolic',
|
||||||
|
'diast-bp': 'Tekanan Darah Diastolic',
|
||||||
|
'hear-rt': 'Detak Jantung',
|
||||||
|
temp: 'Suhu',
|
||||||
|
spo2: 'SpO2',
|
||||||
|
weight: 'Berat Badan',
|
||||||
|
height: 'Tinggi Badan',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const assessmentCodes: Record<string, string> = {
|
||||||
|
'early-diag': 'Diagnosis Awal',
|
||||||
|
'late-diag': 'Diagnosis Akhir',
|
||||||
|
'sec-diag': 'Diagnosis Sekunder',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const instructionCodes: Record<string, string> = {
|
||||||
|
detail: 'Detail Instruksi',
|
||||||
|
'med-act': 'Tindakan medis',
|
||||||
|
medication: 'Obat',
|
||||||
|
material: 'BMHP',
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import type { PagePermission } from '~/models/role'
|
||||||
|
import Error from '~/components/pub/base/error/error.vue'
|
||||||
|
import { PAGE_PERMISSIONS } from '~/lib/page-permission'
|
||||||
|
|
||||||
|
definePageMeta({
|
||||||
|
middleware: ['rbac'],
|
||||||
|
roles: ['doctor', 'nurse', 'admisi', 'pharmacy', 'billing', 'management'],
|
||||||
|
title: 'Tambah User',
|
||||||
|
contentFrame: 'cf-full-width',
|
||||||
|
})
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
|
||||||
|
useHead({
|
||||||
|
title: () => route.meta.title as string,
|
||||||
|
})
|
||||||
|
|
||||||
|
const roleAccess: PagePermission = PAGE_PERMISSIONS['/doctor']
|
||||||
|
|
||||||
|
const { checkRole, hasCreateAccess } = useRBAC()
|
||||||
|
|
||||||
|
// Check if user has access to this page
|
||||||
|
const hasAccess = checkRole(roleAccess)
|
||||||
|
if (!hasAccess) {
|
||||||
|
throw createError({
|
||||||
|
statusCode: 403,
|
||||||
|
statusMessage: 'Access denied',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define permission-based computed properties
|
||||||
|
const canCreate = hasCreateAccess(roleAccess)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div v-if="canCreate">
|
||||||
|
<FlowUserEntry />
|
||||||
|
</div>
|
||||||
|
<Error v-else :status-code="403" />
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import type { PagePermission } from '~/models/role'
|
||||||
|
import Error from '~/components/pub/base/error/error.vue'
|
||||||
|
import { PAGE_PERMISSIONS } from '~/lib/page-permission'
|
||||||
|
|
||||||
|
definePageMeta({
|
||||||
|
middleware: ['rbac'],
|
||||||
|
roles: ['doctor', 'nurse', 'admisi', 'pharmacy', 'billing', 'management'],
|
||||||
|
title: 'Daftar User',
|
||||||
|
contentFrame: 'cf-full-width',
|
||||||
|
})
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
|
||||||
|
useHead({
|
||||||
|
title: () => route.meta.title as string,
|
||||||
|
})
|
||||||
|
|
||||||
|
const roleAccess: PagePermission = PAGE_PERMISSIONS['/doctor']
|
||||||
|
|
||||||
|
const { checkRole, hasReadAccess } = useRBAC()
|
||||||
|
|
||||||
|
// Check if user has access to this page
|
||||||
|
const hasAccess = checkRole(roleAccess)
|
||||||
|
if (!hasAccess) {
|
||||||
|
navigateTo('/403')
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define permission-based computed properties
|
||||||
|
const canRead = hasReadAccess(roleAccess)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div v-if="canRead">
|
||||||
|
<FlowUserList />
|
||||||
|
</div>
|
||||||
|
<Error v-else :status-code="403" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
definePageMeta({
|
||||||
|
layout: 'blank',
|
||||||
|
public: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
const contentFrame = computed(() => route.meta.contentFrame)
|
||||||
|
const contentContent = computed(() => {
|
||||||
|
switch (contentFrame.value) {
|
||||||
|
case 'cf-container-lg':
|
||||||
|
return 'cf-frame cf-container-lg-content'
|
||||||
|
case 'cf-container-md':
|
||||||
|
return 'cf-frame cf-container-md-content'
|
||||||
|
case 'cf-container-sm':
|
||||||
|
return 'cf-frame cf-container-sm-content'
|
||||||
|
case 'cf-full-width':
|
||||||
|
return 'cf-frame-width'
|
||||||
|
default:
|
||||||
|
return 'cf-frame'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const teams: {
|
||||||
|
name: string
|
||||||
|
logo: string
|
||||||
|
plan: string
|
||||||
|
}[] = [
|
||||||
|
{
|
||||||
|
name: 'SIMRS - RSSA',
|
||||||
|
logo: '/rssa-logo.png',
|
||||||
|
plan: 'Saiful Anwar Hospital',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
const sidebar = {
|
||||||
|
collapsible: 'offcanvas', // 'offcanvas' | 'icon' | 'none'
|
||||||
|
side: 'left', // 'left' | 'right'
|
||||||
|
variant: 'sidebar', // 'sidebar' | 'floating' | 'inset'
|
||||||
|
}
|
||||||
|
|
||||||
|
const navMenu = ref({
|
||||||
|
heading: 'Main Menu',
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
title: 'Test User List',
|
||||||
|
icon: 'i-lucide-user',
|
||||||
|
component: defineAsyncComponent(() => import('~/pages/_dev/user/list.vue')),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
|
||||||
|
const activeComponent = ref<any>(null)
|
||||||
|
|
||||||
|
function selectComponent(item: any) {
|
||||||
|
activeComponent.value = item.component
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<SidebarProvider>
|
||||||
|
<Sidebar :collapsible="sidebar.collapsible" :side="sidebar.side" :variant="sidebar.variant">
|
||||||
|
<SidebarHeader>
|
||||||
|
<LayoutSidebarNavHeader :teams="teams" />
|
||||||
|
</SidebarHeader>
|
||||||
|
<SidebarContent>
|
||||||
|
<SidebarGroup v-if="navMenu.items.length > 0">
|
||||||
|
<SidebarGroupLabel>
|
||||||
|
{{ navMenu.heading }}
|
||||||
|
</SidebarGroupLabel>
|
||||||
|
<button
|
||||||
|
v-for="(item, index) in navMenu.items"
|
||||||
|
:key="index"
|
||||||
|
class="my-2 mb-2 flex w-full items-center gap-2 rounded px-2 py-1 hover:bg-gray-100"
|
||||||
|
@click="selectComponent(item)"
|
||||||
|
>
|
||||||
|
<i :class="item.icon"></i>
|
||||||
|
{{ item.title }}
|
||||||
|
</button>
|
||||||
|
</SidebarGroup>
|
||||||
|
</SidebarContent>
|
||||||
|
<SidebarFooter>
|
||||||
|
<LayoutSidebarNavFooter />
|
||||||
|
</SidebarFooter>
|
||||||
|
<SidebarRail />
|
||||||
|
</Sidebar>
|
||||||
|
|
||||||
|
<SidebarInset>
|
||||||
|
<LayoutHeader />
|
||||||
|
<div class="w-full min-w-0 flex-1 overflow-x-auto p-4 lg:p-6">
|
||||||
|
<div v-if="activeComponent">
|
||||||
|
<component :is="activeComponent" />
|
||||||
|
</div>
|
||||||
|
<div v-else class="text-gray-500">Playground untuk testing component</div>
|
||||||
|
</div>
|
||||||
|
</SidebarInset>
|
||||||
|
</SidebarProvider>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
definePageMeta({
|
||||||
|
layout: 'blank',
|
||||||
|
public: true,
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>test tambah user</div>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
definePageMeta({
|
||||||
|
layout: 'blank',
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>test list user</div>
|
||||||
|
</template>
|
||||||
+3
-2
@@ -18,14 +18,15 @@ export default withNuxt(
|
|||||||
{
|
{
|
||||||
rules: {
|
rules: {
|
||||||
// Basic rules
|
// Basic rules
|
||||||
'quotes': ['error', 'single', { avoidEscape: true }],
|
quotes: ['error', 'single', { avoidEscape: true }],
|
||||||
|
'style/quote-props': 'off',
|
||||||
'style/no-trailing-spaces': ['error', { ignoreComments: true }],
|
'style/no-trailing-spaces': ['error', { ignoreComments: true }],
|
||||||
|
|
||||||
'no-console': 'off',
|
'no-console': 'off',
|
||||||
|
|
||||||
// Relax strict formatting rules
|
// Relax strict formatting rules
|
||||||
'style/brace-style': 'off', // Allow inline if
|
'style/brace-style': 'off', // Allow inline if
|
||||||
'curly': ['error', 'multi-line'], // Only require braces for multi-line
|
curly: ['error', 'multi-line'], // Only require braces for multi-line
|
||||||
'style/arrow-parens': 'off',
|
'style/arrow-parens': 'off',
|
||||||
|
|
||||||
// UnoCSS - make it warning instead of error, or disable completely
|
// UnoCSS - make it warning instead of error, or disable completely
|
||||||
|
|||||||
@@ -30,6 +30,17 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"title": "Karyawan",
|
||||||
|
"icon": "i-lucide-users",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"title": "User",
|
||||||
|
"icon": "i-lucide-user",
|
||||||
|
"link": "/human-src/user"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"title": "Dokter",
|
"title": "Dokter",
|
||||||
"icon": "i-lucide-cross",
|
"icon": "i-lucide-cross",
|
||||||
|
|||||||
Reference in New Issue
Block a user