diff --git a/components/pendaftaran/BiodataPasien.vue b/components/pendaftaran/BiodataPasien.vue index 87f74e6..fc80441 100644 --- a/components/pendaftaran/BiodataPasien.vue +++ b/components/pendaftaran/BiodataPasien.vue @@ -1,4 +1,12 @@ @@ -122,9 +140,13 @@ const deletePhoneNumber = (index: number) => { placeholder="Masukan Nomor RM / Nama Pasien" variant="outlined" maxlength="8" - density="comfortable" + density="comfortable" + type="tel" :rules="[rules.required]" hide-details="auto" + :readonly="readonly" + :bg-color="readonly ? 'grey-lighten-3' : undefined" + @input="handleRmInput" > @@ -145,7 +167,7 @@ const deletePhoneNumber = (index: number) => { Jenis Kelamin - + @@ -197,13 +219,14 @@ const deletePhoneNumber = (index: number) => { :key="index" class="px-4 mb-2" border - @click="editPhoneNumber(index)" - style="cursor: pointer;" + @click="!readonly && editPhoneNumber(index)" + :style="readonly ? 'cursor: default;' : 'cursor: pointer;'" > {{ phone }} { { :disabled="!newPhoneNumber.trim() || phoneError !== true" > mdi-check - Save + Simpan diff --git a/components/pendaftaran/MedisPasien.vue b/components/pendaftaran/MedisPasien.vue index f3500bf..8af7fe0 100644 --- a/components/pendaftaran/MedisPasien.vue +++ b/components/pendaftaran/MedisPasien.vue @@ -14,6 +14,14 @@ interface TindakanItem { tindakanTambahan?: string; } +interface Props { + readonly?: boolean; +} + +const props = withDefaults(defineProps(), { + readonly: false +}); + const diagnosisItems = defineModel('diagnosisItems', { required: true }); const tindakanItems = defineModel('tindakanItems', { required: true }); @@ -186,8 +194,8 @@ const handleKodeTindakanChange = (kode: string) => { v-for="(item, index) in diagnosisItems" :key="index" class="px-4 mb-2" - @click="editDiagnosis(index)" - style="cursor: pointer;" + @click="!readonly && editDiagnosis(index)" + :style="readonly ? 'cursor: default;' : 'cursor: pointer;'" > @@ -198,6 +206,7 @@ const handleKodeTindakanChange = (kode: string) => { { - + Tambah Diagnosa @@ -235,8 +244,8 @@ const handleKodeTindakanChange = (kode: string) => { v-for="(item, index) in tindakanItems" :key="index" class="px-4 mb-2" - @click="editTindakan(index)" - style="cursor: pointer;" + @click="!readonly && editTindakan(index)" + :style="readonly ? 'cursor: default;' : 'cursor: pointer;'" > @@ -247,6 +256,7 @@ const handleKodeTindakanChange = (kode: string) => { { - + Tambah Tindakan @@ -336,7 +346,7 @@ const handleKodeTindakanChange = (kode: string) => { :disabled="!diagnosisForm.kodeDiagnosa.trim() || !diagnosisForm.diagnosa.trim()" > mdi-check - Save + Simpan @@ -414,7 +424,7 @@ const handleKodeTindakanChange = (kode: string) => { :disabled="!tindakanForm.kodeTindakan.trim() || !tindakanForm.tindakan.trim()" > mdi-check - Save + Simpan diff --git a/components/pendaftaran/RencanaOperasi.vue b/components/pendaftaran/RencanaOperasi.vue index 7da361a..d433cdb 100644 --- a/components/pendaftaran/RencanaOperasi.vue +++ b/components/pendaftaran/RencanaOperasi.vue @@ -11,6 +11,14 @@ interface Dokter { satuan_kerja: string; } +interface Props { + readonly?: boolean; +} + +const props = withDefaults(defineProps(), { + readonly: false +}); + const rencanaOperasiData = defineModel<{ spesialis: number | null | undefined; subSpesialis: number | null | undefined; @@ -146,6 +154,9 @@ const toggleDokterSelection = (dokterId: number) => { density="comfortable" :rules="[rules.required]" hide-details="auto" + :readonly="readonly" + :disabled="readonly" + :bg-color="readonly ? 'grey-lighten-3' : undefined" > @@ -160,7 +171,9 @@ const toggleDokterSelection = (dokterId: number) => { density="comfortable" :rules="[rules.required]" hide-details="auto" - :disabled="!rencanaOperasiData.spesialis" + :disabled="readonly || !rencanaOperasiData.spesialis" + :readonly="readonly" + :bg-color="readonly ? 'grey-lighten-3' : undefined" > @@ -182,8 +195,9 @@ const toggleDokterSelection = (dokterId: number) => { @@ -194,6 +208,7 @@ const toggleDokterSelection = (dokterId: number) => { { - + Tambah Dokter Pelaksana @@ -222,6 +237,8 @@ const toggleDokterSelection = (dokterId: number) => { density="comfortable" :rules="[rules.required]" hide-details="auto" + :readonly="readonly" + :bg-color="readonly ? 'grey-lighten-3' : undefined" > @@ -236,6 +253,9 @@ const toggleDokterSelection = (dokterId: number) => { density="comfortable" :rules="[rules.required]" hide-details="auto" + :readonly="readonly" + :disabled="readonly" + :bg-color="readonly ? 'grey-lighten-3' : undefined" > @@ -247,6 +267,8 @@ const toggleDokterSelection = (dokterId: number) => { variant="outlined" rows="5" hide-details="auto" + :readonly="readonly" + :bg-color="readonly ? 'grey-lighten-3' : undefined" > @@ -258,6 +280,8 @@ const toggleDokterSelection = (dokterId: number) => { variant="outlined" rows="3" hide-details="auto" + :readonly="readonly" + :bg-color="readonly ? 'grey-lighten-3' : undefined" > @@ -357,7 +381,7 @@ const toggleDokterSelection = (dokterId: number) => { :disabled="selectedDokters.length === 0" > mdi-check - Save ({{ selectedDokters.length }}) + Simpan ({{ selectedDokters.length }}) diff --git a/components/pendaftaran/StatusPasienOperasi.vue b/components/pendaftaran/StatusPasienOperasi.vue index dc917c1..8fe1860 100644 --- a/components/pendaftaran/StatusPasienOperasi.vue +++ b/components/pendaftaran/StatusPasienOperasi.vue @@ -1,4 +1,12 @@ @@ -64,6 +81,28 @@ const itemsPerPageLocal = ref(props.itemsPerPage); + + + + + + + {{ action.icon }} + + {{ action.tooltip }} + + + + + diff --git a/data/mock/hakAkses.json b/data/mock/hakAkses.json new file mode 100644 index 0000000..c4f77c3 --- /dev/null +++ b/data/mock/hakAkses.json @@ -0,0 +1,32 @@ +[ + { + "id": 1, + "namaHakAkses": "Super Admin", + "jumlahHalaman": 15, + "status": "aktif" + }, + { + "id": 2, + "namaHakAkses": "Admin Operasi", + "jumlahHalaman": 8, + "status": "aktif" + }, + { + "id": 3, + "namaHakAkses": "Dokter", + "jumlahHalaman": 5, + "status": "aktif" + }, + { + "id": 4, + "namaHakAkses": "Perawat", + "jumlahHalaman": 4, + "status": "aktif" + }, + { + "id": 5, + "namaHakAkses": "Admin Rekam Medis", + "jumlahHalaman": 6, + "status": "tidak aktif" + } +] diff --git a/data/mock/users.json b/data/mock/users.json new file mode 100644 index 0000000..303f0a4 --- /dev/null +++ b/data/mock/users.json @@ -0,0 +1,42 @@ +[ + { + "id": 1, + "namaUser": "Dr. John Doe", + "username": "john.doe", + "email": "john.doe@hospital.com", + "hakAkses": "Dokter", + "status": "aktif" + }, + { + "id": 2, + "namaUser": "Admin Sistem", + "username": "admin", + "email": "admin@hospital.com", + "hakAkses": "Super Admin", + "status": "aktif" + }, + { + "id": 3, + "namaUser": "Perawat Siti", + "username": "siti.perawat", + "email": "siti@hospital.com", + "hakAkses": "Perawat", + "status": "aktif" + }, + { + "id": 4, + "namaUser": "Admin Operasi 1", + "username": "admin.op1", + "email": "adminop1@hospital.com", + "hakAkses": "Admin Operasi", + "status": "aktif" + }, + { + "id": 5, + "namaUser": "RM Staff", + "username": "rm.staff", + "email": "rm@hospital.com", + "hakAkses": "Admin Rekam Medis", + "status": "tidak aktif" + } +] diff --git a/pages/antrean/all.vue b/pages/antrean/all.vue index 1fa06de..4d0be87 100644 --- a/pages/antrean/all.vue +++ b/pages/antrean/all.vue @@ -2,6 +2,7 @@ import BaseBreadcrumb from '@/components/shared/BaseBreadcrumb.vue'; import TableAntrian from '@/components/pendaftaran/TableAntrian.vue'; import antreanOperasiData from '~/data/mock/antreanOperasi.json'; +import { Title } from '#components'; interface AntreanOperasi { id: number; @@ -29,6 +30,19 @@ const breadcrumbs = ref([ const search = ref(''); const antreanList = ref(antreanOperasiData); +const router = useRouter(); + +// Snackbar state +const snackbar = ref(false); +const snackbarMessage = ref(''); +const snackbarColor = ref('success'); + +const showSnackbar = (message: string, color: string = 'success') => { + snackbarMessage.value = message; + snackbarColor.value = color; + snackbar.value = true; +}; + const headers = [ { title: 'No Urut', key: 'no', width: '180px', align: 'center' as const }, { title: 'No Urut Kategori', key: 'no', width: '180px', align: 'center' as const }, @@ -38,8 +52,43 @@ const headers = [ { title: 'Nama Pasien', key: 'namaPasien', sortable: true }, { title: 'No Ktp', key: 'noKtp', sortable: true }, { title: 'No Rekam Medis', key: 'noRekamMedis', sortable: true, width: '250px' }, - { title: 'Status', key: 'status', sortable: true, width: '150px' } + { title: 'Status', key: 'status', sortable: true, width: '150px' }, + { title: 'Actions', key: 'actions', sortable: false } ]; + +const actions = [ + { icon: 'mdi-eye', color: 'info', tooltip: 'View', event: 'view' }, + { icon: 'mdi-pencil', color: 'primary', tooltip: 'Edit', event: 'edit' }, + { icon: 'mdi-delete', color: 'error', tooltip: 'Delete', event: 'delete' } +]; + +const handleView = (item: unknown) => { + const data = item as AntreanOperasi; + router.push({ + path: '/antrean/pendaftaran', + query: { + mode: 'view', + id: data.id + } + }); +}; + +const handleEdit = (item: unknown) => { + const data = item as AntreanOperasi; + router.push({ + path: '/antrean/pendaftaran', + query: { + mode: 'edit', + id: data.id + } + }); +}; + +const handleDelete = (item: unknown) => { + if(confirm('Apakah Anda yakin ingin menghapus data ini?')) { + showSnackbar('Data berhasil dihapus.', 'success'); + } +}; @@ -73,7 +122,11 @@ const headers = [ :headers="headers" :items="antreanList" :search="search" - min-width="1400px" + :actions="actions" + min-width="1500px" + @view="handleView" + @edit="handleEdit" + @delete="handleDelete" > {{ index + 1 }} @@ -83,4 +136,22 @@ const headers = [ + + + + {{ snackbarMessage }} + + + Close + + + \ No newline at end of file diff --git a/pages/antrean/pendaftaran.vue b/pages/antrean/pendaftaran.vue index 55b97e2..f1978a7 100644 --- a/pages/antrean/pendaftaran.vue +++ b/pages/antrean/pendaftaran.vue @@ -28,15 +28,51 @@ const { const form = ref(); const valid = ref(true); -const page = ref({ title: 'Pendaftaran Antrean Operasi' }); -const breadcrumbs = ref([ +// Detect mode from route query +type PageMode = 'create' | 'edit' | 'view'; +const mode = computed(() => { + const modeParam = route.query.mode as string; + if (modeParam === 'edit') return 'edit'; + if (modeParam === 'view') return 'view'; + return 'create'; +}); + +// Computed readonly state +const isReadonly = computed(() => mode.value === 'view'); + +// Dynamic page title based on mode +const pageTitle = computed(() => { + switch (mode.value) { + case 'edit': + return 'Edit Pendaftaran Antrean Operasi'; + case 'view': + return 'Detail Pendaftaran Antrean Operasi'; + default: + return 'Tambah Pendaftaran Antrean Operasi'; + } +}); + +// Dynamic breadcrumbs based on mode +const breadcrumbText = computed(() => { + switch (mode.value) { + case 'edit': + return 'Edit Pendaftaran'; + case 'view': + return 'Detail Pendaftaran'; + default: + return 'Tambah Pendaftaran'; + } +}); + +const page = ref({ title: pageTitle }); +const breadcrumbs = computed(() => [ { text: 'Antrean', - disabled: true, - href: '#' + disabled: false, + href: '/antrean/all' }, { - text: 'Pendaftaran', + text: breadcrumbText.value, disabled: true, href: '#' } @@ -106,12 +142,12 @@ const handleKembali = () => { - + - + @@ -119,6 +155,7 @@ const handleKembali = () => { @@ -127,12 +164,13 @@ const handleKembali = () => { - + @@ -144,23 +182,28 @@ const handleKembali = () => { color="default" size="large" variant="outlined" + prepend-icon="mdi-arrow-left" @click="handleKembali" > Kembali Reset Simpan diff --git a/pages/setting/hak-akses/form.vue b/pages/setting/hak-akses/form.vue new file mode 100644 index 0000000..4f4b57b --- /dev/null +++ b/pages/setting/hak-akses/form.vue @@ -0,0 +1,339 @@ + + + + + + + + + + + + + + Informasi Hak Akses + + + + + + + Nama Hak Akses * + + + + + + Status * + + + + {{ status === 'aktif' ? 'Aktif' : 'Tidak Aktif' }} + + + + + + + + + + + + + + Akses Halaman + + + + + + + + + + + {{ section.header }} + + + + + + + + + + + + + + + + + + + + {{ selectedPages.length }} halaman dipilih + + + + + + + + + + + + + + + Kembali + + + Reset + + + Simpan + + + + + + + + \ No newline at end of file diff --git a/pages/setting/hak-akses/index.vue b/pages/setting/hak-akses/index.vue new file mode 100644 index 0000000..d395ed4 --- /dev/null +++ b/pages/setting/hak-akses/index.vue @@ -0,0 +1,160 @@ + + + + + + + + + + + + + + Tambah Hak Akses + + + + + + {{ index + 1 }} + + + + {{ item.status }} + + + + + + + + + + + {{ snackbarMessage }} + + + Close + + + + \ No newline at end of file diff --git a/pages/setting/user/form.vue b/pages/setting/user/form.vue new file mode 100644 index 0000000..6c32f96 --- /dev/null +++ b/pages/setting/user/form.vue @@ -0,0 +1,283 @@ + + + + + + + + + + + + + + Informasi User + + + + + + + Nama User * + + + + + + Username * + + + + + + Email * + + + + + + Hak Akses * + + + + + + Status * + + + + {{ status === 'aktif' ? 'Aktif' : 'Tidak Aktif' }} + + + + + + + + + + + + + + + + Kembali + + + Reset + + + Simpan + + + + + + + + \ No newline at end of file diff --git a/pages/setting/user/index.vue b/pages/setting/user/index.vue new file mode 100644 index 0000000..95d1e4d --- /dev/null +++ b/pages/setting/user/index.vue @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + Tambah User + + + + + + {{ index + 1 }} + + + + {{ item.status }} + + + + + + + + + + + {{ snackbarMessage }} + + + Close + + + + \ No newline at end of file