fix : review modal update

This commit is contained in:
Yusron alamsyah
2026-03-06 13:44:10 +07:00
parent d24c2a2b11
commit 38809bec2b
3 changed files with 451 additions and 480 deletions
+1 -1
View File
@@ -83,7 +83,7 @@ const resetFilters = () => {
color="primary"
prepend-icon="mdi-filter-variant"
>
Filter & Sort
Filter & Urutkan
<v-badge
v-if="activeFilterCount > 0"
color="primary"
+244 -319
View File
@@ -1,5 +1,5 @@
<script setup lang="ts">
import api from '@/services/api';
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';
@@ -34,7 +34,7 @@ const searchDiagnosis = async (search: string) => {
loadingDiagnosis.value = true;
diagnosisSearchPerformed.value = false;
try {
const response = await api.get('/reference/diagnosa', {
params: {
@@ -71,8 +71,7 @@ const handleDiagnosisSearchInput = (value: string) => {
const diagnosisOptions = computed(() => {
return diagnosisList.value.map(d => ({
title: d.select,
value: d.kodeicd,
diagnosa: d.keterangan
value: d.select
}));
});
@@ -99,7 +98,7 @@ const searchTindakan = async (search: string) => {
loadingTindakan.value = true;
tindakanSearchPerformed.value = false;
try {
const response = await api.get('/reference/tindakan', {
params: {
@@ -136,8 +135,7 @@ const handleTindakanSearchInput = (value: string) => {
const tindakanOptions = computed(() => {
return tindakanList.value.map(t => ({
title: t.select,
value: t.kode,
tindakan: t.keterangan
value: t.select
}));
});
@@ -170,13 +168,13 @@ const editDiagnosis = (index: number) => {
const saveDiagnosis = () => {
if (!diagnosisForm.value.kodeDiagnosa.trim() || !diagnosisForm.value.diagnosa.trim()) return;
if (editingDiagnosisIndex.value !== null) {
diagnosisItems.value[editingDiagnosisIndex.value] = { ...diagnosisForm.value };
} else {
diagnosisItems.value.push({ ...diagnosisForm.value });
}
resetDiagnosisForm();
diagnosisFormExpanded.value = false;
};
@@ -191,10 +189,18 @@ const deleteDiagnosis = (index: number) => {
};
// Auto-fill diagnosis when code is selected
const handleKodeDiagnosaChange = (kode: string) => {
const found = diagnosisList.value.find(d => d.kodeicd === kode);
if (found) {
diagnosisForm.value.diagnosa = found.keterangan;
const handleKodeDiagnosaChange = (selectValue: string) => {
if (!selectValue) {
diagnosisForm.value.kodeDiagnosa = '';
diagnosisForm.value.diagnosa = '';
return;
}
// Parse the select value format: "A04 | Other bacterial intestinal infections"
const parts = selectValue.split('|').map(p => p.trim());
if (parts.length >= 2) {
diagnosisForm.value.kodeDiagnosa = parts[0];
diagnosisForm.value.diagnosa = parts.slice(1).join('|').trim();
}
};
@@ -219,13 +225,13 @@ const editTindakan = (index: number) => {
const saveTindakan = () => {
if (!tindakanForm.value.kodeTindakan.trim() || !tindakanForm.value.tindakan.trim()) return;
if (editingTindakanIndex.value !== null) {
tindakanItems.value[editingTindakanIndex.value] = { ...tindakanForm.value };
} else {
tindakanItems.value.push({ ...tindakanForm.value });
}
resetTindakanForm();
tindakanFormExpanded.value = false;
};
@@ -240,10 +246,18 @@ const deleteTindakan = (index: number) => {
};
// Auto-fill tindakan when code is selected
const handleKodeTindakanChange = (kode: string) => {
const found = tindakanList.value.find(t => t.kode === kode);
if (found) {
tindakanForm.value.tindakan = found.keterangan;
const handleKodeTindakanChange = (selectValue: string) => {
if (!selectValue) {
tindakanForm.value.kodeTindakan = '';
tindakanForm.value.tindakan = '';
return;
}
// Parse the select value format: "CODE | Description"
const parts = selectValue.split('|').map(p => p.trim());
if (parts.length >= 2) {
tindakanForm.value.kodeTindakan = parts[0];
tindakanForm.value.tindakan = parts.slice(1).join('|').trim();
}
};
@@ -284,304 +298,215 @@ defineExpose({
<template>
<v-divider> </v-divider>
<v-card elevation="0" class="mt-4 mb-0">
<v-card-text class="pa-2">
<div class="d-flex align-center justify-space-between">
<div class="d-flex align-center">
<Icon icon="solar:health-bold-duotone" height="20" class="mr-2 text-primary" />
<span class="text-h5">Diagnosa</span>
</div>
<v-btn
v-if="!readonly"
color="primary"
variant="text"
@click="openDiagnosisModal"
>
<Icon icon="mdi-plus-circle" height="18" class="mr-1" />
Tambah Diagnosa
</v-btn>
</div>
</v-card-text>
<v-card-text class="pt-2">
<!-- Diagnosa -->
<div ref="diagnosisSection">
<v-table>
<thead>
<tr>
<th style="width: 200px;">Jenis Diagnosa</th>
<th style="width: 300px;">Kode Diagnosa</th>
<th>Diagnosa</th>
<th style="width: 130px;" class="text-center">Action</th>
</tr>
</thead>
<tbody>
<!-- Empty State -->
<tr v-if="diagnosisItems.length === 0 && !diagnosisFormExpanded">
<td colspan="4" class="text-center pa-8">
<div class="text-medium-emphasis">
<Icon icon="solar:medical-kit-outline" height="48" class="mb-2" />
<p class="text-body-2">Tidak ada data diagnosa</p>
</div>
</td>
</tr>
<!-- Data Rows -->
<tr v-for="(item, index) in diagnosisItems" :key="index">
<td>
<v-chip
:color="item.jenisDiagnosa === 'utama' ? 'primary' : 'secondary'"
variant="flat"
size="small"
>
{{ item.jenisDiagnosa }}
</v-chip>
</td>
<td>{{ item.kodeDiagnosa }}</td>
<td>{{ item.diagnosa }}</td>
<td class="text-center">
<v-btn
v-if="!readonly"
icon
size="small"
variant="text"
color="error"
@click="deleteDiagnosis(index)"
>
<Icon icon="mdi-delete-outline" height="20" />
</v-btn>
</td>
</tr>
<!-- Form Input Row -->
<tr v-if="!readonly && diagnosisFormExpanded" class="bg-blue-lighten-5">
<td>
<v-btn-group density="compact">
<v-btn
:color="diagnosisForm.jenisDiagnosa === 'utama' ? 'primary' : 'default'"
:variant="diagnosisForm.jenisDiagnosa === 'utama' ? 'flat' : 'outlined'"
size="small"
class="text-none"
@click="diagnosisForm.jenisDiagnosa = 'utama'"
:prepend-icon="diagnosisForm.jenisDiagnosa === 'utama' ? 'mdi-radiobox-marked' : 'mdi-radiobox-blank'"
>
utama
</v-btn>
<v-btn
:color="diagnosisForm.jenisDiagnosa === 'tambahan' ? 'primary' : 'default'"
:variant="diagnosisForm.jenisDiagnosa === 'tambahan' ? 'flat' : 'outlined'"
size="small"
class="text-none"
@click="diagnosisForm.jenisDiagnosa = 'tambahan'"
:prepend-icon="diagnosisForm.jenisDiagnosa === 'tambahan' ? 'mdi-radiobox-marked' : 'mdi-radiobox-blank'"
>
tambahan
</v-btn>
</v-btn-group>
</td>
<td>
<v-autocomplete
ref="diagnosisInput"
v-model="diagnosisForm.kodeDiagnosa"
:items="diagnosisOptions"
placeholder="Cari..."
variant="outlined"
density="compact"
hide-details
:loading="loadingDiagnosis"
no-filter
clearable
@update:search="handleDiagnosisSearchInput"
@update:model-value="handleKodeDiagnosaChange"
>
<template #append-inner>
<Icon icon="mdi-magnify" height="18" />
</template>
<template #no-data>
<v-list-item>
<v-list-item-title class="text-caption">
{{ diagnosisSearchPerformed && diagnosisList.length === 0
? 'Data tidak ditemukan' : 'Ketik untuk mencari...' }}
</v-list-item-title>
</v-list-item>
</template>
</v-autocomplete>
</td>
<td>
<v-text-field
v-model="diagnosisForm.diagnosa"
variant="outlined"
density="compact"
readonly
bg-color="grey-lighten-3"
hide-details
placeholder="Diagnosa akan muncul setelah memilih kode"
></v-text-field>
</td>
<td class="text-center">
<v-btn
icon
size="small"
variant="text"
color="grey"
@click="cancelEditDiagnosis"
>
<Icon icon="mdi-close" height="20" />
</v-btn>
<v-btn
icon
size="small"
variant="text"
color="success"
@click="saveDiagnosis"
:disabled="!diagnosisForm.kodeDiagnosa || !diagnosisForm.diagnosa"
>
<Icon icon="mdi-check" height="20" />
</v-btn>
</td>
</tr>
</tbody>
</v-table>
</div>
</v-card-text>
</v-card>
<v-divider> </v-divider>
<v-card elevation="0" class="mt-4 mb-0">
<v-card-text class="pa-2">
<div class="d-flex align-center justify-space-between">
<div class="d-flex align-center">
<Icon icon="solar:medical-kit-bold-duotone" height="20" class="mr-2 text-primary" />
<span class="text-h5">Tindakan</span>
</div>
<v-btn
v-if="!readonly"
color="primary"
variant="text"
@click="openTindakanModal"
>
<Icon icon="mdi-plus-circle" height="18" class="mr-1" />
Tambah Tindakan
</v-btn>
</div>
</v-card-text>
<v-card-text class="pt-2">
<!-- Tindakan -->
<div ref="tindakanSection">
<v-table>
<thead>
<tr>
<th style="width: 300px;">Kode Tindakan</th>
<th>Tindakan</th>
<th style="width: 350px;">Tindakan Tambahan</th>
<th style="width: 130px;" class="text-center">Action</th>
</tr>
</thead>
<tbody>
<!-- Empty State -->
<tr v-if="tindakanItems.length === 0 && !tindakanFormExpanded">
<td colspan="4" class="text-center pa-8">
<div class="text-medium-emphasis">
<Icon icon="solar:medical-kit-outline" height="48" class="mb-2" />
<p class="text-body-2">Tidak ada data tindakan</p>
</div>
</td>
</tr>
<!-- Data Rows -->
<tr v-for="(item, index) in tindakanItems" :key="index">
<td>{{ item.kodeTindakan }}</td>
<td>{{ item.tindakan }}</td>
<td>
<span class="text-body-2 text-medium-emphasis">{{ item.tindakanTambahan || '-' }}</span>
</td>
<td class="text-center">
<v-btn
v-if="!readonly"
icon
size="small"
variant="text"
color="error"
@click="deleteTindakan(index)"
>
<Icon icon="mdi-delete-outline" height="20" />
</v-btn>
</td>
</tr>
<!-- Form Input Row -->
<tr v-if="!readonly && tindakanFormExpanded" class="bg-purple-lighten-5">
<td>
<v-autocomplete
ref="tindakanInput"
v-model="tindakanForm.kodeTindakan"
:items="tindakanOptions"
placeholder="Cari..."
variant="outlined"
density="compact"
hide-details
:loading="loadingTindakan"
no-filter
clearable
@update:search="handleTindakanSearchInput"
@update:model-value="handleKodeTindakanChange"
>
<template #append-inner>
<Icon icon="mdi-magnify" height="18" />
</template>
<template #no-data>
<v-list-item>
<v-list-item-title class="text-caption">
{{ tindakanSearchPerformed && tindakanList.length === 0
? 'Data tidak ditemukan' : 'Ketik untuk mencari...' }}
</v-list-item-title>
</v-list-item>
</template>
</v-autocomplete>
</td>
<td>
<v-text-field
v-model="tindakanForm.tindakan"
variant="outlined"
density="compact"
readonly
bg-color="grey-lighten-3"
hide-details
placeholder="Tindakan akan muncul setelah memilih kode"
></v-text-field>
</td>
<td>
<v-text-field
v-model="tindakanForm.tindakanTambahan"
placeholder="Tindakan Tambahan..."
variant="outlined"
density="compact"
hide-details
></v-text-field>
</td>
<td class="text-center">
<v-btn
icon
size="small"
variant="text"
color="grey"
@click="cancelEditTindakan"
>
<Icon icon="mdi-close" height="20" />
</v-btn>
<v-btn
icon
size="small"
variant="text"
color="success"
@click="saveTindakan"
:disabled="!tindakanForm.kodeTindakan || !tindakanForm.tindakan"
>
<Icon icon="mdi-check" height="20" />
</v-btn>
</td>
</tr>
</tbody>
</v-table>
</div>
</v-card-text>
</v-card>
<v-row class="row">
<v-col cols="12">
<v-card elevation="0" class="mt-4 mb-0">
<v-card-text class="pa-2">
<div class="d-flex align-center justify-space-between">
<div class="d-flex align-center">
<Icon icon="solar:health-bold-duotone" height="20" class="mr-2 text-primary" />
<span class="text-h5">Diagnosa</span>
</div>
<v-btn v-if="!readonly" color="primary" variant="text" @click="openDiagnosisModal">
<Icon icon="mdi-plus-circle" height="18" class="mr-1" />
Tambah Diagnosa
</v-btn>
</div>
</v-card-text>
<v-card-text class="pt-2">
<!-- Diagnosa -->
<div ref="diagnosisSection">
<v-table>
<thead>
<tr>
<th style="width: 200px;">Jenis Diagnosa</th>
<th>Diagnosa</th>
<th style="width: 130px;" class="text-center">Action</th>
</tr>
</thead>
<tbody>
<!-- Empty State -->
<tr v-if="diagnosisItems.length === 0 && !diagnosisFormExpanded">
<td colspan="3" class="text-center pa-8">
<div class="text-medium-emphasis">
<Icon icon="solar:health-bold-duotone" height="48" class="mb-2" />
<p class="text-body-2">Tidak ada data diagnosa</p>
</div>
</td>
</tr>
<!-- Data Rows -->
<tr v-for="(item, index) in diagnosisItems" :key="index">
<td>
<v-chip :color="item.jenisDiagnosa === 'utama' ? 'primary' : 'secondary'"
variant="flat" size="small">
{{ item.jenisDiagnosa }}
</v-chip>
</td>
<td>{{ item.kodeDiagnosa }} | {{ item.diagnosa }}</td>
<td class="text-center">
<v-btn v-if="!readonly" icon size="small" variant="text" color="error"
@click="deleteDiagnosis(index)">
<Icon icon="mdi-delete-outline" height="20" />
</v-btn>
</td>
</tr>
<!-- Form Input Row -->
<tr v-if="!readonly && diagnosisFormExpanded" class="bg-blue-lighten-5">
<td>
<v-btn-group density="compact">
<v-btn
:color="diagnosisForm.jenisDiagnosa === 'utama' ? 'primary' : 'default'"
:variant="diagnosisForm.jenisDiagnosa === 'utama' ? 'flat' : 'outlined'"
size="small" class="text-none"
@click="diagnosisForm.jenisDiagnosa = 'utama'"
:prepend-icon="diagnosisForm.jenisDiagnosa === 'utama' ? 'mdi-radiobox-marked' : 'mdi-radiobox-blank'">
utama
</v-btn>
<v-btn
:color="diagnosisForm.jenisDiagnosa === 'tambahan' ? 'primary' : 'default'"
:variant="diagnosisForm.jenisDiagnosa === 'tambahan' ? 'flat' : 'outlined'"
size="small" class="text-none"
@click="diagnosisForm.jenisDiagnosa = 'tambahan'"
:prepend-icon="diagnosisForm.jenisDiagnosa === 'tambahan' ? 'mdi-radiobox-marked' : 'mdi-radiobox-blank'">
tambahan
</v-btn>
</v-btn-group>
</td>
<td>
<v-autocomplete ref="diagnosisInput"
:model-value="diagnosisForm.kodeDiagnosa && diagnosisForm.diagnosa ? `${diagnosisForm.kodeDiagnosa} | ${diagnosisForm.diagnosa}` : ''"
:items="diagnosisOptions" placeholder="Cari kode atau diagnosa..."
variant="outlined" density="compact" hide-details
:loading="loadingDiagnosis" no-filter clearable
@update:search="handleDiagnosisSearchInput"
@update:model-value="handleKodeDiagnosaChange">
<template #append-inner>
<Icon icon="mdi-magnify" height="18" />
</template>
<template #no-data>
<v-list-item>
<v-list-item-title class="text-caption">
{{ diagnosisSearchPerformed && diagnosisList.length === 0
? 'Data tidak ditemukan' : 'Ketik minimal 3 karakter untuk mencari...' }}
</v-list-item-title>
</v-list-item>
</template>
</v-autocomplete>
</td>
<td class="text-center">
<v-btn icon size="small" variant="text" color="grey"
@click="cancelEditDiagnosis">
<Icon icon="mdi-close" height="20" />
</v-btn>
<v-btn icon size="small" variant="text" color="success" @click="saveDiagnosis"
:disabled="!diagnosisForm.kodeDiagnosa || !diagnosisForm.diagnosa">
<Icon icon="mdi-check" height="20" />
</v-btn>
</td>
</tr>
</tbody>
</v-table>
</div>
</v-card-text>
</v-card>
</v-col>
<v-col cols="12">
<v-card elevation="0" class="mt-4 mb-0">
<v-card-text class="pa-2">
<div class="d-flex align-center justify-space-between">
<div class="d-flex align-center">
<Icon icon="solar:medical-kit-bold-duotone" height="20" class="mr-2 text-primary" />
<span class="text-h5">Tindakan</span>
</div>
<v-btn v-if="!readonly" color="primary" variant="text" @click="openTindakanModal">
<Icon icon="mdi-plus-circle" height="18" class="mr-1" />
Tambah Tindakan
</v-btn>
</div>
</v-card-text>
<v-card-text class="pt-2">
<!-- Tindakan -->
<div ref="tindakanSection">
<v-table>
<thead>
<tr>
<th>Tindakan</th>
<th style="width: 350px;">Tindakan Tambahan</th>
<th style="width: 130px;" class="text-center">Action</th>
</tr>
</thead>
<tbody>
<!-- Empty State -->
<tr v-if="tindakanItems.length === 0 && !tindakanFormExpanded">
<td colspan="3" class="text-center pa-8">
<div class="text-medium-emphasis">
<Icon icon="solar:medical-kit-outline" height="48" class="mb-2" />
<p class="text-body-2">Tidak ada data tindakan</p>
</div>
</td>
</tr>
<!-- Data Rows -->
<tr v-for="(item, index) in tindakanItems" :key="index">
<td>{{ item.kodeTindakan }} | {{ item.tindakan }}</td>
<td>
<span class="text-body-2 text-medium-emphasis">{{ item.tindakanTambahan || '-'
}}</span>
</td>
<td class="text-center">
<v-btn v-if="!readonly" icon size="small" variant="text" color="error"
@click="deleteTindakan(index)">
<Icon icon="mdi-delete-outline" height="20" />
</v-btn>
</td>
</tr>
<!-- Form Input Row -->
<tr v-if="!readonly && tindakanFormExpanded" class="bg-purple-lighten-5">
<td>
<v-autocomplete ref="tindakanInput"
:model-value="tindakanForm.kodeTindakan && tindakanForm.tindakan ? `${tindakanForm.kodeTindakan} | ${tindakanForm.tindakan}` : ''"
:items="tindakanOptions" placeholder="Cari kode atau tindakan..."
variant="outlined" density="compact" hide-details :loading="loadingTindakan"
no-filter clearable @update:search="handleTindakanSearchInput"
@update:model-value="handleKodeTindakanChange">
<template #append-inner>
<Icon icon="mdi-magnify" height="18" />
</template>
<template #no-data>
<v-list-item>
<v-list-item-title class="text-caption">
{{ tindakanSearchPerformed && tindakanList.length === 0
? 'Data tidak ditemukan' : 'Ketik minimal 3 karakter untuk mencari...' }}
</v-list-item-title>
</v-list-item>
</template>
</v-autocomplete>
</td>
<td>
<v-text-field v-model="tindakanForm.tindakanTambahan"
placeholder="Tindakan Tambahan..." variant="outlined" density="compact"
hide-details></v-text-field>
</td>
<td class="text-center">
<v-btn icon size="small" variant="text" color="grey"
@click="cancelEditTindakan">
<Icon icon="mdi-close" height="20" />
</v-btn>
<v-btn icon size="small" variant="text" color="success" @click="saveTindakan"
:disabled="!tindakanForm.kodeTindakan || !tindakanForm.tindakan">
<Icon icon="mdi-check" height="20" />
</v-btn>
</td>
</tr>
</tbody>
</v-table>
</div>
</v-card-text>
</v-card>
</v-col>
</v-row>
<v-divider> </v-divider>
</template>
+206 -160
View File
@@ -166,7 +166,7 @@ watch(() => props.modelValue, (isOpen) => {
</script>
<template>
<v-dialog v-model="dialog" max-width="1200px" persistent scrollable>
<v-dialog v-model="dialog" max-width="1000px" persistent scrollable>
<v-card>
<v-card-title class="d-flex align-center justify-space-between pa-4">
<div class="d-flex align-center">
@@ -178,7 +178,7 @@ watch(() => props.modelValue, (isOpen) => {
</v-btn>
</v-card-title>
<v-card-text class="pa-5 bg-background" style="max-height: 75vh; overflow-y: auto;">
<v-card-text class="pa-5 bg-background" style="max-height: 70vh; overflow-y: auto;">
<!-- Loading State -->
<div v-if="loading" class="text-center py-8">
<v-progress-circular indeterminate color="primary" size="50"></v-progress-circular>
@@ -198,187 +198,207 @@ watch(() => props.modelValue, (isOpen) => {
<!-- Content -->
<div v-else-if="pasienData">
<v-row>
<v-col cols="6">
<!-- Informasi Pasien -->
<v-card elevation="2" class="mb-4" style="height: 100%;">
<!-- Left Column: Informasi Pasien -->
<v-col cols="12" md="6">
<v-card elevation="0" class="h-100 border">
<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-subtitle-1 font-weight-bold text-uppercase">Informasi Pasien</span>
</div>
</v-card-title>
<v-card-text class="pa-4">
<v-row>
<v-col cols="12" sm="6">
<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>
<v-card-text class="pa-5">
<!-- Nama Pasien -->
<div class="mb-5">
<div class="text-caption text-medium-emphasis text-uppercase mb-2">Nama Pasien</div>
<div class="text-h6 font-weight-bold">
{{ pasienData.formData?.namaPasien || '-' }}
<v-icon
:color="pasienData.formData?.jenisKelamin === 'L' ? 'info' : 'error'"
size="small"
class="ml-1">
{{ pasienData.formData?.jenisKelamin === 'L' ? 'mdi-gender-male' : 'mdi-gender-female' }}
</v-icon>
</div>
</div>
<!-- No Rekam Medis -->
<div class="mb-5">
<div class="text-caption text-medium-emphasis text-uppercase mb-2">No. Rekam Medis</div>
<div class="text-h6 font-weight-bold">
{{ pasienData.formData?.noRekamMedis || '-' }}
</div>
</div>
<!-- Tanggal Daftar -->
<div class="mb-5">
<div class="text-caption text-medium-emphasis text-uppercase mb-2">
<Icon icon="solar:calendar-bold" height="16" class="mr-1" />
Tanggal Daftar
</div>
<div class="text-body-1">
{{ formatDate(pasienData.rencanaOperasiData?.tanggalDaftar) }}
</div>
</div>
<!-- Kategori -->
<div class="mb-5">
<div class="text-caption text-medium-emphasis text-uppercase mb-2">Kategori</div>
<v-chip variant="flat" size="small">
{{ pasienData.rencanaOperasiData?.kategoriName?.split('-')[1]?.trim() || '-' }}
</v-chip>
</div>
<!-- Spesialis / Sub Spesialis -->
<div>
<div class="text-caption text-medium-emphasis text-uppercase mb-2">Spesialis / Sub Spesialis</div>
<div class="row">
<div class="col-md-12">
<v-chip color="primary" class="mb-1 mr-1" variant="flat" size="small">
{{ pasienData.rencanaOperasiData?.SpesialisName || '-' }}
</v-chip>
<span class="text-body-1">/</span>
<v-chip color="secondary" class="mb-1 ml-1" variant="flat" size="small">
{{ pasienData.rencanaOperasiData?.SubSpesialisName || '-' }}
</v-chip>
</div>
</v-col>
<v-col cols="12" sm="6">
<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 || '-' }}
<v-tooltip location="right">
<template #activator="{ props }">
<v-chip v-bind="props"
:color="pasienData.formData?.jenisKelamin === 'L' ? 'primary' : 'error'"
size="small" variant="flat" class="ml-2">
<Icon
:icon="pasienData.formData?.jenisKelamin === 'L' ? 'mdi-gender-male' : 'mdi-gender-female'"
height="14" />
</v-chip>
</template>
{{ pasienData.formData?.jenisKelamin === 'L' ? 'Laki-laki' :
'Perempuan' }}
</v-tooltip>
</div>
</div>
</v-col>
<v-col cols="12" sm="6">
<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="6">
<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?.split('-')[1]?.trim()
|| '-' }}
</v-chip>
</div>
</div>
</v-col>
<v-col cols="12" sm="6">
<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="6">
<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>
</div>
</div>
</v-card-text>
</v-card>
</v-col>
<v-col cols="6">
<!-- Form Update Status -->
<v-card elevation="2" class="mb-2" style="height: 100%;">
<v-card-title class="bg-orange-lighten-5 pa-4">
<!-- Right Column: Update Status Operasi -->
<v-col cols="12" md="6">
<v-card elevation="0" class="h-100 border">
<v-card-title class="bg-blue-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>
<Icon icon="solar:settings-bold-duotone" height="24" class="mr-2 text-primary" />
<span class="text-subtitle-1 font-weight-bold text-uppercase">Update Status Operasi</span>
</div>
</v-card-title>
<v-card-text class="pa-4">
<v-row>
<!-- Status Operasi -->
<v-col cols="12">
<v-row>
<v-col cols="12" sm="12">
<v-btn-group v-model="formData.statusOperasi" mandatory
class="w-100">
<v-btn class="flex-grow-1" size="large"
:variant="formData.statusOperasi === STATUS.BELUM ? 'flat' : 'outlined'"
: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 class="flex-grow-1" size="large"
:variant="formData.statusOperasi === STATUS.SELESAI ? 'flat' : 'outlined'"
: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 class="flex-grow-1" size="large"
:variant="formData.statusOperasi === STATUS.TUNDA ? 'flat' : 'outlined'"
: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 class="flex-grow-1" size="large"
:variant="formData.statusOperasi === STATUS.BATAL ? 'flat' : 'outlined'"
: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>
</v-col>
</v-row>
</v-col>
<v-card-text class="pa-4 pt-3">
<!-- Status Options -->
<v-list class="pa-0" density="compact">
<!-- Belum -->
<v-list-item
@click="formData.statusOperasi = STATUS.BELUM"
:class="formData.statusOperasi === STATUS.BELUM ? 'bg-primary-lighten-5 border-primary' : 'border'"
class="mb-2 rounded-lg pa-2"
style="border-width: 2px; border-style: solid; cursor: pointer; min-height: 50px;">
<template #prepend>
<div class="status-indicator-sm bg-primary mr-2"></div>
<v-avatar color="grey-lighten-3" size="32" class="mr-2">
<Icon icon="mdi-clock-outline" height="20" class="text-primary" />
</v-avatar>
</template>
<v-list-item-title class="font-weight-bold text-body-1">Belum</v-list-item-title>
<v-list-item-subtitle class="text-caption text-body-2">Pasien masih dalam antrian</v-list-item-subtitle>
<template #append>
<v-icon class="mr-5" v-if="formData.statusOperasi === STATUS.BELUM" color="primary" size="small">
mdi-check-circle
</v-icon>
</template>
</v-list-item>
<!-- Tanggal Selesai (shown only when status is Selesai) -->
<v-col v-if="formData.statusOperasi === STATUS.SELESAI" cols="12">
<!-- Selesai -->
<v-list-item
@click="formData.statusOperasi = STATUS.SELESAI"
:class="formData.statusOperasi === STATUS.SELESAI ? 'bg-success-lighten-5 border-success' : 'border'"
class="mb-2 rounded-lg pa-2"
style="border-width: 2px; border-style: solid; cursor: pointer; min-height: 50px;">
<template #prepend>
<div class="status-indicator-sm bg-success mr-2"></div>
<v-avatar color="success-lighten-4" size="32" class="mr-2">
<Icon icon="mdi-check-circle" height="20" class="text-success" />
</v-avatar>
</template>
<v-list-item-title class="font-weight-bold text-body-1">Selesai</v-list-item-title>
<v-list-item-subtitle class="text-caption text-body-2">Operasi telah berhasil dilakukan</v-list-item-subtitle>
<template #append>
<v-icon class="mr-5" v-if="formData.statusOperasi === STATUS.SELESAI" color="success" size="small">
mdi-check-circle
</v-icon>
</template>
</v-list-item>
<!-- Tunda -->
<v-list-item
@click="formData.statusOperasi = STATUS.TUNDA"
:class="formData.statusOperasi === STATUS.TUNDA ? 'bg-warning-lighten-5 border-warning' : 'border'"
class="mb-2 rounded-lg pa-2"
style="border-width: 2px; border-style: solid; cursor: pointer; min-height: 50px;">
<template #prepend>
<div class="status-indicator-sm bg-warning mr-2"></div>
<v-avatar color="warning-lighten-4" size="32" class="mr-2">
<Icon icon="mdi-pause-circle" height="20" class="text-warning" />
</v-avatar>
</template>
<v-list-item-title class="font-weight-bold text-body-1">Tunda</v-list-item-title>
<v-list-item-subtitle class="text-caption text-body-2" >Jadwal diundur karena alasan medis/teknis</v-list-item-subtitle>
<template #append>
<v-icon class="mr-5" v-if="formData.statusOperasi === STATUS.TUNDA" color="warning" size="small">
mdi-check-circle
</v-icon>
</template>
</v-list-item>
<!-- Batal -->
<v-list-item
@click="formData.statusOperasi = STATUS.BATAL"
:class="formData.statusOperasi === STATUS.BATAL ? 'bg-error-lighten-5 border-error' : 'border'"
class="mb-2 rounded-lg pa-2"
style="border-width: 2px; border-style: solid; cursor: pointer; min-height: 50px;">
<template #prepend>
<div class="status-indicator-sm bg-error mr-2"></div>
<v-avatar color="error-lighten-4" size="32" class="mr-2">
<Icon icon="mdi-close-circle" height="20" class="text-error" />
</v-avatar>
</template>
<v-list-item-title class="font-weight-bold text-body-1">Batal</v-list-item-title>
<v-list-item-subtitle class="text-caption text-body-2" >Operasi dibatalkan sepenuhnya</v-list-item-subtitle>
<template #append>
<v-icon class="mr-5" v-if="formData.statusOperasi === STATUS.BATAL" color="error" size="small">
mdi-check-circle
</v-icon>
</template>
</v-list-item>
</v-list>
<!-- Tanggal Selesai (shown only when status is Selesai) -->
<v-expand-transition>
<div v-if="formData.statusOperasi === STATUS.SELESAI" class="mt-4">
<v-label class="mb-2 font-weight-medium">
Tanggal Selesai Operasi <span class="text-error">*</span>
</v-label>
<v-text-field v-model="formData.tanggalSelesai" type="datetime-local"
variant="outlined" density="comfortable" hide-details="auto"
<v-text-field
v-model="formData.tanggalSelesai"
type="datetime-local"
variant="outlined"
density="comfortable"
hide-details="auto"
:min="minTanggalSelesai"
:error-messages="!formData.tanggalSelesai ? ['Tanggal selesai wajib diisi'] : []"></v-text-field>
</v-col>
:error-messages="!formData.tanggalSelesai ? ['Tanggal selesai wajib diisi'] : []">
</v-text-field>
</div>
</v-expand-transition>
<!-- Keterangan (shown only when status is Tunda or Batal) -->
<v-col
v-if="formData.statusOperasi === STATUS.TUNDA || formData.statusOperasi === STATUS.BATAL"
cols="12">
<!-- Keterangan (shown only when status is Tunda or Batal) -->
<v-expand-transition>
<div v-if="formData.statusOperasi === STATUS.TUNDA || formData.statusOperasi === STATUS.BATAL" class="mt-4">
<v-label class="mb-2 font-weight-medium">
Keterangan <span class="text-error">*</span>
</v-label>
<v-textarea v-model="formData.keteranganStatus" variant="outlined" rows="3"
<v-textarea
v-model="formData.keteranganStatus"
variant="outlined"
rows="3"
hide-details="auto"
:placeholder="`Masukkan alasan ${formData.statusOperasi === STATUS.TUNDA ? 'penundaan' : 'pembatalan'} operasi`"
:error-messages="!formData.keteranganStatus.trim() ? ['Keterangan wajib diisi'] : []"></v-textarea>
</v-col>
</v-row>
:error-messages="!formData.keteranganStatus.trim() ? ['Keterangan wajib diisi'] : []">
</v-textarea>
</div>
</v-expand-transition>
</v-card-text>
</v-card>
</v-col>
@@ -423,4 +443,30 @@ watch(() => props.modelValue, (isOpen) => {
color: rgb(var(--v-theme-on-surface));
padding-left: 28px;
}
.status-indicator {
width: 4px;
height: 60px;
border-radius: 4px;
}
.border {
border: 1px solid rgba(0, 0, 0, 0.12);
}
.border-primary {
border-color: rgb(var(--v-theme-primary)) !important;
}
.border-success {
border-color: rgb(var(--v-theme-success)) !important;
}
.border-warning {
border-color: rgb(var(--v-theme-warning)) !important;
}
.border-error {
border-color: rgb(var(--v-theme-error)) !important;
}
</style>