Files
web-antrean/components/features/antrean/RuangSelectionDialog.vue
T

262 lines
6.4 KiB
Vue

<template>
<v-dialog v-model="dialogModel" max-width="800px">
<v-card class="dialog-card">
<v-card-title class="dialog-header">
<v-icon class="mr-2">mdi-door-open</v-icon>
<span>Pilih Klinik Ruang</span>
<v-spacer />
<v-btn icon @click="dialogModel = false" size="small" class="close-btn">
<v-icon>mdi-close</v-icon>
</v-btn>
</v-card-title>
<v-card-text class="pa-4">
<!-- Patient Info Card -->
<div v-if="patient" class="patient-card mb-4">
<h4 class="card-title">Informasi Pasien</h4>
<v-row>
<v-col cols="6">
<div class="info-label">Nama</div>
<div class="info-value">{{ patient.namaPasien }}</div>
</v-col>
<v-col cols="6">
<div class="info-label">No. RM</div>
<div class="info-value">{{ patient.noRM }}</div>
</v-col>
</v-row>
</div>
<!-- Search Field -->
<v-text-field
v-model="searchModel"
prepend-inner-icon="mdi-magnify"
label="Cari Klinik Ruang"
variant="outlined"
density="comfortable"
hide-details
class="mb-4 search-field"
/>
<!-- Ruang List with Expansion Panels -->
<v-expansion-panels class="ruang-panels">
<v-expansion-panel
v-for="klinikRuang in filteredRuang"
:key="klinikRuang.id"
class="panel-item"
>
<v-expansion-panel-title class="panel-title">
<div class="d-flex align-center w-100">
<v-chip size="small" color="primary-600" class="mr-2 kode-chip">
{{ klinikRuang.kodeKlinik }}
</v-chip>
<strong class="klinik-name">{{ klinikRuang.namaKlinik }}</strong>
<v-spacer />
<v-chip size="small" variant="outlined" class="count-chip">
{{ klinikRuang.ruangList.length }} Ruang
</v-chip>
</div>
</v-expansion-panel-title>
<v-expansion-panel-text>
<v-list density="compact" class="ruang-list">
<v-list-item
v-for="ruang in klinikRuang.ruangList"
:key="ruang.nomorRuang"
@click="$emit('select', klinikRuang, ruang)"
class="ruang-item"
>
<template #prepend>
<v-icon color="primary-600" size="20">mdi-door</v-icon>
</template>
<v-list-item-title class="ruang-title">
<strong>Ruang {{ ruang.nomorRuang }}</strong> - {{ ruang.namaRuang }}
</v-list-item-title>
<v-list-item-subtitle class="ruang-subtitle">
Screen: {{ ruang.nomorScreen }}
</v-list-item-subtitle>
<template #append>
<v-icon size="20">mdi-chevron-right</v-icon>
</template>
</v-list-item>
</v-list>
</v-expansion-panel-text>
</v-expansion-panel>
</v-expansion-panels>
</v-card-text>
</v-card>
</v-dialog>
</template>
<script setup>
import { computed } from 'vue';
const props = defineProps({
modelValue: {
type: Boolean,
required: true
},
patient: {
type: Object,
default: null
},
ruangList: {
type: Array,
default: () => []
},
searchQuery: {
type: String,
default: ''
}
});
const emit = defineEmits(['update:modelValue', 'update:searchQuery', 'select']);
const dialogModel = computed({
get: () => props.modelValue,
set: (value) => emit('update:modelValue', value)
});
const searchModel = computed({
get: () => props.searchQuery,
set: (value) => emit('update:searchQuery', value)
});
const filteredRuang = computed(() => {
if (!searchModel.value) return props.ruangList;
const search = searchModel.value.toLowerCase();
return props.ruangList.filter(k =>
k.namaKlinik.toLowerCase().includes(search) ||
k.kodeKlinik.toLowerCase().includes(search)
);
});
</script>
<style scoped lang="scss">
$neutral-100: #FFFFFF;
$neutral-300: #F5F7FA;
$neutral-400: #E5F7FA;
$neutral-500: #ABBED1;
$neutral-700: #717171;
$neutral-900: #212121;
$primary-600: #FFA532;
$primary-700: #FF9B1B;
$font-family-base: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
$font-weight-regular: 400;
$font-weight-semibold: 600;
.dialog-card {
font-family: $font-family-base;
}
.dialog-header {
background: linear-gradient(135deg, $primary-600 0%, $primary-700 100%);
color: $neutral-100;
padding: 20px 24px;
font-size: 18px;
font-weight: $font-weight-semibold;
display: flex;
align-items: center;
}
.close-btn {
color: $neutral-100 !important;
}
.patient-card {
background: $neutral-300;
padding: 16px;
border-radius: 12px;
border: 1px solid $neutral-500;
}
.card-title {
font-size: 14px;
font-weight: $font-weight-semibold;
color: $neutral-900;
margin-bottom: 12px;
font-family: $font-family-base;
}
.info-label {
font-size: 12px;
line-height: 16px;
color: $neutral-700;
margin-bottom: 4px;
font-family: $font-family-base;
}
.info-value {
font-size: 14px;
line-height: 20px;
font-weight: $font-weight-semibold;
color: $neutral-900;
font-family: $font-family-base;
}
.search-field {
font-family: $font-family-base;
}
.ruang-panels {
font-family: $font-family-base;
}
.panel-item {
margin-bottom: 8px;
border: 1px solid $neutral-500;
border-radius: 8px;
}
.panel-title {
font-family: $font-family-base;
}
.kode-chip {
font-weight: $font-weight-semibold;
font-size: 12px;
}
.klinik-name {
font-size: 14px;
font-weight: $font-weight-semibold;
color: $neutral-900;
font-family: $font-family-base;
}
.count-chip {
font-size: 12px;
font-family: $font-family-base;
}
.ruang-list {
padding: 0;
}
.ruang-item {
cursor: pointer;
border-radius: 8px;
margin-bottom: 4px;
transition: background 0.2s;
font-family: $font-family-base;
}
.ruang-item:hover {
background: $neutral-300;
}
.ruang-title {
font-size: 14px;
font-weight: $font-weight-semibold;
color: $neutral-900;
font-family: $font-family-base;
}
.ruang-subtitle {
font-size: 12px;
color: $neutral-700;
font-family: $font-family-base;
}
</style>