feat: implement Grand Paviliun dashboard with specialized room monitoring, queue management, and modular components

This commit is contained in:
Fanrouver
2026-07-10 09:42:30 +07:00
parent 61772105fd
commit d0eee7d062
14 changed files with 1052 additions and 44 deletions

No files matched your search

+57 -17
View File
@@ -875,11 +875,10 @@ const fetchPatientsForLoket = async (loketId: string | number, force: boolean =
(loket?.namaLoket || '').toUpperCase().includes('EKSEKUTIF');
if (isEksekutif) {
// Return EKSEKUTIF patients from seed data
// Return EKSEKUTIF patients assigned to this loket
return allPatients.value.filter(p => {
const isPembayaranEksekutif = (p.pembayaran || '').toUpperCase().includes('EKSEKUTIF') ||
(p.pembayaran || '').toUpperCase().includes('VIP');
return isPembayaranEksekutif && p.processStage === 'loket';
const isMatchingLoket = String(p.loketId) === String(loketId);
return p.processStage === 'loket' && isMatchingLoket;
});
}
@@ -1485,6 +1484,20 @@ const fetchPatientsForLoket = async (loketId: string | number, force: boolean =
// Enforce clinic mapping (pelayanan)
if (thisLoket && thisLoket.pelayanan && Array.isArray(thisLoket.pelayanan)) {
if (thisLoket.pelayanan.includes(p.kodeKlinik)) {
// Bypass payment check for Eksekutif patients
const isPatientEksekutif = p.noAntrian && (p.noAntrian.startsWith('E') || p.noAntrian.startsWith('F-E'));
const isLoketEksekutif = thisLoket.tipeLoket === 'EKSEKUTIF' || thisLoket.id >= 1000;
if (isPatientEksekutif && isLoketEksekutif) {
return true;
}
if (!isPatientEksekutif && isLoketEksekutif) {
return false;
}
if (isPatientEksekutif && !isLoketEksekutif) {
return false;
}
// NEW: Check payment compatibility
if (!isPaymentCompatible(p.pembayaran, thisLoket.pembayaran)) {
return false;
@@ -2609,11 +2622,22 @@ const fetchPatientsForLoket = async (loketId: string | number, force: boolean =
let targetLoketName = oldPatient.loket;
if (newKlinik.kode) {
const isEksekutif = (oldPatient.pembayaran || '').toUpperCase().includes('EKSEKUTIF') ||
(oldPatient.pembayaran || '').toUpperCase().includes('VIP');
const allLokets = loketStore.lokets || [];
const foundLoket = allLokets.find(l =>
l.pelayanan && Array.isArray(l.pelayanan) &&
(l.pelayanan.includes(newKlinik.kode) || l.pelayanan.includes(newKlinik.kode?.split('-')[0]))
);
const foundLoket = allLokets.find(l => {
const handlesClinic = l.pelayanan && Array.isArray(l.pelayanan) &&
(l.pelayanan.includes(newKlinik.kode) || l.pelayanan.includes(newKlinik.kode?.split('-')[0]));
if (!handlesClinic) return false;
if (isEksekutif) {
return l.id >= 1000 || l.tipeLoket === 'EKSEKUTIF';
} else {
return l.id < 1000 && l.tipeLoket !== 'EKSEKUTIF';
}
});
if (foundLoket) {
targetLoketId = foundLoket.id;
@@ -2782,15 +2806,31 @@ const fetchPatientsForLoket = async (loketId: string | number, force: boolean =
// fulfill requirement: "adjust based on loket id depending on creation"
if (!newPatient.loketId && newPatient.kodeKlinik) {
const allLokets = loketStore.lokets || [];
const targetLoket = allLokets.find(l =>
l.pelayanan && Array.isArray(l.pelayanan) &&
(l.pelayanan.includes(newPatient.kodeKlinik) || l.pelayanan.includes(newPatient.kodeKlinik?.split('-')[0]))
);
if (targetLoket) {
newPatient.loketId = targetLoket.id;
if (!newPatient.loket) newPatient.loket = targetLoket.namaLoket;
console.log(`✅ Auto-assigned Onsite Ticket ${newPatient.noAntrian} to Loket ${targetLoket.id} (${targetLoket.namaLoket})`);
if (isEksekutif) {
const targetLoket = allLokets.find(l =>
l.pelayanan && Array.isArray(l.pelayanan) &&
(l.pelayanan.includes(newPatient.kodeKlinik) || l.pelayanan.includes(newPatient.kodeKlinik?.split('-')[0])) &&
(l.id >= 1000 || l.tipeLoket === 'EKSEKUTIF')
);
if (targetLoket) {
newPatient.loketId = targetLoket.id;
if (!newPatient.loket) newPatient.loket = targetLoket.namaLoket;
console.log(`✅ Auto-assigned Eksekutif Ticket ${newPatient.noAntrian} to Loket ${targetLoket.id} (${targetLoket.namaLoket})`);
} else {
console.warn(`⚠️ Warning: No Eksekutif Loket found for clinic ${newPatient.kodeKlinik}. Ticket will not be routed to any loket.`);
}
} else {
const targetLoket = allLokets.find(l =>
l.pelayanan && Array.isArray(l.pelayanan) &&
(l.pelayanan.includes(newPatient.kodeKlinik) || l.pelayanan.includes(newPatient.kodeKlinik?.split('-')[0]))
);
if (targetLoket) {
newPatient.loketId = targetLoket.id;
if (!newPatient.loket) newPatient.loket = targetLoket.namaLoket;
console.log(`✅ Auto-assigned Onsite Ticket ${newPatient.noAntrian} to Loket ${targetLoket.id} (${targetLoket.namaLoket})`);
}
}
}