update flow pasien, store & preview screen, source klinik, api dokter

This commit is contained in:
bagus-arie05
2025-12-18 14:22:15 +07:00
parent d2a51f3aee
commit dfcd59481c
18 changed files with 984 additions and 183 deletions

No files matched your search

+117
View File
@@ -61,6 +61,18 @@
</div>
</template>
<template v-slot:item.layarInformasi="{ item }">
<v-btn
size="small"
@click="openPreviewDialog(item)"
variant="flat"
class="btn-preview mr-2"
>
<v-icon size="16" left>mdi-eye</v-icon>
Preview
</v-btn>
</template>
<template v-slot:item.actions="{ item }">
<v-btn
size="small"
@@ -182,6 +194,35 @@
</v-card>
</v-dialog>
<!-- Preview Dialog -->
<v-dialog v-model="previewDialog" max-width="95vw" max-height="95vh" persistent>
<v-card class="preview-dialog-card">
<v-card-title class="preview-dialog-header">
<div class="preview-header-content">
<v-icon size="24" class="mr-2">mdi-monitor-dashboard</v-icon>
<span class="headline-4">Preview Anjungan: {{ previewItem?.namaAnjungan || '' }}</span>
</div>
<v-btn icon variant="text" size="small" class="btn-close" @click="closePreviewDialog">
<v-icon>mdi-close</v-icon>
</v-btn>
</v-card-title>
<v-divider></v-divider>
<v-card-text class="preview-content">
<iframe
v-if="previewUrl"
:src="previewUrl"
class="preview-iframe"
frameborder="0"
allowfullscreen
></iframe>
<div v-else class="preview-loading">
<v-progress-circular indeterminate color="primary"></v-progress-circular>
<p class="mt-4">Memuat preview...</p>
</div>
</v-card-text>
</v-card>
</v-dialog>
<v-snackbar v-model="snackbar.show" :color="snackbar.color" :timeout="3000">
<span class="body-3">{{ snackbar.message }}</span>
<template v-slot:actions>
@@ -204,6 +245,9 @@ const clinicStore = useClinicStore();
const dialog = ref(false);
const isEdit = ref(false);
const formRef = ref(null);
const previewDialog = ref(false);
const previewItem = ref(null);
const previewUrl = ref('');
const snackbar = ref({
show: false,
@@ -216,6 +260,7 @@ const headers = ref([
{ title: 'Nama Anjungan', value: 'namaAnjungan', sortable: true },
{ title: 'Jenis Pasien', value: 'jenisPasien', sortable: false },
{ title: 'Klinik Ditampilkan', value: 'klinik', sortable: false },
{ title: 'Layar Informasi', value: 'layarInformasi', sortable: false, width: '150px' },
{ title: 'Actions', value: 'actions', sortable: false, width: 'auto' },
]);
@@ -296,6 +341,19 @@ const handleDelete = (item) => {
};
}
};
const openPreviewDialog = (item) => {
previewItem.value = item;
// Generate preview URL untuk anjungan dengan ID
previewUrl.value = `/anjungan/anjungan/${item.id}`;
previewDialog.value = true;
};
const closePreviewDialog = () => {
previewDialog.value = false;
previewItem.value = null;
previewUrl.value = '';
};
</script>
<style scoped lang="scss">
@@ -543,5 +601,64 @@ $font-weight-semibold: 600;
line-height: 24px;
min-width: 100px;
}
// ============================================
// PREVIEW DIALOG
// ============================================
.btn-preview {
background-color: $success-600 !important;
color: $neutral-100 !important;
text-transform: none;
font-weight: $font-weight-semibold;
font-size: 14px;
line-height: 20px;
}
.preview-dialog-card {
font-family: $font-family-base;
height: 95vh;
display: flex;
flex-direction: column;
}
.preview-dialog-header {
background: linear-gradient(135deg, $secondary-600 0%, $secondary-700 100%);
color: $neutral-100;
padding: 16px 24px;
display: flex;
justify-content: space-between;
align-items: center;
}
.preview-header-content {
display: flex;
align-items: center;
}
.preview-content {
padding: 0 !important;
flex: 1;
display: flex;
align-items: center;
justify-content: center;
background: $neutral-800;
overflow: hidden;
}
.preview-iframe {
width: 100%;
height: 100%;
min-height: 80vh;
border: none;
}
.preview-loading {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
color: $neutral-100;
padding: 40px;
}
</style>
+117
View File
@@ -50,6 +50,18 @@
<span class="ml-2 body-3 text-medium">{{ item.namaKlinik }}</span>
</template>
<template v-slot:item.layarInformasi="{ item }">
<v-btn
size="small"
@click="openPreviewDialog(item)"
variant="flat"
class="btn-preview mr-2"
>
<v-icon size="16" left>mdi-eye</v-icon>
Preview
</v-btn>
</template>
<template v-slot:item.aksi="{ item }">
<v-btn
size="small"
@@ -223,6 +235,35 @@
</v-card>
</v-dialog>
<!-- Preview Dialog -->
<v-dialog v-model="previewDialog" max-width="95vw" max-height="95vh" persistent>
<v-card class="preview-dialog-card">
<v-card-title class="preview-dialog-header">
<div class="preview-header-content">
<v-icon size="24" class="mr-2">mdi-door-open</v-icon>
<span class="headline-4">Preview Klinik Ruang: {{ previewItem?.namaKlinik || '' }}</span>
</div>
<v-btn icon variant="text" size="small" class="btn-close" @click="closePreviewDialog">
<v-icon>mdi-close</v-icon>
</v-btn>
</v-card-title>
<v-divider></v-divider>
<v-card-text class="preview-content">
<iframe
v-if="previewUrl"
:src="previewUrl"
class="preview-iframe"
frameborder="0"
allowfullscreen
></iframe>
<div v-else class="preview-loading">
<v-progress-circular indeterminate color="primary"></v-progress-circular>
<p class="mt-4">Memuat preview...</p>
</div>
</v-card-text>
</v-card>
</v-dialog>
<!-- Snackbar -->
<v-snackbar v-model="snackbar.show" :color="snackbar.color" :timeout="3000">
<span class="body-3">{{ snackbar.message }}</span>
@@ -241,6 +282,9 @@ const masterStore = useMasterStore();
const dialog = ref(false);
const isEdit = ref(false);
const formRef = ref(null);
const previewDialog = ref(false);
const previewItem = ref(null);
const previewUrl = ref('');
const snackbar = ref({
show: false,
@@ -253,6 +297,7 @@ const headers = ref([
{ title: 'Nama Klinik', value: 'namaKlinik', sortable: true },
{ title: 'Kode', value: 'kodeKlinik', sortable: true },
{ title: 'Nama Ruang', value: 'namaRuang', sortable: true },
{ title: 'Layar Informasi', value: 'layarInformasi', sortable: false, width: '150px' },
{ title: 'Aksi', value: 'aksi', sortable: false },
]);
@@ -361,6 +406,19 @@ const handleDelete = (item) => {
};
}
};
const openPreviewDialog = (item) => {
previewItem.value = item;
// Generate preview URL untuk klinik ruang menggunakan kodeKlinik
previewUrl.value = `/anjungan/antrianklinikruang/${item.kodeKlinik}`;
previewDialog.value = true;
};
const closePreviewDialog = () => {
previewDialog.value = false;
previewItem.value = null;
previewUrl.value = '';
};
</script>
<style scoped lang="scss">
@@ -648,6 +706,65 @@ $font-weight-semibold: 600;
min-width: 100px;
}
// ============================================
// PREVIEW DIALOG
// ============================================
.btn-preview {
background-color: $secondary-600 !important;
color: $neutral-100 !important;
text-transform: none;
font-weight: $font-weight-semibold;
font-size: 14px;
line-height: 20px;
}
.preview-dialog-card {
font-family: $font-family-base;
height: 95vh;
display: flex;
flex-direction: column;
}
.preview-dialog-header {
background: linear-gradient(135deg, $success-600 0%, $success-700 100%);
color: $neutral-100;
padding: 16px 24px;
display: flex;
justify-content: space-between;
align-items: center;
}
.preview-header-content {
display: flex;
align-items: center;
}
.preview-content {
padding: 0 !important;
flex: 1;
display: flex;
align-items: center;
justify-content: center;
background: $neutral-800;
overflow: hidden;
}
.preview-iframe {
width: 100%;
height: 100%;
min-height: 80vh;
border: none;
}
.preview-loading {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
color: $neutral-100;
padding: 40px;
}
// ============================================
// RESPONSIVE
// ============================================
+117
View File
@@ -57,6 +57,18 @@
</div>
</template>
<template v-slot:item.layarInformasi="{ item }">
<v-btn
size="small"
@click="openPreviewDialog(item)"
variant="flat"
class="btn-preview mr-2"
>
<v-icon size="16" left>mdi-eye</v-icon>
Preview
</v-btn>
</template>
<template v-slot:item.actions="{ item }">
<v-btn
size="small"
@@ -214,6 +226,35 @@
</v-card>
</v-dialog>
<!-- Preview Dialog -->
<v-dialog v-model="previewDialog" max-width="95vw" max-height="95vh" persistent>
<v-card class="preview-dialog-card">
<v-card-title class="preview-dialog-header">
<div class="preview-header-content">
<v-icon size="24" class="mr-2">mdi-monitor</v-icon>
<span class="headline-4">Preview Screen: {{ previewItem?.namaScreen || '' }}</span>
</div>
<v-btn icon variant="text" size="small" class="btn-close" @click="closePreviewDialog">
<v-icon>mdi-close</v-icon>
</v-btn>
</v-card-title>
<v-divider></v-divider>
<v-card-text class="preview-content">
<iframe
v-if="previewUrl"
:src="previewUrl"
class="preview-iframe"
frameborder="0"
allowfullscreen
></iframe>
<div v-else class="preview-loading">
<v-progress-circular indeterminate color="primary"></v-progress-circular>
<p class="mt-4">Memuat preview...</p>
</div>
</v-card-text>
</v-card>
</v-dialog>
<!-- Snackbar -->
<v-snackbar v-model="snackbar.show" :color="snackbar.color" :timeout="3000">
<span class="body-3">{{ snackbar.message }}</span>
@@ -234,6 +275,9 @@ const screenStore = useScreenStore();
const dialog = ref(false);
const isEdit = ref(false);
const formRef = ref(null);
const previewDialog = ref(false);
const previewItem = ref(null);
const previewUrl = ref('');
const snackbar = ref({
show: false,
@@ -246,6 +290,7 @@ const headers = ref([
{ title: "Nama Screen", value: "namaScreen", sortable: true },
{ title: "Nomor Screen", value: "nomorScreen", sortable: true },
{ title: "Klinik Ditampilkan", value: "klinik", sortable: false },
{ title: "Layar Informasi", value: "layarInformasi", sortable: false, width: "150px" },
{ title: "Actions", value: "actions", sortable: false, width: "auto" },
]);
@@ -328,6 +373,19 @@ const handleDelete = (item) => {
};
}
};
const openPreviewDialog = (item) => {
previewItem.value = item;
// Generate preview URL untuk screen dengan ID
previewUrl.value = `/anjungan/antrianklinik/${item.id}`;
previewDialog.value = true;
};
const closePreviewDialog = () => {
previewDialog.value = false;
previewItem.value = null;
previewUrl.value = '';
};
</script>
<style scoped lang="scss">
@@ -634,4 +692,63 @@ $font-weight-semibold: 600;
line-height: 24px;
min-width: 100px;
}
// ============================================
// PREVIEW DIALOG
// ============================================
.btn-preview {
background-color: $success-600 !important;
color: $neutral-100 !important;
text-transform: none;
font-weight: $font-weight-semibold;
font-size: 14px;
line-height: 20px;
}
.preview-dialog-card {
font-family: $font-family-base;
height: 95vh;
display: flex;
flex-direction: column;
}
.preview-dialog-header {
background: linear-gradient(135deg, $secondary-600 0%, $secondary-700 100%);
color: $neutral-100;
padding: 16px 24px;
display: flex;
justify-content: space-between;
align-items: center;
}
.preview-header-content {
display: flex;
align-items: center;
}
.preview-content {
padding: 0 !important;
flex: 1;
display: flex;
align-items: center;
justify-content: center;
background: $neutral-800;
overflow: hidden;
}
.preview-iframe {
width: 100%;
height: 100%;
min-height: 80vh;
border: none;
}
.preview-loading {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
color: $neutral-100;
padding: 40px;
}
</style>