Files
web-antrean/pages/AdminLoket.vue
T

215 lines
5.4 KiB
Vue

<template>
<div class="loket-container">
<!-- Compact Header -->
<PageHeader
icon="mdi-view-dashboard"
title="Admin Loket"
:subtitle="currentDate"
:show-add-button="false"
theme="primary"
/>
<!-- Main Content Grid -->
<v-row class="content-grid" dense>
<!-- Left Column: Current Patient & Queue Actions -->
<v-col cols="12" md="5">
<!-- Current Patient Card -->
<CurrentPatientCard
:patient="currentProcessingPatient"
@action="handlePatientAction"
@change-klinik="showChangeKlinikDialog = true"
/>
<!-- Queue Actions Card -->
<QueueActionsCard
class="mt-3"
:total-quota="150"
:used-quota="quotaUsed"
:has-next="!!nextPatient"
@call="handleCall"
/>
<!-- Create Queue Buttons -->
<div class="create-buttons mt-3">
<v-btn
color="primary-600"
variant="flat"
block
size="large"
class="mb-2"
@click="showKlinikDialog = true"
>
<v-icon start size="20">mdi-hospital-building</v-icon>
Buat Antrean Klinik
</v-btn>
<v-btn
color="secondary-600"
variant="flat"
block
size="large"
class="text-white"
@click="openPenunjangDialog()"
>
<v-icon start size="20">mdi-clipboard-pulse</v-icon>
Buat Antrean Penunjang
</v-btn>
</div>
</v-col>
<!-- Right Column: Patient Table -->
<v-col cols="12" md="7">
<PatientDataTable
:items="allPatients"
v-model:selected-status="selectedStatus"
v-model:search-query="searchQuery"
:di-loket-count="(diLoketPatients || []).length"
:terlambat-count="(terlambatPatients || []).length"
:pending-count="(pendingPatients || []).length"
@action="handleTableAction"
/>
</v-col>
</v-row>
<!-- Klinik Dialog -->
<SelectionDialog
v-model="showKlinikDialog"
title="Pilih Klinik"
:items="filteredKliniks"
v-model:search-query="klinikSearch"
search-placeholder="Cari klinik..."
@select="selectKlinik"
/>
<!-- Penunjang Dialog -->
<SelectionDialog
v-model="showPenunjangDialog"
title="Pilih Penunjang"
:items="filteredPenunjangs"
v-model:search-query="penunjangSearch"
search-placeholder="Cari penunjang..."
@select="selectPenunjang"
/>
<!-- Change Klinik Dialog -->
<SelectionDialog
v-model="showChangeKlinikDialog"
title="Ubah Klinik"
:items="filteredChangeKliniks"
v-model:search-query="changeKlinikSearch"
search-placeholder="Cari klinik..."
@select="changeKlinik"
/>
<!-- Snackbar -->
<AppSnackbar
v-model="snackbar"
:message="snackbarText"
:color="snackbarColor"
/>
</div>
</template>
<script setup>
import { ref, computed } from "vue";
import { useQueue } from "@/composables/useQueue";
import PageHeader from "@/components/common/PageHeader.vue";
import CurrentPatientCard from "@/components/features/queue/CurrentPatientCard.vue";
import QueueActionsCard from "@/components/features/queue/QueueActionsCard.vue";
import PatientDataTable from "@/components/features/queue/TabelPatientData.vue";
import SelectionDialog from "@/components/common/SelectionDialog.vue";
import AppSnackbar from "@/components/common/AppSnackbar.vue";
const {
snackbar,
snackbarText,
snackbarColor,
showKlinikDialog,
showPenunjangDialog,
showChangeKlinikDialog,
klinikSearch,
penunjangSearch,
changeKlinikSearch,
currentProcessingPatient,
diLoketPatients,
terlambatPatients,
pendingPatients,
nextPatient,
quotaUsed,
filteredKliniks,
filteredPenunjangs,
filteredChangeKliniks,
callNext,
callMultiplePatients,
processPatient,
selectKlinik,
selectPenunjang,
openPenunjangDialog,
changeKlinik,
} = useQueue("loket");
const currentDate = ref(
new Date().toLocaleDateString("id-ID", {
weekday: "long",
day: "numeric",
month: "long",
year: "numeric",
})
);
const selectedStatus = ref("all");
const searchQuery = ref("");
// Combine all patients with status
const allPatients = computed(() => {
const diLoket = (diLoketPatients.value || []).map(p => ({ ...p, status: 'diloket' }));
const terlambat = (terlambatPatients.value || []).map(p => ({ ...p, status: 'terlambat' }));
const pending = (pendingPatients.value || []).map(p => ({ ...p, status: 'pending' }));
return [...diLoket, ...terlambat, ...pending];
});
const handlePatientAction = (action) => {
if (currentProcessingPatient.value) {
processPatient(currentProcessingPatient.value, action);
}
};
const handleCall = (count) => {
if (count === 1) {
callNext();
} else {
callMultiplePatients(count);
}
};
const handleTableAction = (item, action) => {
processPatient(item, action);
};
</script>
<style scoped lang="scss">
.loket-container {
background: var(--color-neutral-300);
min-height: 100vh;
padding: 16px;
}
.content-grid {
margin: 0 -8px;
}
.content-grid > .v-col {
padding: 8px;
}
.create-buttons .v-btn {
text-transform: none;
font-weight: 600;
}
@media (max-width: 960px) {
.loket-container {
padding: 12px;
}
}
</style>