183 lines
5.0 KiB
JavaScript
183 lines
5.0 KiB
JavaScript
// 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,
|
|
};
|
|
}; |