// composables/useQueue.js import { ref, computed } from "vue"; import { useQueueStore } from "../stores/queueStore"; export const useQueue = (adminType = "loket") => { const queueStore = useQueueStore(); // Local state const snackbar = ref(false); const snackbarText = ref(""); const snackbarColor = ref("success"); // Dialog states const showKlinikDialog = ref(false); const showPenunjangDialog = ref(false); const showChangeKlinikDialog = ref(false); const klinikSearch = ref(""); const penunjangSearch = ref(""); const changeKlinikSearch = ref(""); const selectedPatientForPenunjang = ref(null); // FIXED: Get stage patients once, then derive others from it const stagePatients = computed(() => { // Don't use .value here - getPatientsByStage returns a computed already const patients = queueStore.getPatientsByStage(adminType); return patients.value; }); // Computed from store - filtered by stage const currentProcessingPatient = computed(() => { return queueStore.currentProcessingPatient[adminType]; }); // Derive from stagePatients const diLoketPatients = computed(() => stagePatients.value.diLoket || []); const terlambatPatients = computed(() => stagePatients.value.terlambat || []); const pendingPatients = computed(() => stagePatients.value.pending || []); const waitingPatients = computed(() => stagePatients.value.waiting || []); const nextPatient = computed(() => { return waitingPatients.value[0] || null; }); // Total pasien hanya untuk stage admin ini const totalPasien = computed(() => { const total = queueStore.getTotalPasienByStage(adminType); return total.value; }); const quotaUsed = computed(() => queueStore.quotaUsed); // Filtered lists const filteredKliniks = computed(() => { if (!klinikSearch.value) return queueStore.kliniks; return queueStore.kliniks.filter((k) => k.name.toLowerCase().includes(klinikSearch.value.toLowerCase()) ); }); const filteredPenunjangs = computed(() => { if (!penunjangSearch.value) return queueStore.penunjangs; return queueStore.penunjangs.filter((p) => p.name.toLowerCase().includes(penunjangSearch.value.toLowerCase()) ); }); const filteredChangeKliniks = computed(() => { if (!changeKlinikSearch.value) return queueStore.kliniks; return queueStore.kliniks.filter((k) => k.name.toLowerCase().includes(changeKlinikSearch.value.toLowerCase()) ); }); // Methods const showSnackbar = (text, color = "success") => { snackbarText.value = text; snackbarColor.value = color; snackbar.value = true; }; const callNext = () => { const result = queueStore.callNext(adminType); showSnackbar(result.message, result.success ? "success" : "warning"); }; const callMultiplePatients = (count) => { const result = queueStore.callMultiplePatients(count, adminType); showSnackbar(result.message, result.success ? "success" : "warning"); }; const processPatient = (patient, action) => { const result = queueStore.processPatient(patient, action, adminType); let color = "success"; if (action === "terlambat") color = "warning"; else if (action === "pending") color = "info"; showSnackbar(result.message, color); }; const selectKlinik = (klinik) => { const result = queueStore.createAntreanKlinik(klinik, adminType); showSnackbar(result.message, "success"); showKlinikDialog.value = false; }; const selectPenunjang = (penunjang) => { const result = queueStore.createAntreanPenunjang( penunjang, selectedPatientForPenunjang.value, adminType ); showSnackbar(result.message, "success"); showPenunjangDialog.value = false; selectedPatientForPenunjang.value = null; }; const openPenunjangDialog = (patient = null) => { selectedPatientForPenunjang.value = patient; showPenunjangDialog.value = true; }; const changeKlinik = (klinik) => { if (currentProcessingPatient.value) { const result = queueStore.changeKlinik( currentProcessingPatient.value, klinik, adminType ); showSnackbar(result.message, result.success ? "success" : "error"); showChangeKlinikDialog.value = false; } }; const getRowClass = (item) => { if (item.status === "current") { return "text-success font-weight-bold"; } return ""; }; return { // State snackbar, snackbarText, snackbarColor, showKlinikDialog, showPenunjangDialog, showChangeKlinikDialog, klinikSearch, penunjangSearch, changeKlinikSearch, selectedPatientForPenunjang, // Computed currentProcessingPatient, diLoketPatients, terlambatPatients, pendingPatients, waitingPatients, nextPatient, totalPasien, quotaUsed, filteredKliniks, filteredPenunjangs, filteredChangeKliniks, stagePatients, // Methods showSnackbar, callNext, callMultiplePatients, processPatient, selectKlinik, selectPenunjang, openPenunjangDialog, changeKlinik, getRowClass, }; };