fix(FE) : fix review style
This commit is contained in:
No files matched your search
@@ -2,6 +2,7 @@
|
||||
import api from '@/services/api';
|
||||
import type { Props } from '~/types/common';
|
||||
import type { PatientData } from '~/types/pendaftaran';
|
||||
import { Icon } from '@iconify/vue';
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
readonly: false
|
||||
@@ -36,7 +37,7 @@ const searchPatients = async (search: string) => {
|
||||
}
|
||||
|
||||
loadingPatients.value = true;
|
||||
|
||||
|
||||
try {
|
||||
const response = await api.get('/reference/pasien', {
|
||||
params: {
|
||||
@@ -58,7 +59,7 @@ const searchPatients = async (search: string) => {
|
||||
|
||||
// Handle search input with debounce
|
||||
const handleSearchInput = (value: string) => {
|
||||
if(value === formData.value.noRekamMedis) {
|
||||
if (value === formData.value.noRekamMedis) {
|
||||
patientItems.value = selectedPatient.value ? [selectedPatient.value] : [];
|
||||
return;
|
||||
}
|
||||
@@ -88,9 +89,9 @@ const handlePatientSelect = (patient: PatientData | null) => {
|
||||
// Fetch patient by RM number (for edit mode)
|
||||
const fetchPatientByRm = async (rm: string) => {
|
||||
if (!rm) return;
|
||||
|
||||
|
||||
loadingPatients.value = true;
|
||||
|
||||
|
||||
try {
|
||||
const response = await api.get('/reference/pasien', {
|
||||
params: {
|
||||
@@ -117,15 +118,15 @@ const fetchPatientByRm = async (rm: string) => {
|
||||
watchEffect(async () => {
|
||||
const rm = formData.value.noRekamMedis;
|
||||
const nama = formData.value.namaPasien;
|
||||
|
||||
|
||||
// Use nextTick to ensure all reactive updates are complete
|
||||
await nextTick();
|
||||
|
||||
|
||||
// If both RM and Nama are populated but selectedPatient is not, fetch patient details
|
||||
if (rm && nama && !selectedPatient.value) {
|
||||
await fetchPatientByRm(rm);
|
||||
}
|
||||
|
||||
|
||||
// Clear selectedPatient if RM is cleared
|
||||
if (!rm && selectedPatient.value) {
|
||||
selectedPatient.value = null;
|
||||
@@ -160,15 +161,15 @@ if (!Array.isArray(formData.value.nomorTelepon)) {
|
||||
const handlePhoneInput = (event: Event) => {
|
||||
const input = event.target as HTMLInputElement;
|
||||
const value = input.value;
|
||||
|
||||
|
||||
// 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) {
|
||||
@@ -180,18 +181,18 @@ const handlePhoneInput = (event: Event) => {
|
||||
|
||||
const addPhoneNumber = () => {
|
||||
if (!newPhoneNumber.value.trim()) return;
|
||||
|
||||
|
||||
// Validate before saving
|
||||
const lengthValidation = phoneLength(newPhoneNumber.value);
|
||||
const formatValidation = indonesianPhoneFormat(newPhoneNumber.value);
|
||||
|
||||
|
||||
if (lengthValidation !== true || formatValidation !== true) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Add to list
|
||||
formData.value.nomorTelepon.push(newPhoneNumber.value);
|
||||
|
||||
|
||||
// Reset input
|
||||
newPhoneNumber.value = '';
|
||||
phoneError.value = true;
|
||||
@@ -200,73 +201,77 @@ const addPhoneNumber = () => {
|
||||
const deletePhoneNumber = (index: number) => {
|
||||
formData.value.nomorTelepon.splice(index, 1);
|
||||
};
|
||||
|
||||
// Ref for no rekam medis input
|
||||
const noRekamMedisInput = ref();
|
||||
|
||||
// Expose method to focus on no rekam medis
|
||||
const focusNoRekamMedis = () => {
|
||||
if (noRekamMedisInput.value) {
|
||||
noRekamMedisInput.value.focus();
|
||||
}
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
focusNoRekamMedis
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-card elevation="10">
|
||||
|
||||
<v-card-text class="pa-5">
|
||||
<div class="d-flex align-center">
|
||||
<!-- <Icon icon="solar:user-bold-duotone" height="24" class="mr-2" /> -->
|
||||
<span class="text-h5">Biodata Pasien</span>
|
||||
</div>
|
||||
</v-card-text>
|
||||
<v-divider> </v-divider>
|
||||
<v-card-text>
|
||||
<v-row>
|
||||
<!-- No Rekam Medis -->
|
||||
<v-col cols="12" md="6" class="">
|
||||
<v-label class="mb-2 font-weight-medium">No Rekam Medis <span
|
||||
class="text-error">*</span></v-label>
|
||||
<v-autocomplete
|
||||
v-model="formData.noRekamMedis"
|
||||
:items="patientItems"
|
||||
item-title="select"
|
||||
item-value="nomr"
|
||||
placeholder="Masukan Nomor RM / Nama Pasien"
|
||||
variant="outlined"
|
||||
density="compact"
|
||||
:rules="[rules.required]"
|
||||
hide-details="auto"
|
||||
max="8"
|
||||
:readonly="readonly"
|
||||
:disabled="readonly"
|
||||
:bg-color="readonly ? 'grey-lighten-3' : undefined"
|
||||
:loading="loadingPatients"
|
||||
no-filter
|
||||
clearable
|
||||
@update:search="handleSearchInput"
|
||||
<v-col cols="12" md="12" class="">
|
||||
<v-label class="mb-2">No Rekam Medis <span class="text-error">*</span></v-label>
|
||||
<v-autocomplete ref="noRekamMedisInput" v-model="formData.noRekamMedis" :items="patientItems"
|
||||
item-title="select" item-value="nomr" placeholder="Masukan Nomor RM / Nama Pasien"
|
||||
variant="outlined" density="compact" :rules="[rules.required]" hide-details="auto" max="8"
|
||||
:readonly="readonly" :disabled="readonly" :bg-color="readonly ? 'grey-lighten-3' : undefined"
|
||||
:loading="loadingPatients" no-filter clearable @update:search="handleSearchInput"
|
||||
@update:model-value="(value: string) => {
|
||||
const patient = patientItems.find(p => p.nomr === value);
|
||||
handlePatientSelect(patient || null);
|
||||
}"
|
||||
>
|
||||
}">
|
||||
<template #no-data>
|
||||
<v-list-item>
|
||||
<v-list-item-title>
|
||||
Cari No RM atau Nama Pasien
|
||||
Cari No RM atau Nama Pasien
|
||||
</v-list-item-title>
|
||||
</v-list-item>
|
||||
</template>
|
||||
</v-autocomplete>
|
||||
</v-col>
|
||||
|
||||
<v-col cols="12" md="6">
|
||||
</v-col>
|
||||
|
||||
<template v-if="formData.noRekamMedis && selectedPatient">
|
||||
<!-- No KTP -->
|
||||
<v-col cols="12" md="6">
|
||||
<v-label class="mb-2 font-weight-medium">No Ktp</v-label>
|
||||
<v-text-field v-model="formData.noKtp" variant="outlined" density="compact"
|
||||
hide-details="auto" readonly style="background-color: #f5f5f5; border-radius: 4px;"></v-text-field>
|
||||
<v-text-field v-model="formData.noKtp" variant="outlined" density="compact" hide-details="auto"
|
||||
readonly style="background-color: #f5f5f5; border-radius: 4px;"></v-text-field>
|
||||
</v-col>
|
||||
|
||||
<!-- Nama Pasien -->
|
||||
<v-col cols="12" md="6">
|
||||
<v-label class="mb-2 font-weight-medium">Nama Pasien</v-label>
|
||||
<v-text-field v-model="formData.namaPasien" variant="outlined" density="compact"
|
||||
hide-details="auto" readonly style="background-color: #f5f5f5; border-radius: 4px;"></v-text-field>
|
||||
hide-details="auto" readonly
|
||||
style="background-color: #f5f5f5; border-radius: 4px;"></v-text-field>
|
||||
</v-col>
|
||||
|
||||
<!-- Jenis Kelamin -->
|
||||
<v-col cols="12" md="6">
|
||||
<v-label class="mb-2 font-weight-medium">Jenis Kelamin</v-label>
|
||||
<v-text-field :model-value="formData.jenisKelamin === 'L' ? 'Laki-laki' : 'Perempuan'" variant="outlined" density="compact"
|
||||
hide-details="auto" readonly style="background-color: #f5f5f5; border-radius: 4px;"></v-text-field>
|
||||
<v-text-field :model-value="formData.jenisKelamin === 'L' ? 'Laki-laki' : 'Perempuan'"
|
||||
variant="outlined" density="compact" hide-details="auto" readonly
|
||||
style="background-color: #f5f5f5; border-radius: 4px;"></v-text-field>
|
||||
<!-- <v-btn-group
|
||||
v-model="formData.jenisKelamin"
|
||||
divided
|
||||
@@ -300,8 +305,8 @@ const deletePhoneNumber = (index: number) => {
|
||||
<!-- Tanggal Lahir -->
|
||||
<v-col cols="12" md="6">
|
||||
<v-label class="mb-2 font-weight-medium">Tanggal Lahir</v-label>
|
||||
<v-text-field v-model="formData.tanggalLahir" type="date" variant="outlined"
|
||||
density="compact" hide-details="auto" readonly
|
||||
<v-text-field v-model="formData.tanggalLahir" type="date" variant="outlined" density="compact"
|
||||
hide-details="auto" readonly
|
||||
style="background-color: #f5f5f5; border-radius: 4px;"></v-text-field>
|
||||
</v-col>
|
||||
|
||||
@@ -315,84 +320,57 @@ const deletePhoneNumber = (index: number) => {
|
||||
<!-- Alamat -->
|
||||
<v-col cols="12">
|
||||
<v-label class="mb-2 font-weight-medium">Alamat</v-label>
|
||||
<v-textarea v-model="formData.alamat" variant="outlined" rows="3" hide-details="auto"
|
||||
readonly style="background-color: #f5f5f5; border-radius: 4px;"></v-textarea>
|
||||
<v-textarea v-model="formData.alamat" variant="outlined" rows="3" hide-details="auto" readonly
|
||||
style="background-color: #f5f5f5; border-radius: 4px;"></v-textarea>
|
||||
</v-col>
|
||||
|
||||
<!-- Nomor Telepon -->
|
||||
<v-col cols="12">
|
||||
<v-label class="mb-2 font-weight-medium">Nomor Telepon</v-label>
|
||||
|
||||
<!-- Input field for adding phone number -->
|
||||
<div v-if="!readonly" class="mb-3">
|
||||
<div class="d-flex gap-2">
|
||||
<v-text-field
|
||||
v-model="newPhoneNumber"
|
||||
placeholder="Contoh: 08123456789"
|
||||
variant="outlined"
|
||||
density="compact"
|
||||
type="tel"
|
||||
hide-details="auto"
|
||||
@input="handlePhoneInput"
|
||||
@keyup.enter="addPhoneNumber"
|
||||
:error-messages="phoneError !== true && newPhoneNumber ? [phoneError as string] : []"
|
||||
class="flex-1-1"
|
||||
>
|
||||
</v-text-field>
|
||||
<v-btn
|
||||
color="primary"
|
||||
variant="flat"
|
||||
size="large"
|
||||
@click="addPhoneNumber"
|
||||
:disabled="!newPhoneNumber.trim() || phoneError !== true"
|
||||
>
|
||||
<v-icon>mdi-check</v-icon>
|
||||
</v-btn>
|
||||
</div>
|
||||
<div class="text-caption text-medium-emphasis mt-2">
|
||||
Format: 08xxxxxxxxx (9-15 digit)
|
||||
</div>
|
||||
</div>
|
||||
<v-label class="mb-2 font-weight-medium">Nomor Telepon</v-label>
|
||||
|
||||
<!-- Alert when no phone numbers -->
|
||||
<v-alert
|
||||
v-if="formData.nomorTelepon.length === 0"
|
||||
type="info"
|
||||
variant="tonal"
|
||||
class="mb-3"
|
||||
density="compact"
|
||||
>
|
||||
<div class="d-flex align-center">
|
||||
<span>Tidak ada nomor telepon</span>
|
||||
<!-- Input field for adding phone number -->
|
||||
<div v-if="!readonly" class="mb-3">
|
||||
<div class="d-flex gap-2">
|
||||
<v-text-field v-model="newPhoneNumber" placeholder="Contoh: 08123456789"
|
||||
variant="outlined" density="compact" type="tel" hide-details="auto"
|
||||
@input="handlePhoneInput" @keyup.enter="addPhoneNumber"
|
||||
:error-messages="phoneError !== true && newPhoneNumber ? [phoneError as string] : []"
|
||||
class="flex-1-1">
|
||||
</v-text-field>
|
||||
<v-btn color="primary" variant="flat" size="large" @click="addPhoneNumber"
|
||||
:disabled="!newPhoneNumber.trim() || phoneError !== true">
|
||||
<v-icon>mdi-check</v-icon>
|
||||
</v-btn>
|
||||
</div>
|
||||
<div class="text-caption text-medium-emphasis mt-2">
|
||||
Format: 08xxxxxxxxx (9-15 digit)
|
||||
</div>
|
||||
</div>
|
||||
</v-alert>
|
||||
|
||||
<!-- List of phone numbers -->
|
||||
<v-list v-if="formData.nomorTelepon.length > 0" density="compact">
|
||||
<v-list-item
|
||||
v-for="(phone, index) in formData.nomorTelepon"
|
||||
:key="index"
|
||||
class="px-4 mb-2"
|
||||
border
|
||||
>
|
||||
<template #default>
|
||||
<div class="d-flex align-center justify-space-between w-100">
|
||||
<span>{{ phone }}</span>
|
||||
<v-btn
|
||||
v-if="!readonly"
|
||||
icon
|
||||
size="small"
|
||||
variant="text"
|
||||
color="error"
|
||||
@click="deletePhoneNumber(index)"
|
||||
>
|
||||
<v-icon>mdi-delete</v-icon>
|
||||
</v-btn>
|
||||
</div>
|
||||
</template>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-col>
|
||||
<!-- Alert when no phone numbers -->
|
||||
<v-alert v-if="formData.nomorTelepon.length === 0" type="info" variant="tonal" class="mb-3"
|
||||
density="compact">
|
||||
<div class="d-flex align-center">
|
||||
<span>Tidak ada nomor telepon</span>
|
||||
</div>
|
||||
</v-alert>
|
||||
|
||||
<!-- List of phone numbers -->
|
||||
<v-list v-if="formData.nomorTelepon.length > 0" density="compact">
|
||||
<v-list-item v-for="(phone, index) in formData.nomorTelepon" :key="index" class="px-4 mb-2"
|
||||
border>
|
||||
<template #default>
|
||||
<div class="d-flex align-center justify-space-between w-100">
|
||||
<span>{{ phone }}</span>
|
||||
<v-btn v-if="!readonly" icon size="small" variant="text" color="error"
|
||||
@click="deletePhoneNumber(index)">
|
||||
<v-icon>mdi-delete</v-icon>
|
||||
</v-btn>
|
||||
</div>
|
||||
</template>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-col>
|
||||
</template>
|
||||
</v-row>
|
||||
</v-card-text>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import api from '@/services/api';
|
||||
import type { Props } from '~/types/common';
|
||||
import type { DiagnosisItem, TindakanItem, DiagnosisApiData, TindakanApiData } from '~/types/pendaftaran';
|
||||
import { Icon } from '@iconify/vue';
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
readonly: false
|
||||
@@ -239,67 +240,95 @@ const handleKodeTindakanChange = (kode: string) => {
|
||||
tindakanForm.value.tindakan = found.keterangan;
|
||||
}
|
||||
};
|
||||
|
||||
// Refs for focus functionality
|
||||
const diagnosisSection = ref();
|
||||
const tindakanSection = ref();
|
||||
const diagnosisInput = ref();
|
||||
const tindakanInput = ref();
|
||||
|
||||
// Expose methods to focus on fields
|
||||
const focusDiagnosis = () => {
|
||||
if (diagnosisSection.value) {
|
||||
diagnosisSection.value.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||
setTimeout(() => {
|
||||
if (diagnosisInput.value) {
|
||||
diagnosisInput.value.focus();
|
||||
}
|
||||
}, 300);
|
||||
}
|
||||
};
|
||||
|
||||
const focusTindakan = () => {
|
||||
if (tindakanSection.value) {
|
||||
tindakanSection.value.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||
setTimeout(() => {
|
||||
if (tindakanInput.value) {
|
||||
tindakanInput.value.focus();
|
||||
}
|
||||
}, 300);
|
||||
}
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
focusDiagnosis,
|
||||
focusTindakan
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-card elevation="10">
|
||||
<v-divider></v-divider>
|
||||
<v-card-item>
|
||||
<h5 class="text-h5 font-weight-bold">Data Medis Pasien</h5>
|
||||
</v-card-item>
|
||||
<v-card-text class="pa-5">
|
||||
<div class="d-flex align-center">
|
||||
<!-- <Icon icon="solar:medical-kit-bold-duotone" height="24" class="mr-2" /> -->
|
||||
<span class="text-h5">Data Medis Pasien</span>
|
||||
</div>
|
||||
</v-card-text>
|
||||
<v-divider> </v-divider>
|
||||
<v-card-text>
|
||||
<!-- Diagnosa -->
|
||||
<div class="mb-6">
|
||||
<h6 class="text-h6 font-weight-medium mb-3">Diagnosa</h6>
|
||||
<div ref="diagnosisSection" class="mb-6">
|
||||
|
||||
<!-- Form Input Diagnosa -->
|
||||
<v-card v-if="!readonly" variant="outlined" class="mb-4 pa-4" color="blue-lighten-5">
|
||||
<h6 class="text-h6 font-weight-bold mb-6">Diagnosa</h6>
|
||||
<v-row>
|
||||
|
||||
<!-- Jenis Diagnosa -->
|
||||
<v-col cols="12" md="3">
|
||||
<v-col cols="12" md="6">
|
||||
<v-label class="mb-2 font-weight-medium text-caption">
|
||||
Jenis Diagnosa <span class="text-error">*</span>
|
||||
</v-label>
|
||||
<v-select
|
||||
v-model="diagnosisForm.jenisDiagnosa"
|
||||
:items="['utama', 'tambahan']"
|
||||
variant="outlined"
|
||||
density="compact"
|
||||
hide-details="auto"
|
||||
></v-select>
|
||||
<!-- <v-btn-group
|
||||
v-model="diagnosisForm.jenisDiagnosa"
|
||||
variant="outlined"
|
||||
density="compact"
|
||||
>
|
||||
<div class="d-flex ga-2">
|
||||
<v-btn
|
||||
:color="diagnosisForm.jenisDiagnosa === 'utama' ? 'primary' : 'light'"
|
||||
variant="flat"
|
||||
size="small"
|
||||
:color="diagnosisForm.jenisDiagnosa === 'utama' ? 'primary' : 'default'"
|
||||
:variant="diagnosisForm.jenisDiagnosa === 'utama' ? 'flat' : 'outlined'"
|
||||
size="large"
|
||||
class="flex-grow-1 text-none"
|
||||
@click="diagnosisForm.jenisDiagnosa = 'utama'"
|
||||
:value="'utama'"
|
||||
:prepend-icon="diagnosisForm.jenisDiagnosa === 'utama' ? 'mdi-radiobox-marked' : 'mdi-radiobox-blank'"
|
||||
>
|
||||
Diagnosa Utama
|
||||
Diagnosa utama
|
||||
</v-btn>
|
||||
<v-btn
|
||||
:color="diagnosisForm.jenisDiagnosa === 'tambahan' ? 'primary' : 'light'"
|
||||
variant="flat"
|
||||
size="small"
|
||||
:color="diagnosisForm.jenisDiagnosa === 'tambahan' ? 'primary' : 'default'"
|
||||
:variant="diagnosisForm.jenisDiagnosa === 'tambahan' ? 'flat' : 'outlined'"
|
||||
size="large"
|
||||
class="flex-grow-1 text-none"
|
||||
@click="diagnosisForm.jenisDiagnosa = 'tambahan'"
|
||||
:value="'tambahan'"
|
||||
:prepend-icon="diagnosisForm.jenisDiagnosa === 'tambahan' ? 'mdi-radiobox-marked' : 'mdi-radiobox-blank'"
|
||||
>
|
||||
Diagnosa Tambahan
|
||||
Diagnosa tambahan
|
||||
</v-btn>
|
||||
</v-btn-group> -->
|
||||
</div>
|
||||
</v-col>
|
||||
|
||||
<!-- Kode Diagnosa -->
|
||||
<v-col cols="12" md="4">
|
||||
<v-col cols="12" md="6">
|
||||
<v-label class="mb-2 font-weight-medium text-caption">
|
||||
Kode Diagnosa <span class="text-error">*</span>
|
||||
</v-label>
|
||||
<v-autocomplete
|
||||
ref="diagnosisInput"
|
||||
v-model="diagnosisForm.kodeDiagnosa"
|
||||
:items="diagnosisOptions"
|
||||
placeholder="Ketik min. 3 karakter..."
|
||||
@@ -324,7 +353,7 @@ const handleKodeTindakanChange = (kode: string) => {
|
||||
</v-col>
|
||||
|
||||
<!-- Diagnosa -->
|
||||
<v-col cols="12" md="5">
|
||||
<v-col cols="12" md="12">
|
||||
<v-label class="mb-2 font-weight-medium text-caption">
|
||||
Diagnosa <span class="text-error">*</span>
|
||||
</v-label>
|
||||
@@ -413,7 +442,7 @@ const handleKodeTindakanChange = (kode: string) => {
|
||||
<div class="d-flex ga-1">
|
||||
<v-btn
|
||||
icon
|
||||
size="x-small"
|
||||
size="small"
|
||||
variant="text"
|
||||
color="primary"
|
||||
@click="editDiagnosis(index)"
|
||||
@@ -422,7 +451,7 @@ const handleKodeTindakanChange = (kode: string) => {
|
||||
</v-btn>
|
||||
<v-btn
|
||||
icon
|
||||
size="x-small"
|
||||
size="small"
|
||||
variant="text"
|
||||
color="error"
|
||||
@click="deleteDiagnosis(index)"
|
||||
@@ -438,11 +467,11 @@ const handleKodeTindakanChange = (kode: string) => {
|
||||
</div>
|
||||
|
||||
<!-- Tindakan -->
|
||||
<div>
|
||||
<h6 class="text-h6 font-weight-medium mb-3">Tindakan</h6>
|
||||
<div ref="tindakanSection">
|
||||
|
||||
<!-- Form Input Tindakan -->
|
||||
<v-card v-if="!readonly" variant="outlined" class="mb-4 pa-4" color="purple-lighten-5">
|
||||
<h6 class="text-h6 font-weight-bold mb-6">Tindakan</h6>
|
||||
<v-row>
|
||||
<!-- Kode Tindakan -->
|
||||
<v-col cols="12" md="6">
|
||||
@@ -450,6 +479,7 @@ const handleKodeTindakanChange = (kode: string) => {
|
||||
Kode Tindakan <span class="text-error">*</span>
|
||||
</v-label>
|
||||
<v-autocomplete
|
||||
ref="tindakanInput"
|
||||
v-model="tindakanForm.kodeTindakan"
|
||||
:items="tindakanOptions"
|
||||
placeholder="Ketik min. 3 karakter..."
|
||||
@@ -571,7 +601,7 @@ const handleKodeTindakanChange = (kode: string) => {
|
||||
<div class="d-flex ga-1">
|
||||
<v-btn
|
||||
icon
|
||||
size="x-small"
|
||||
size="small"
|
||||
variant="text"
|
||||
color="primary"
|
||||
@click="editTindakan(index)"
|
||||
@@ -580,7 +610,7 @@ const handleKodeTindakanChange = (kode: string) => {
|
||||
</v-btn>
|
||||
<v-btn
|
||||
icon
|
||||
size="x-small"
|
||||
size="small"
|
||||
variant="text"
|
||||
color="error"
|
||||
@click="deleteTindakan(index)"
|
||||
|
||||
@@ -226,22 +226,21 @@ const closeModal = () => {
|
||||
<template>
|
||||
<v-dialog v-model="showModal" max-width="900px" persistent scrollable>
|
||||
<v-card>
|
||||
<v-card-title class="d-flex align-center justify-space-between pa-4 bg-primary text-white">
|
||||
<v-card-title class="d-flex align-center justify-space-between pa-4">
|
||||
<div class="d-flex align-center">
|
||||
<Icon icon="solar:clipboard-text-bold-duotone" height="28" class="mr-3" />
|
||||
<Icon icon="solar:clipboard-text-bold-duotone" height="28" class="text-primary mr-3" />
|
||||
<span class="text-h6">Detail Pendaftaran Antrean Operasi</span>
|
||||
</div>
|
||||
<v-btn
|
||||
icon
|
||||
variant="text"
|
||||
color="white"
|
||||
@click="closeModal"
|
||||
>
|
||||
<v-icon>mdi-close</v-icon>
|
||||
</v-btn>
|
||||
</v-card-title>
|
||||
|
||||
<v-card-text class="pa-4" style="max-height: 75vh; overflow-y: auto;">
|
||||
<v-card-text class="pa-5 bg-background" style="max-height: 75vh; overflow-y: auto;">
|
||||
<LoadingState
|
||||
:loading="loading"
|
||||
:error="error"
|
||||
@@ -249,7 +248,7 @@ const closeModal = () => {
|
||||
error-text="Gagal memuat data detail"
|
||||
@retry="fetchDetailData"
|
||||
>
|
||||
<!-- Status Badge -->
|
||||
<!-- Status Badge
|
||||
<v-row class="mb-2">
|
||||
<v-col cols="12">
|
||||
<v-chip
|
||||
@@ -262,17 +261,17 @@ const closeModal = () => {
|
||||
Status: {{ getStatusText(statusPasienData.statusOperasi) }}
|
||||
</v-chip>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-row> -->
|
||||
|
||||
<!-- Informasi Pasien -->
|
||||
<v-card elevation="2" class="mb-4">
|
||||
<v-card-title class="bg-blue-lighten-5 pa-3">
|
||||
<v-card elevation="10" class="mb-4">
|
||||
<v-card-title class="bg-blue-lighten-5 pa-4">
|
||||
<div class="d-flex align-center">
|
||||
<Icon icon="solar:user-bold-duotone" height="24" class="mr-2 text-primary" />
|
||||
<span class="text-h6">Informasi Pasien</span>
|
||||
<span class="text-h6">Biodata Pasien</span>
|
||||
</div>
|
||||
</v-card-title>
|
||||
<v-card-text class="pa-4">
|
||||
<v-card-text class="pa-5">
|
||||
<v-row>
|
||||
<v-col cols="12" md="6">
|
||||
<div class="info-item">
|
||||
@@ -280,7 +279,7 @@ const closeModal = () => {
|
||||
<Icon icon="mdi-card-account-details" height="20" class="mr-2" />
|
||||
No Rekam Medis
|
||||
</div>
|
||||
<div class="info-value font-weight-bold text-primary">
|
||||
<div class="info-value font-weight-bold">
|
||||
{{ formData.noRekamMedis || '-' }}
|
||||
</div>
|
||||
</div>
|
||||
@@ -385,8 +384,8 @@ const closeModal = () => {
|
||||
</v-card>
|
||||
|
||||
<!-- Diagnosis -->
|
||||
<v-card elevation="2" class="mb-4">
|
||||
<v-card-title class="bg-green-lighten-5 pa-3">
|
||||
<v-card elevation="10" class="mb-4">
|
||||
<v-card-title class="bg-green-lighten-5 pa-4">
|
||||
<div class="d-flex align-center">
|
||||
<Icon icon="solar:health-bold-duotone" height="24" class="mr-2 text-success" />
|
||||
<span class="text-h6">Diagnosis</span>
|
||||
@@ -406,12 +405,12 @@ const closeModal = () => {
|
||||
{{ index + 1 }}
|
||||
</v-avatar>
|
||||
<div class="flex-1-1">
|
||||
<div class="text-caption text-medium-emphasis mb-1">
|
||||
{{ item.jenisDiagnosa }}
|
||||
</div>
|
||||
<div class="font-weight-medium mb-1">
|
||||
{{ item.diagnosa }}
|
||||
</div>
|
||||
<div class="text-caption text-medium-emphasis mb-1">
|
||||
{{ item.jenisDiagnosa }}
|
||||
</div>
|
||||
<v-chip size="x-small" color="success" variant="outlined">
|
||||
{{ item.kodeDiagnosa }}
|
||||
</v-chip>
|
||||
@@ -428,10 +427,10 @@ const closeModal = () => {
|
||||
</v-card>
|
||||
|
||||
<!-- Tindakan -->
|
||||
<v-card elevation="2" class="mb-4">
|
||||
<v-card-title class="bg-purple-lighten-5 pa-3">
|
||||
<v-card elevation="10" class="mb-4">
|
||||
<v-card-title class="bg-purple-lighten-5 pa-4">
|
||||
<div class="d-flex align-center">
|
||||
<Icon icon="solar:medical-kit-bold-duotone" height="24" class="mr-2 text-purple" />
|
||||
<Icon icon="solar:medical-kit-bold-duotone" height="24" class="mr-2 text-secondary" />
|
||||
<span class="text-h6">Tindakan Operasi</span>
|
||||
</div>
|
||||
</v-card-title>
|
||||
@@ -442,10 +441,10 @@ const closeModal = () => {
|
||||
:key="index"
|
||||
class="px-0 mb-3"
|
||||
>
|
||||
<v-card variant="tonal" color="purple">
|
||||
<v-card variant="tonal" color="secondary">
|
||||
<v-card-text class="pa-3">
|
||||
<div class="d-flex align-start">
|
||||
<v-avatar color="purple" size="32" class="mr-3">
|
||||
<v-avatar color="secondary" size="32" class="mr-3">
|
||||
{{ index + 1 }}
|
||||
</v-avatar>
|
||||
<div class="flex-1-1">
|
||||
@@ -471,10 +470,10 @@ const closeModal = () => {
|
||||
</v-card>
|
||||
|
||||
<!-- Rencana Operasi -->
|
||||
<v-card elevation="2" class="mb-4">
|
||||
<v-card-title class="bg-orange-lighten-5 pa-3">
|
||||
<v-card elevation="10" class="mb-4">
|
||||
<v-card-title class="bg-orange-lighten-5 pa-4">
|
||||
<div class="d-flex align-center">
|
||||
<Icon icon="solar:calendar-mark-bold-duotone" height="24" class="mr-2 text-orange" />
|
||||
<Icon icon="solar:calendar-mark-bold-duotone" height="24" class="mr-2 text-warning" />
|
||||
<span class="text-h6">Rencana Operasi</span>
|
||||
</div>
|
||||
</v-card-title>
|
||||
@@ -526,10 +525,21 @@ const closeModal = () => {
|
||||
</div>
|
||||
</div>
|
||||
</v-col>
|
||||
<v-col v-if="rencanaOperasiData.keterangan" cols="12">
|
||||
<v-col v-if="rencanaOperasiData.rencanaOperasi" cols="6">
|
||||
<div class="info-item">
|
||||
<div class="info-label">
|
||||
<Icon icon="solar:notes-bold" height="20" class="mr-2" />
|
||||
Rencana Operasi
|
||||
</div>
|
||||
<div class="info-value">
|
||||
{{ rencanaOperasiData.rencanaOperasi }}
|
||||
</div>
|
||||
</div>
|
||||
</v-col>
|
||||
<v-col v-if="rencanaOperasiData.keterangan" cols="6">
|
||||
<div class="info-item">
|
||||
<div class="info-label">
|
||||
<Icon icon="solar:notebook-bold" height="20" class="mr-2" />
|
||||
Keterangan
|
||||
</div>
|
||||
<div class="info-value">
|
||||
@@ -542,14 +552,14 @@ const closeModal = () => {
|
||||
</v-card>
|
||||
|
||||
<!-- Dokter Pelaksana -->
|
||||
<v-card elevation="2" class="mb-4">
|
||||
<v-card-title class="bg-indigo-lighten-5 pa-3">
|
||||
<v-card elevation="10" class="mb-4">
|
||||
<v-card-title class="bg-indigo-lighten-5 pa-4">
|
||||
<div class="d-flex align-center">
|
||||
<Icon icon="solar:user-id-bold-duotone" height="24" class="mr-2 text-indigo" />
|
||||
<Icon icon="solar:user-id-bold-duotone" height="24" class="mr-2 text-info" />
|
||||
<span class="text-h6">Tim Dokter Pelaksana</span>
|
||||
</div>
|
||||
</v-card-title>
|
||||
<v-card-text class="pa-2">
|
||||
<v-card-text class="pa-4">
|
||||
<v-list v-if="dokterPelaksanaItems.length > 0" class="pa-0">
|
||||
<v-list-item
|
||||
v-for="(dokter, index) in dokterPelaksanaItems"
|
||||
@@ -583,8 +593,8 @@ const closeModal = () => {
|
||||
</v-card>
|
||||
|
||||
<!-- Status Operasi -->
|
||||
<v-card elevation="2" class="mb-2">
|
||||
<v-card-title class="bg-grey-lighten-3 pa-3">
|
||||
<v-card elevation="10" class="mb-2">
|
||||
<v-card-title class="bg-grey-lighten-3 pa-4">
|
||||
<div class="d-flex align-center">
|
||||
<Icon icon="solar:clipboard-check-bold-duotone" height="24" class="mr-2 text-grey-darken-2" />
|
||||
<span class="text-h6">Status Operasi</span>
|
||||
|
||||
@@ -49,6 +49,11 @@ const valid = ref(true);
|
||||
const loadingDetail = ref(false);
|
||||
const errorDetail = ref(false);
|
||||
|
||||
// Refs for child components
|
||||
const biodataPasienRef = ref();
|
||||
const medisPasienRef = ref();
|
||||
const rencanaOperasiRef = ref();
|
||||
|
||||
// Computed properties
|
||||
const isReadonly = computed(() => props.mode === 'view');
|
||||
|
||||
@@ -183,6 +188,38 @@ const closeModal = () => {
|
||||
showModal.value = false;
|
||||
};
|
||||
|
||||
// Focus on error field - scroll to component and focus on first invalid field
|
||||
const focusOnErrorField = (fieldName: string) => {
|
||||
nextTick(() => {
|
||||
// Map field names to component refs and actions
|
||||
const fieldMap: Record<string, { ref: any; action: string }> = {
|
||||
'noRekamMedis': { ref: biodataPasienRef, action: 'focusNoRekamMedis' },
|
||||
'diagnosis': { ref: medisPasienRef, action: 'focusDiagnosis' },
|
||||
'tindakan': { ref: medisPasienRef, action: 'focusTindakan' },
|
||||
'spesialis': { ref: rencanaOperasiRef, action: 'focusSpesialis' },
|
||||
'subSpesialis': { ref: rencanaOperasiRef, action: 'focusSubSpesialis' },
|
||||
'tanggalDaftar': { ref: rencanaOperasiRef, action: 'focusTanggalDaftar' },
|
||||
'kategoriOperasi': { ref: rencanaOperasiRef, action: 'focusKategoriOperasi' },
|
||||
};
|
||||
|
||||
const fieldInfo = fieldMap[fieldName];
|
||||
if (fieldInfo && fieldInfo.ref.value) {
|
||||
// Scroll to component
|
||||
const componentElement = fieldInfo.ref.value.$el;
|
||||
if (componentElement) {
|
||||
componentElement.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||
|
||||
// Call focus method if available
|
||||
setTimeout(() => {
|
||||
if (typeof fieldInfo.ref.value[fieldInfo.action] === 'function') {
|
||||
fieldInfo.ref.value[fieldInfo.action]();
|
||||
}
|
||||
}, 300); // Wait for scroll to complete
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const handleSimpan = async () => {
|
||||
const { valid: isValid } = await form.value.validate();
|
||||
|
||||
@@ -193,6 +230,11 @@ const handleSimpan = async () => {
|
||||
if (!validation.valid) {
|
||||
const errorMessage = `Data berikut harus diisi:\n\n${validation.errors.join(', ')}`;
|
||||
pendaftaranStore.showSnackbar(errorMessage, 'error');
|
||||
|
||||
// Focus on first error field
|
||||
if (validation.firstErrorField) {
|
||||
focusOnErrorField(validation.firstErrorField);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -210,6 +252,11 @@ const handleSimpan = async () => {
|
||||
const validation = pendaftaranStore.validateForm();
|
||||
const errorMessage = `Data berikut harus diisi:\n\n${validation.errors.join(', ')}`;
|
||||
pendaftaranStore.showSnackbar(errorMessage, 'error');
|
||||
|
||||
// Focus on first error field
|
||||
if (validation.firstErrorField) {
|
||||
focusOnErrorField(validation.firstErrorField);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -230,11 +277,11 @@ const handleReset = () => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-dialog v-model="showModal" max-width="1100px" persistent scrollable>
|
||||
<v-dialog v-model="showModal" max-width="900px" persistent scrollable>
|
||||
<v-card>
|
||||
<v-card-title class="d-flex align-center justify-space-between pa-3 bg-primary text-white">
|
||||
<v-card-title class="d-flex align-center justify-space-between pa-3">
|
||||
<div class="d-flex align-center">
|
||||
<v-icon class="mr-3">mdi-clipboard-plus</v-icon>
|
||||
<v-icon class="mr-3 text-primary">mdi-clipboard-plus</v-icon>
|
||||
<span class="text-h6">{{ modalTitle }}</span>
|
||||
</div>
|
||||
<v-btn
|
||||
@@ -246,7 +293,7 @@ const handleReset = () => {
|
||||
</v-btn>
|
||||
</v-card-title>
|
||||
|
||||
<v-card-text class="pa-4" style="max-height: 70vh; overflow-y: auto; overflow-x: hidden;">
|
||||
<v-card-text class="bg-background pa-5" style="max-height: 70vh; overflow-y: auto; overflow-x: hidden;">
|
||||
<LoadingState
|
||||
:loading="loadingDetail"
|
||||
:error="errorDetail"
|
||||
@@ -257,13 +304,14 @@ const handleReset = () => {
|
||||
<v-form ref="form" v-model="valid" lazy-validation>
|
||||
<v-row no-gutters>
|
||||
<!-- Data Biodata Pasien -->
|
||||
<v-col cols="12">
|
||||
<BiodataPasien v-model="formData" :readonly="isReadonly" />
|
||||
<v-col cols="12" class="mb-5">
|
||||
<BiodataPasien ref="biodataPasienRef" v-model="formData" :readonly="isReadonly" />
|
||||
</v-col>
|
||||
|
||||
<!-- Data Medis Pasien -->
|
||||
<v-col cols="12">
|
||||
<v-col cols="12" class="mb-5">
|
||||
<MedisPasien
|
||||
ref="medisPasienRef"
|
||||
v-model:diagnosis-items="diagnosisItems"
|
||||
v-model:tindakan-items="tindakanItems"
|
||||
:readonly="isReadonly"
|
||||
@@ -273,6 +321,7 @@ const handleReset = () => {
|
||||
<!-- Data Rencana Operasi -->
|
||||
<v-col cols="12">
|
||||
<RencanaOperasi
|
||||
ref="rencanaOperasiRef"
|
||||
v-model:rencana-operasi-data="rencanaOperasiData"
|
||||
v-model:dokter-pelaksana-items="dokterPelaksanaItems"
|
||||
:readonly="isReadonly"
|
||||
@@ -284,15 +333,6 @@ const handleReset = () => {
|
||||
</v-card-text>
|
||||
|
||||
<v-card-actions class="pa-4 justify-end">
|
||||
<v-btn
|
||||
color="default"
|
||||
size="large"
|
||||
variant="outlined"
|
||||
prepend-icon="mdi-close"
|
||||
@click="closeModal"
|
||||
>
|
||||
{{ isReadonly ? 'Tutup' : 'Batal' }}
|
||||
</v-btn>
|
||||
<v-btn
|
||||
v-if="!isReadonly"
|
||||
color="error"
|
||||
|
||||
@@ -166,24 +166,24 @@ watch(() => props.modelValue, (isOpen) => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-dialog v-model="dialog" max-width="800" persistent scrollable>
|
||||
<v-dialog v-model="dialog" max-width="900px" persistent scrollable>
|
||||
<v-card>
|
||||
<v-card-title class="d-flex align-center justify-space-between bg-primary pa-4">
|
||||
<v-card-title class="d-flex align-center justify-space-between pa-4">
|
||||
<div class="d-flex align-center">
|
||||
<Icon icon="solar:clipboard-check-bold" height="24" class="mr-2" />
|
||||
<span class="text-h5">Update Status Antrian Operasi</span>
|
||||
<Icon icon="solar:clipboard-check-bold-duotone" height="28" class="text-primary mr-3" />
|
||||
<span class="text-h6">Update Status Antrian Operasi</span>
|
||||
</div>
|
||||
<v-btn
|
||||
icon
|
||||
variant="text"
|
||||
size="small"
|
||||
@click="dialog = false"
|
||||
:disabled="loadingSubmit"
|
||||
>
|
||||
<Icon icon="mdi-close" height="20" />
|
||||
<v-icon>mdi-close</v-icon>
|
||||
</v-btn>
|
||||
</v-card-title>
|
||||
<v-card-text class="pa-4" style="max-height: 600px;">
|
||||
|
||||
<v-card-text class="pa-5 bg-background" style="max-height: 75vh; overflow-y: auto;">
|
||||
<!-- Loading State -->
|
||||
<div v-if="loading" class="text-center py-8">
|
||||
<v-progress-circular
|
||||
@@ -207,62 +207,96 @@ watch(() => props.modelValue, (isOpen) => {
|
||||
<!-- Content -->
|
||||
<div v-else-if="pasienData">
|
||||
<!-- Informasi Pasien -->
|
||||
<v-card variant="outlined" class="mb-6">
|
||||
<v-card-item>
|
||||
<h6 class="text-h6 font-weight-bold mb-4">
|
||||
<Icon icon="solar:user-bold" height="20" class="mr-2" />
|
||||
Informasi Pasien
|
||||
</h6>
|
||||
</v-card-item>
|
||||
<v-divider></v-divider>
|
||||
<v-card-text >
|
||||
<v-card elevation="2" class="mb-4">
|
||||
<v-card-title class="bg-blue-lighten-5 pa-4">
|
||||
<div class="d-flex align-center">
|
||||
<Icon icon="solar:user-bold-duotone" height="24" class="mr-2 text-primary" />
|
||||
<span class="text-h6">Informasi Pasien</span>
|
||||
</div>
|
||||
</v-card-title>
|
||||
<v-card-text class="pa-5">
|
||||
<v-row>
|
||||
<v-col cols="12" sm="6">
|
||||
<div class="mb-3">
|
||||
<div class="text-caption text-medium-emphasis">No. Rekam Medis</div>
|
||||
<div class="text-body-1 font-weight-medium">{{ pasienData.formData?.noRekamMedis || '-' }}</div>
|
||||
<div class="info-item">
|
||||
<div class="info-label">
|
||||
<Icon icon="mdi-card-account-details" height="20" class="mr-2" />
|
||||
No. Rekam Medis
|
||||
</div>
|
||||
<div class="info-value font-weight-bold">
|
||||
{{ pasienData.formData?.noRekamMedis || '-' }}
|
||||
</div>
|
||||
</div>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="6">
|
||||
<div class="mb-3">
|
||||
<div class="text-caption text-medium-emphasis">Nama Pasien</div>
|
||||
<div class="text-body-1 font-weight-medium">{{ pasienData.formData?.namaPasien || '-' }}</div>
|
||||
<div class="info-item">
|
||||
<div class="info-label">
|
||||
<Icon icon="solar:user-heart-bold" height="20" class="mr-2" />
|
||||
Nama Pasien
|
||||
</div>
|
||||
<div class="info-value font-weight-bold">
|
||||
{{ pasienData.formData?.namaPasien || '-' }}
|
||||
</div>
|
||||
</div>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="6">
|
||||
<div class="mb-3">
|
||||
<div class="text-caption text-medium-emphasis">Jenis Kelamin</div>
|
||||
<div class="text-body-1">{{ getGenderText(pasienData.formData?.jenisKelamin) }}</div>
|
||||
<div class="info-item">
|
||||
<div class="info-label">
|
||||
<Icon icon="mdi-gender-male-female" height="20" class="mr-2" />
|
||||
Jenis Kelamin
|
||||
</div>
|
||||
<div class="info-value">
|
||||
{{ getGenderText(pasienData.formData?.jenisKelamin) }}
|
||||
</div>
|
||||
</div>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="6">
|
||||
<div class="mb-3">
|
||||
<div class="text-caption text-medium-emphasis">Tanggal Daftar</div>
|
||||
<div class="text-body-1">{{ formatDate(pasienData.rencanaOperasiData?.tanggalDaftar) }}</div>
|
||||
<div class="info-item">
|
||||
<div class="info-label">
|
||||
<Icon icon="solar:calendar-date-bold" height="20" class="mr-2" />
|
||||
Tanggal Daftar
|
||||
</div>
|
||||
<div class="info-value">
|
||||
{{ formatDate(pasienData.rencanaOperasiData?.tanggalDaftar) }}
|
||||
</div>
|
||||
</div>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="4">
|
||||
<div class="mb-3">
|
||||
<div class="text-caption text-medium-emphasis">Kategori</div>
|
||||
<v-chip size="small" color="primary" variant="tonal">
|
||||
{{ pasienData.rencanaOperasiData?.kategoriName || '-' }}
|
||||
</v-chip>
|
||||
<div class="info-item">
|
||||
<div class="info-label">
|
||||
<Icon icon="solar:clipboard-list-bold" height="20" class="mr-2" />
|
||||
Kategori
|
||||
</div>
|
||||
<div class="info-value">
|
||||
<v-chip size="small" color="primary" variant="flat">
|
||||
{{ pasienData.rencanaOperasiData?.kategoriName || '-' }}
|
||||
</v-chip>
|
||||
</div>
|
||||
</div>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="4">
|
||||
<div class="mb-3">
|
||||
<div class="text-caption text-medium-emphasis">Spesialis</div>
|
||||
<v-chip size="small" color="secondary" variant="tonal">
|
||||
{{ pasienData.rencanaOperasiData?.SpesialisName || '-' }}
|
||||
</v-chip>
|
||||
<div class="info-item">
|
||||
<div class="info-label">
|
||||
<Icon icon="solar:stethoscope-bold" height="20" class="mr-2" />
|
||||
Spesialis
|
||||
</div>
|
||||
<div class="info-value">
|
||||
<v-chip size="small" color="secondary" variant="flat">
|
||||
{{ pasienData.rencanaOperasiData?.SpesialisName || '-' }}
|
||||
</v-chip>
|
||||
</div>
|
||||
</div>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="4">
|
||||
<div class="mb-3">
|
||||
<div class="text-caption text-medium-emphasis">Sub Spesialis</div>
|
||||
<v-chip size="small" color="info" variant="tonal">
|
||||
{{ pasienData.rencanaOperasiData?.SubSpesialisName || '-' }}
|
||||
</v-chip>
|
||||
<div class="info-item">
|
||||
<div class="info-label">
|
||||
<Icon icon="solar:health-bold" height="20" class="mr-2" />
|
||||
Sub Spesialis
|
||||
</div>
|
||||
<div class="info-value">
|
||||
<v-chip size="small" color="info" variant="flat">
|
||||
{{ pasienData.rencanaOperasiData?.SubSpesialisName || '-' }}
|
||||
</v-chip>
|
||||
</div>
|
||||
</div>
|
||||
</v-col>
|
||||
</v-row>
|
||||
@@ -270,15 +304,14 @@ watch(() => props.modelValue, (isOpen) => {
|
||||
</v-card>
|
||||
|
||||
<!-- Form Update Status -->
|
||||
<v-card variant="outlined">
|
||||
<v-card-item>
|
||||
<h6 class="text-h6 font-weight-bold mb-4">
|
||||
<Icon icon="solar:settings-bold" height="20" class="mr-2" />
|
||||
Update Status Operasi
|
||||
</h6>
|
||||
</v-card-item>
|
||||
<v-divider></v-divider>
|
||||
<v-card-text>
|
||||
<v-card elevation="2" class="mb-2">
|
||||
<v-card-title class="bg-orange-lighten-5 pa-4">
|
||||
<div class="d-flex align-center">
|
||||
<Icon icon="solar:settings-bold-duotone" height="24" class="mr-2 text-warning" />
|
||||
<span class="text-h6">Update Status Operasi</span>
|
||||
</div>
|
||||
</v-card-title>
|
||||
<v-card-text class="pa-4">
|
||||
<v-row>
|
||||
<!-- Status Operasi -->
|
||||
<v-col cols="12">
|
||||
@@ -299,6 +332,7 @@ watch(() => props.modelValue, (isOpen) => {
|
||||
:color="formData.statusOperasi === STATUS.BELUM ? 'primary' : 'default'"
|
||||
@click="formData.statusOperasi = STATUS.BELUM"
|
||||
>
|
||||
<Icon v-if="formData.statusOperasi === STATUS.BELUM" icon="mdi-progress-clock" height="20" class="mr-2" />
|
||||
Belum
|
||||
</v-btn>
|
||||
<v-btn
|
||||
@@ -308,6 +342,7 @@ watch(() => props.modelValue, (isOpen) => {
|
||||
:color="formData.statusOperasi === STATUS.SELESAI ? 'success' : 'default'"
|
||||
@click="formData.statusOperasi = STATUS.SELESAI"
|
||||
>
|
||||
<Icon v-if="formData.statusOperasi === STATUS.SELESAI" icon="mdi-check-circle" height="20" class="mr-2" />
|
||||
Selesai
|
||||
</v-btn>
|
||||
<v-btn
|
||||
@@ -317,6 +352,7 @@ watch(() => props.modelValue, (isOpen) => {
|
||||
:color="formData.statusOperasi === STATUS.TUNDA ? 'warning' : 'default'"
|
||||
@click="formData.statusOperasi = STATUS.TUNDA"
|
||||
>
|
||||
<Icon v-if="formData.statusOperasi === STATUS.TUNDA" icon="mdi-timer-sand" height="20" class="mr-2" />
|
||||
Tunda
|
||||
</v-btn>
|
||||
<v-btn
|
||||
@@ -326,6 +362,7 @@ watch(() => props.modelValue, (isOpen) => {
|
||||
:color="formData.statusOperasi === STATUS.BATAL ? 'error' : 'default'"
|
||||
@click="formData.statusOperasi = STATUS.BATAL"
|
||||
>
|
||||
<Icon v-if="formData.statusOperasi === STATUS.BATAL" icon="mdi-close-circle" height="20" class="mr-2" />
|
||||
Batal
|
||||
</v-btn>
|
||||
</v-btn-group>
|
||||
@@ -369,27 +406,16 @@ watch(() => props.modelValue, (isOpen) => {
|
||||
</div>
|
||||
</v-card-text>
|
||||
|
||||
<v-divider></v-divider>
|
||||
|
||||
<v-card-actions class="pa-4">
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn
|
||||
variant="outlined"
|
||||
@click="dialog = false"
|
||||
:disabled="loadingSubmit"
|
||||
size="large"
|
||||
prepend-icon="mdi-close"
|
||||
>
|
||||
Batal
|
||||
</v-btn>
|
||||
|
||||
<v-card-actions class="pa-4 justify-end">
|
||||
<v-btn
|
||||
color="primary"
|
||||
@click="handleSubmit"
|
||||
size="large"
|
||||
variant="flat"
|
||||
prepend-icon="mdi-content-save"
|
||||
:loading="loadingSubmit"
|
||||
:disabled="loading || !isFormValid"
|
||||
variant="flat"
|
||||
size="large"
|
||||
prepend-icon="mdi-content-save"
|
||||
@click="handleSubmit"
|
||||
>
|
||||
Simpan
|
||||
</v-btn>
|
||||
@@ -415,3 +441,25 @@ watch(() => props.modelValue, (isOpen) => {
|
||||
</v-snackbar>
|
||||
</v-dialog>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.info-item {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 0.875rem;
|
||||
color: rgb(var(--v-theme-on-surface));
|
||||
opacity: 0.7;
|
||||
margin-bottom: 0.5rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
font-size: 1rem;
|
||||
color: rgb(var(--v-theme-on-surface));
|
||||
padding-left: 28px;
|
||||
}
|
||||
</style>
|
||||
@@ -4,6 +4,7 @@ import api from '~/services/api';
|
||||
import type { Props } from '~/types/common';
|
||||
import type { Dokter } from '~/types/pendaftaran';
|
||||
import type { KategoriOperasi, Spesialis, SubSpesialis } from '~/types/antrean';
|
||||
import { Icon } from '@iconify/vue';
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
readonly: false
|
||||
@@ -284,23 +285,65 @@ const selectedDokterIds = computed({
|
||||
const removeDokter = (dokterId: string) => {
|
||||
dokterPelaksanaItems.value = dokterPelaksanaItems.value.filter(d => d.id !== dokterId);
|
||||
};
|
||||
|
||||
// Refs for focus functionality
|
||||
const spesialisInput = ref();
|
||||
const subSpesialisInput = ref();
|
||||
const tanggalDaftarInput = ref();
|
||||
const kategoriOperasiInput = ref();
|
||||
|
||||
// Expose methods to focus on fields
|
||||
const focusSpesialis = () => {
|
||||
if (spesialisInput.value) {
|
||||
spesialisInput.value.focus();
|
||||
}
|
||||
};
|
||||
|
||||
const focusSubSpesialis = () => {
|
||||
if (subSpesialisInput.value) {
|
||||
subSpesialisInput.value.focus();
|
||||
}
|
||||
};
|
||||
|
||||
const focusTanggalDaftar = () => {
|
||||
if (tanggalDaftarInput.value) {
|
||||
tanggalDaftarInput.value.focus();
|
||||
}
|
||||
};
|
||||
|
||||
const focusKategoriOperasi = () => {
|
||||
if (kategoriOperasiInput.value) {
|
||||
kategoriOperasiInput.value.focus();
|
||||
}
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
focusSpesialis,
|
||||
focusSubSpesialis,
|
||||
focusTanggalDaftar,
|
||||
focusKategoriOperasi
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-card elevation="10">
|
||||
<v-divider></v-divider>
|
||||
<v-card-item>
|
||||
<h5 class="text-h5 font-weight-bold">Data Rencana Operasi</h5>
|
||||
</v-card-item>
|
||||
<v-card-text class="pa-5">
|
||||
<div class="d-flex align-center">
|
||||
<!-- <Icon icon="solar:calendar-mark-bold-duotone" height="24" class="mr-2" /> -->
|
||||
<span class="text-h5">Data Rencana Operasi</span>
|
||||
</div>
|
||||
</v-card-text>
|
||||
<v-divider> </v-divider>
|
||||
<v-card-text>
|
||||
<v-row>
|
||||
<!-- Spesialis -->
|
||||
<v-col cols="12" md="6">
|
||||
<v-label class="mb-2 font-weight-medium">Spesialis <span class="text-error">*</span></v-label>
|
||||
<v-autocomplete
|
||||
ref="spesialisInput"
|
||||
v-model="rencanaOperasiData.spesialis"
|
||||
:items="spesialisOptions"
|
||||
placeholder="Select an item..."
|
||||
placeholder="Pilih Spesialis..."
|
||||
variant="outlined"
|
||||
density="comfortable"
|
||||
:rules="[rules.required]"
|
||||
@@ -316,9 +359,10 @@ const removeDokter = (dokterId: string) => {
|
||||
<v-col cols="12" md="6">
|
||||
<v-label class="mb-2 font-weight-medium">Sub Spesialis <span class="text-error">*</span></v-label>
|
||||
<v-autocomplete
|
||||
ref="subSpesialisInput"
|
||||
v-model="rencanaOperasiData.subSpesialis"
|
||||
:items="subSpesialisOptions"
|
||||
placeholder="Select an item..."
|
||||
placeholder="Pilih Sub Spesialis..."
|
||||
variant="outlined"
|
||||
density="comfortable"
|
||||
:rules="[rules.required]"
|
||||
@@ -420,7 +464,7 @@ const removeDokter = (dokterId: string) => {
|
||||
<template #append>
|
||||
<v-btn
|
||||
icon
|
||||
size="x-small"
|
||||
size="small"
|
||||
variant="text"
|
||||
color="error"
|
||||
@click="removeDokter(dokter.id)"
|
||||
@@ -464,6 +508,7 @@ const removeDokter = (dokterId: string) => {
|
||||
<v-col cols="12" md="6">
|
||||
<v-label class="mb-2 font-weight-medium">Tanggal Daftar <span class="text-error">*</span></v-label>
|
||||
<v-text-field
|
||||
ref="tanggalDaftarInput"
|
||||
v-model="rencanaOperasiData.tanggalDaftar"
|
||||
type="datetime-local"
|
||||
variant="outlined"
|
||||
@@ -479,9 +524,10 @@ const removeDokter = (dokterId: string) => {
|
||||
<v-col cols="12" md="6">
|
||||
<v-label class="mb-2 font-weight-medium">Kategori Operasi <span class="text-error">*</span></v-label>
|
||||
<v-autocomplete
|
||||
ref="kategoriOperasiInput"
|
||||
v-model="rencanaOperasiData.kategoriOperasi"
|
||||
:items="kategoriOperasiOptions"
|
||||
placeholder="Select an item..."
|
||||
placeholder="Pilih Kategori Operasi..."
|
||||
variant="outlined"
|
||||
density="comfortable"
|
||||
:rules="[rules.required]"
|
||||
|
||||
Reference in New Issue
Block a user