diff --git a/components/layout/full/vertical-sidebar/sidebarItem.ts b/components/layout/full/vertical-sidebar/sidebarItem.ts index fa8c080..9f651cd 100644 --- a/components/layout/full/vertical-sidebar/sidebarItem.ts +++ b/components/layout/full/vertical-sidebar/sidebarItem.ts @@ -37,12 +37,33 @@ const sidebarItem: menu[] = [ icon: 'cart-3-line-duotone', to: '/antrean/all', }, + { + title: 'Kategori', + icon: 'layers-line-duotone', + to: '/antrean/list-kategori' + }, { title: 'Spesialis', icon: 'widget-4-line-duotone', to: '/antrean/list-spesialis' } ] + }, + { + header: 'pengaturan', + id: 1, + children: [ + { + title: 'Hak Akses', + icon: 'settings-line-duotone', + to: '/setting/hak-akses', + }, + { + title: 'User', + icon: 'user-line-duotone', + to: '/setting/user' + } + ] } ]; diff --git a/components/pendaftaran/BiodataPasien.vue b/components/pendaftaran/BiodataPasien.vue index 169d7e9..87f74e6 100644 --- a/components/pendaftaran/BiodataPasien.vue +++ b/components/pendaftaran/BiodataPasien.vue @@ -14,10 +14,25 @@ const rules = { required: (value: string) => !!value || 'Field ini wajib diisi' }; +// Phone validation rules +const phoneLength = (value: string) => { + if (!value) return true; + // Hapus karakter non-angka sebelum menghitung panjang + const length = value.replace(/[^0-9]/g, '').length; + return (length >= 9 && length <= 15) || 'Nomor telepon harus antara 9 hingga 15 digit.'; +}; + +const indonesianPhoneFormat = (value: string) => { + if (!value) return true; + // Pola: Harus dimulai dengan '08', diikuti 7 hingga 13 digit angka + return /^08[0-9]{7,13}$/.test(value) || 'Format nomor telepon tidak valid (Contoh: 08xxxxxxxx).'; +}; + // Modal state const showModal = ref(false); const newPhoneNumber = ref(''); const editingIndex = ref(null); +const phoneError = ref(true); // Initialize nomorTelepon as array if not already if (!Array.isArray(formData.value.nomorTelepon)) { @@ -27,18 +42,19 @@ if (!Array.isArray(formData.value.nomorTelepon)) { const openAddModal = () => { newPhoneNumber.value = ''; editingIndex.value = null; + phoneError.value = true; showModal.value = true; }; const editPhoneNumber = (index: number) => { const phone = formData.value.nomorTelepon[index]; - // Remove +62 prefix for editing - newPhoneNumber.value = phone.startsWith('+62') ? phone.substring(3) : phone; + newPhoneNumber.value = phone; editingIndex.value = index; + phoneError.value = true; showModal.value = true; }; -// Handle only numeric input +// Handle only numeric input and validate const handlePhoneInput = (event: Event) => { const input = event.target as HTMLInputElement; const value = input.value; @@ -46,22 +62,42 @@ const handlePhoneInput = (event: Event) => { // Only allow numbers const numericValue = value.replace(/\D/g, ''); newPhoneNumber.value = numericValue; + + // Validate format and length + const lengthValidation = phoneLength(numericValue); + const formatValidation = indonesianPhoneFormat(numericValue); + + if (lengthValidation !== true) { + phoneError.value = lengthValidation; + } else if (formatValidation !== true) { + phoneError.value = formatValidation; + } else { + phoneError.value = true; + } }; const savePhoneNumber = () => { if (!newPhoneNumber.value.trim()) return; - const fullPhoneNumber = `+62${newPhoneNumber.value}`; + // Validate before saving + const lengthValidation = phoneLength(newPhoneNumber.value); + const formatValidation = indonesianPhoneFormat(newPhoneNumber.value); + if (lengthValidation !== true || formatValidation !== true) { + return; + } + + // Save directly as 08xxx format if (editingIndex.value !== null) { - formData.value.nomorTelepon[editingIndex.value] = fullPhoneNumber; + formData.value.nomorTelepon[editingIndex.value] = newPhoneNumber.value; } else { - formData.value.nomorTelepon.push(fullPhoneNumber); + formData.value.nomorTelepon.push(newPhoneNumber.value); } showModal.value = false; newPhoneNumber.value = ''; editingIndex.value = null; + phoneError.value = true; }; const deletePhoneNumber = (index: number) => { @@ -85,6 +121,7 @@ const deletePhoneNumber = (index: number) => { v-model="formData.noRekamMedis" placeholder="Masukan Nomor RM / Nama Pasien" variant="outlined" + maxlength="8" density="comfortable" :rules="[rules.required]" hide-details="auto" @@ -217,17 +254,17 @@ const deletePhoneNumber = (index: number) => { Nomor Telepon - +
+ Format: 08xxxxxxxxx (9-15 digit) +
@@ -237,7 +274,7 @@ const deletePhoneNumber = (index: number) => { color="primary" variant="flat" @click="savePhoneNumber" - :disabled="!newPhoneNumber.trim()" + :disabled="!newPhoneNumber.trim() || phoneError !== true" > mdi-check Save diff --git a/components/pendaftaran/TableAntrian.vue b/components/pendaftaran/TableAntrian.vue new file mode 100644 index 0000000..273e407 --- /dev/null +++ b/components/pendaftaran/TableAntrian.vue @@ -0,0 +1,80 @@ + + + + + diff --git a/components/shared/BaseBreadcrumb.vue b/components/shared/BaseBreadcrumb.vue index 1f4d066..6f2d684 100644 --- a/components/shared/BaseBreadcrumb.vue +++ b/components/shared/BaseBreadcrumb.vue @@ -1,19 +1,36 @@ \ No newline at end of file diff --git a/pages/antrean/kategori/[id].vue b/pages/antrean/kategori/[id].vue new file mode 100644 index 0000000..46d1218 --- /dev/null +++ b/pages/antrean/kategori/[id].vue @@ -0,0 +1,122 @@ + + diff --git a/pages/antrean/list-kategori.vue b/pages/antrean/list-kategori.vue new file mode 100644 index 0000000..647b7a5 --- /dev/null +++ b/pages/antrean/list-kategori.vue @@ -0,0 +1,70 @@ + + \ No newline at end of file diff --git a/pages/antrean/list-spesialis.vue b/pages/antrean/list-spesialis.vue index e5583c4..d33b372 100644 --- a/pages/antrean/list-spesialis.vue +++ b/pages/antrean/list-spesialis.vue @@ -27,7 +27,7 @@ interface AntreanOperasi { kodeSubSpesialis: string; } -const page = ref({ title: 'List Antrean Operasi Spesialis' }); +const page = ref({ title: 'List Antrean Operasi per Spesialis' }); const breadcrumbs = ref([ { text: 'Antrean', @@ -35,7 +35,7 @@ const breadcrumbs = ref([ href: '#' }, { - text: 'List Antrean Operasi Spesialis', + text: 'List Antrean Operasi per Spesialis', disabled: true, href: '#' } diff --git a/pages/antrean/pendaftaran.vue b/pages/antrean/pendaftaran.vue index 1c4d24e..55b97e2 100644 --- a/pages/antrean/pendaftaran.vue +++ b/pages/antrean/pendaftaran.vue @@ -44,6 +44,19 @@ const breadcrumbs = ref([ // Auto-select spesialis dan sub spesialis dari query parameter onMounted(async () => { + // Reset form terlebih dahulu + pendaftaranStore.resetForm(); + + // Set default tanggal daftar ke now + const now = new Date(); + const year = now.getFullYear(); + const month = String(now.getMonth() + 1).padStart(2, '0'); + const day = String(now.getDate()).padStart(2, '0'); + const hours = String(now.getHours()).padStart(2, '0'); + const minutes = String(now.getMinutes()).padStart(2, '0'); + pendaftaranStore.rencanaOperasiData.tanggalDaftar = `${year}-${month}-${day}T${hours}:${minutes}`; + + // Auto-select spesialis dan sub spesialis jika ada query parameter const kodeSpesialis = route.query.kodeSpesialis as string; const kodeSubSpesialis = route.query.kodeSubSpesialis as string; diff --git a/pages/antrean/spesialis/[kode].vue b/pages/antrean/spesialis/[kode].vue index 2bee623..7d26d07 100644 --- a/pages/antrean/spesialis/[kode].vue +++ b/pages/antrean/spesialis/[kode].vue @@ -1,5 +1,6 @@