955 lines
30 KiB
JavaScript
955 lines
30 KiB
JavaScript
// stores/clinicStore.js
|
|
import { defineStore } from 'pinia';
|
|
import { ref, computed } from 'vue';
|
|
|
|
export const useClinicStore = defineStore('clinic', () => {
|
|
console.log('🏪 Initializing clinicStore...');
|
|
|
|
// Data clinics - Single source of truth untuk semua data klinik
|
|
// Includes basic info (name, kode, icon, doctors, shifts) + master config (totalQuota, jamShiftPerHari, jadwalKlinik, tanggalTutup)
|
|
// jenisLayanan: "Reguler" (from API) or "Eksekutif" (seed data)
|
|
const clinics = ref([
|
|
// EKSEKUTIF SEED DATA - keeping for backwards compatibility
|
|
{
|
|
id: 1000,
|
|
kode: "AK",
|
|
name: "ANAK",
|
|
subtitle: "",
|
|
icon: "mdi-baby-face",
|
|
shift: "1 SHIFT",
|
|
schedule: "Mulai Pukul 07:00",
|
|
available: true,
|
|
doctors: ["dr. Sarah Putri, Sp.A", "dr. Andi Wijaya, Sp.A"],
|
|
shifts: [],
|
|
totalQuota: 3000,
|
|
jamShiftPerHari: {
|
|
'Senin': [{ dari: '07:00', sampai: '11:00', kuota: 1000 }],
|
|
'Rabu': [{ dari: '07:00', sampai: '11:00', kuota: 1000 }],
|
|
'Jumat': [{ dari: '07:00', sampai: '11:00', kuota: 1000 }]
|
|
},
|
|
jamShiftList: [],
|
|
autoShift: false,
|
|
jadwalKlinik: ['Senin', 'Rabu', 'Jumat'],
|
|
tanggalTutup: [],
|
|
jenisLayanan: "Eksekutif",
|
|
},
|
|
{
|
|
id: 1001,
|
|
kode: "AN",
|
|
name: "ANESTESI",
|
|
subtitle: "",
|
|
icon: "mdi-face-mask",
|
|
shift: "2 SHIFT",
|
|
schedule: "Mulai Pukul 07:00",
|
|
available: true,
|
|
doctors: ["dr. Ahmad Fauzi, Sp.An"],
|
|
shifts: [],
|
|
totalQuota: 7500,
|
|
jamShiftPerHari: {
|
|
'Senin': [
|
|
{ dari: '07:00', sampai: '11:00', kuota: 1000 },
|
|
{ dari: '13:00', sampai: '16:00', kuota: 500 }
|
|
],
|
|
'Selasa': [
|
|
{ dari: '07:00', sampai: '11:00', kuota: 1000 },
|
|
{ dari: '13:00', sampai: '16:00', kuota: 500 }
|
|
],
|
|
'Rabu': [
|
|
{ dari: '07:00', sampai: '11:00', kuota: 1000 },
|
|
{ dari: '13:00', sampai: '16:00', kuota: 500 }
|
|
],
|
|
'Kamis': [
|
|
{ dari: '07:00', sampai: '11:00', kuota: 1000 },
|
|
{ dari: '13:00', sampai: '16:00', kuota: 500 }
|
|
],
|
|
'Jum\'at': [
|
|
{ dari: '07:00', sampai: '11:00', kuota: 1000 },
|
|
{ dari: '13:00', sampai: '16:00', kuota: 500 }
|
|
]
|
|
},
|
|
jamShiftList: [],
|
|
autoShift: false,
|
|
jadwalKlinik: ['Senin', 'Selasa', 'Rabu', 'Kamis', 'Jum\'at'],
|
|
tanggalTutup: [],
|
|
jenisLayanan: "Eksekutif",
|
|
},
|
|
{
|
|
id: 1002,
|
|
kode: "BD",
|
|
name: "BEDAH",
|
|
subtitle: "",
|
|
icon: "mdi-medical-bag",
|
|
shift: "1 SHIFT",
|
|
schedule: "Mulai Pukul 07:00",
|
|
available: true,
|
|
doctors: ["dr. Budi Santoso, Sp.B", "dr. Eko Prasetyo, Sp.B", "dr. Dian Permata, Sp.B"],
|
|
shifts: [],
|
|
totalQuota: 2400,
|
|
jamShiftPerHari: {
|
|
'Senin': [{ dari: '07:00', sampai: '11:00', kuota: 800 }],
|
|
'Rabu': [{ dari: '07:00', sampai: '11:00', kuota: 800 }],
|
|
'Jumat': [{ dari: '07:00', sampai: '11:00', kuota: 800 }]
|
|
},
|
|
jamShiftList: [],
|
|
autoShift: false,
|
|
jadwalKlinik: ['Senin', 'Rabu', 'Jumat'],
|
|
tanggalTutup: [],
|
|
jenisLayanan: "Eksekutif",
|
|
},
|
|
{
|
|
id: 1003,
|
|
kode: "GM",
|
|
name: "GIGI DAN MULUT",
|
|
subtitle: "",
|
|
icon: "mdi-tooth",
|
|
shift: "3 SHIFT",
|
|
schedule: "Mulai Pukul 07:00",
|
|
available: true,
|
|
doctors: ["drg. Rina Wati, Sp.KG", "drg. Made Surya, Sp.KG"],
|
|
shifts: [],
|
|
totalQuota: 10500,
|
|
jamShiftPerHari: {
|
|
'Senin': [
|
|
{ dari: '07:00', sampai: '11:00', kuota: 1000 },
|
|
{ dari: '13:00', sampai: '16:00', kuota: 700 },
|
|
{ dari: '18:00', sampai: '20:00', kuota: 400 }
|
|
],
|
|
'Selasa': [
|
|
{ dari: '07:00', sampai: '11:00', kuota: 1000 },
|
|
{ dari: '13:00', sampai: '16:00', kuota: 700 },
|
|
{ dari: '18:00', sampai: '20:00', kuota: 400 }
|
|
],
|
|
'Rabu': [
|
|
{ dari: '07:00', sampai: '11:00', kuota: 1000 },
|
|
{ dari: '13:00', sampai: '16:00', kuota: 700 },
|
|
{ dari: '18:00', sampai: '20:00', kuota: 400 }
|
|
],
|
|
'Kamis': [
|
|
{ dari: '07:00', sampai: '11:00', kuota: 1000 },
|
|
{ dari: '13:00', sampai: '16:00', kuota: 700 },
|
|
{ dari: '18:00', sampai: '20:00', kuota: 400 }
|
|
],
|
|
'Jum\'at': [
|
|
{ dari: '07:00', sampai: '11:00', kuota: 1000 },
|
|
{ dari: '13:00', sampai: '16:00', kuota: 700 },
|
|
{ dari: '18:00', sampai: '20:00', kuota: 400 }
|
|
]
|
|
},
|
|
jamShiftList: [],
|
|
autoShift: true,
|
|
jadwalKlinik: ['Senin', 'Selasa', 'Rabu', 'Kamis', 'Jum\'at'],
|
|
tanggalTutup: [],
|
|
jenisLayanan: "Eksekutif",
|
|
},
|
|
{
|
|
id: 1004,
|
|
kode: "GR",
|
|
name: "GERIATRI",
|
|
subtitle: "",
|
|
icon: "mdi-human-cane",
|
|
shift: "1 SHIFT",
|
|
schedule: "Mulai Pukul 07:00",
|
|
available: true,
|
|
doctors: ["dr. Siti Aminah, Sp.PD-KGer"],
|
|
shifts: [],
|
|
totalQuota: 1800,
|
|
jamShiftPerHari: {
|
|
'Senin': [{ dari: '07:00', sampai: '11:00', kuota: 600 }],
|
|
'Rabu': [{ dari: '07:00', sampai: '11:00', kuota: 600 }],
|
|
'Jumat': [{ dari: '07:00', sampai: '11:00', kuota: 600 }]
|
|
},
|
|
jamShiftList: [],
|
|
autoShift: false,
|
|
jadwalKlinik: ['Senin', 'Rabu', 'Jumat'],
|
|
tanggalTutup: [],
|
|
jenisLayanan: "Eksekutif",
|
|
},
|
|
{
|
|
id: 1005,
|
|
kode: "GZ",
|
|
name: "GIZI",
|
|
subtitle: "",
|
|
icon: "mdi-food-apple",
|
|
shift: "1 SHIFT",
|
|
schedule: "Mulai Pukul 07:00",
|
|
available: true,
|
|
doctors: ["dr. Lisa Andriani, Sp.GK"],
|
|
shifts: [],
|
|
totalQuota: 1500,
|
|
jamShiftPerHari: {
|
|
'Senin': [{ dari: '07:00', sampai: '11:00', kuota: 500 }],
|
|
'Rabu': [{ dari: '07:00', sampai: '11:00', kuota: 500 }],
|
|
'Jumat': [{ dari: '07:00', sampai: '11:00', kuota: 500 }]
|
|
},
|
|
jamShiftList: [],
|
|
autoShift: false,
|
|
jadwalKlinik: ['Senin', 'Rabu', 'Jumat'],
|
|
tanggalTutup: [],
|
|
jenisLayanan: "Eksekutif",
|
|
},
|
|
{
|
|
id: 1006,
|
|
kode: "HO",
|
|
name: "HOM",
|
|
subtitle: "",
|
|
icon: "mdi-water",
|
|
shift: "1 SHIFT",
|
|
schedule: "",
|
|
available: false,
|
|
doctors: [],
|
|
shifts: [],
|
|
totalQuota: 2250,
|
|
jamShiftPerHari: {
|
|
'Senin': [{ dari: '07:00', sampai: '11:00', kuota: 750 }],
|
|
'Selasa': [{ dari: '07:00', sampai: '11:00', kuota: 750 }],
|
|
'Rabu': [{ dari: '07:00', sampai: '11:00', kuota: 750 }]
|
|
},
|
|
jamShiftList: [],
|
|
autoShift: false,
|
|
jadwalKlinik: ['Senin', 'Selasa', 'Rabu'],
|
|
tanggalTutup: [],
|
|
jenisLayanan: "Eksekutif",
|
|
},
|
|
{
|
|
id: 1007,
|
|
kode: "IP",
|
|
name: "IPD",
|
|
subtitle: "",
|
|
icon: "mdi-hospital",
|
|
shift: "1 SHIFT",
|
|
schedule: "Mulai Pukul 07:00",
|
|
available: true,
|
|
doctors: ["dr. Hendra Wijaya, Sp.PD", "dr. Agus Salim, Sp.PD", "dr. Retno Wulan, Sp.PD", "dr. Bambang Susilo, Sp.PD"],
|
|
shifts: [],
|
|
totalQuota: 2700,
|
|
jamShiftPerHari: {
|
|
'Senin': [{ dari: '07:00', sampai: '11:00', kuota: 900 }],
|
|
'Rabu': [{ dari: '07:00', sampai: '11:00', kuota: 900 }],
|
|
'Jumat': [{ dari: '07:00', sampai: '11:00', kuota: 900 }]
|
|
},
|
|
jamShiftList: [],
|
|
autoShift: false,
|
|
jadwalKlinik: ['Senin', 'Rabu', 'Jumat'],
|
|
tanggalTutup: [],
|
|
jenisLayanan: "Eksekutif",
|
|
},
|
|
{
|
|
id: 1008,
|
|
kode: "JT",
|
|
name: "JANTUNG",
|
|
subtitle: "",
|
|
icon: "mdi-heart-pulse",
|
|
shift: "2 SHIFT",
|
|
schedule: "Mulai Pukul 07:00",
|
|
available: true,
|
|
doctors: ["dr. Rudi Hartono, Sp.JP", "dr. Sinta Dewi, Sp.JP"],
|
|
shifts: [],
|
|
totalQuota: 6000,
|
|
jamShiftPerHari: {
|
|
'Senin': [
|
|
{ dari: '07:00', sampai: '11:00', kuota: 800 },
|
|
{ dari: '13:00', sampai: '16:00', kuota: 400 }
|
|
],
|
|
'Selasa': [
|
|
{ dari: '07:00', sampai: '11:00', kuota: 800 },
|
|
{ dari: '13:00', sampai: '16:00', kuota: 400 }
|
|
],
|
|
'Rabu': [
|
|
{ dari: '07:00', sampai: '11:00', kuota: 800 },
|
|
{ dari: '13:00', sampai: '16:00', kuota: 400 }
|
|
],
|
|
'Kamis': [
|
|
{ dari: '07:00', sampai: '11:00', kuota: 800 },
|
|
{ dari: '13:00', sampai: '16:00', kuota: 400 }
|
|
],
|
|
'Jum\'at': [
|
|
{ dari: '07:00', sampai: '11:00', kuota: 800 },
|
|
{ dari: '13:00', sampai: '16:00', kuota: 400 }
|
|
]
|
|
},
|
|
jamShiftList: [],
|
|
autoShift: false,
|
|
jadwalKlinik: ['Senin', 'Selasa', 'Rabu', 'Kamis', 'Jum\'at'],
|
|
tanggalTutup: [],
|
|
jenisLayanan: "Eksekutif",
|
|
},
|
|
{
|
|
id: 1009,
|
|
kode: "JW",
|
|
name: "JIWA",
|
|
subtitle: "",
|
|
icon: "mdi-head-dots-horizontal",
|
|
shift: "1 SHIFT",
|
|
schedule: "Mulai Pukul 07:00",
|
|
available: true,
|
|
doctors: ["dr. Maya Kusuma, Sp.KJ"],
|
|
shifts: [],
|
|
totalQuota: 1400,
|
|
jamShiftPerHari: {
|
|
'Senin': [{ dari: '07:00', sampai: '11:00', kuota: 700 }],
|
|
'Rabu': [{ dari: '07:00', sampai: '11:00', kuota: 700 }]
|
|
},
|
|
jamShiftList: [],
|
|
autoShift: false,
|
|
jadwalKlinik: ['Senin', 'Rabu'],
|
|
tanggalTutup: [],
|
|
jenisLayanan: "Eksekutif",
|
|
},
|
|
{
|
|
id: 1010,
|
|
kode: "KM",
|
|
name: "KEMOTERAPI",
|
|
subtitle: "",
|
|
icon: "mdi-virus",
|
|
shift: "1 SHIFT",
|
|
schedule: "Mulai Pukul 07:00",
|
|
available: true,
|
|
doctors: ["dr. Andi Pratama, Sp.PD-KHOM"],
|
|
shifts: [],
|
|
totalQuota: 0,
|
|
jamShiftPerHari: {},
|
|
jamShiftList: [],
|
|
autoShift: false,
|
|
jadwalKlinik: [],
|
|
tanggalTutup: [],
|
|
jenisLayanan: "Eksekutif",
|
|
},
|
|
{
|
|
id: 1011,
|
|
kode: "KK",
|
|
name: "KUL KEL",
|
|
subtitle: "",
|
|
icon: "mdi-human-male-female",
|
|
shift: "1 SHIFT",
|
|
schedule: "Mulai Pukul 07:00",
|
|
available: true,
|
|
doctors: ["dr. Tika Anggraini, Sp.KK", "dr. Fajar Ramadhan, Sp.KK"],
|
|
shifts: [],
|
|
totalQuota: 1200,
|
|
jamShiftPerHari: {
|
|
'Selasa': [{ dari: '07:00', sampai: '11:00', kuota: 600 }],
|
|
'Kamis': [{ dari: '07:00', sampai: '11:00', kuota: 600 }]
|
|
},
|
|
jamShiftList: [],
|
|
autoShift: false,
|
|
jadwalKlinik: ['Selasa', 'Kamis'],
|
|
tanggalTutup: [],
|
|
jenisLayanan: "Eksekutif",
|
|
},
|
|
{
|
|
id: 1012,
|
|
kode: "KO",
|
|
name: "KOMPLEMENTER",
|
|
subtitle: "",
|
|
icon: "mdi-medical-bag",
|
|
shift: "1 SHIFT",
|
|
schedule: "Mulai Pukul 07:00",
|
|
available: true,
|
|
doctors: ["dr. Ratna Sari, Sp.KFR"],
|
|
shifts: [],
|
|
totalQuota: 0,
|
|
jamShiftPerHari: {},
|
|
jamShiftList: [],
|
|
autoShift: false,
|
|
jadwalKlinik: [],
|
|
tanggalTutup: [],
|
|
jenisLayanan: "Eksekutif",
|
|
},
|
|
{
|
|
id: 1013,
|
|
kode: "MC",
|
|
name: "MCU",
|
|
subtitle: "",
|
|
icon: "mdi-clipboard-check",
|
|
shift: "1 SHIFT",
|
|
schedule: "Mulai Pukul 07:00",
|
|
available: true,
|
|
doctors: ["dr. Fitri Handayani, Sp.OK"],
|
|
shifts: [],
|
|
totalQuota: 0,
|
|
jamShiftPerHari: {},
|
|
jamShiftList: [],
|
|
autoShift: false,
|
|
jadwalKlinik: [],
|
|
tanggalTutup: [],
|
|
jenisLayanan: "Eksekutif",
|
|
},
|
|
{
|
|
id: 1014,
|
|
kode: "MT",
|
|
name: "MATA",
|
|
subtitle: "",
|
|
icon: "mdi-eye",
|
|
shift: "1 SHIFT",
|
|
schedule: "Mulai Pukul 07:00",
|
|
available: true,
|
|
doctors: ["dr. Yudi Prasetyo, Sp.M", "dr. Linda Kartika, Sp.M"],
|
|
shifts: [],
|
|
totalQuota: 2400,
|
|
jamShiftPerHari: {
|
|
'Senin': [{ dari: '07:00', sampai: '11:00', kuota: 800 }],
|
|
'Rabu': [{ dari: '07:00', sampai: '11:00', kuota: 800 }],
|
|
'Jumat': [{ dari: '07:00', sampai: '11:00', kuota: 800 }]
|
|
},
|
|
jamShiftList: [],
|
|
autoShift: false,
|
|
jadwalKlinik: ['Senin', 'Rabu', 'Jumat'],
|
|
tanggalTutup: [],
|
|
jenisLayanan: "Eksekutif",
|
|
},
|
|
{
|
|
id: 1015,
|
|
kode: "KD",
|
|
name: "KANDUNGAN",
|
|
subtitle: "",
|
|
icon: "mdi-human-pregnant",
|
|
shift: "2 SHIFT",
|
|
schedule: "Mulai Pukul 07:00",
|
|
available: true,
|
|
doctors: ["dr. Dewi Lestari, Sp.OG", "dr. Putri Andini, Sp.OG", "dr. Nova Riani, Sp.OG"],
|
|
shifts: [],
|
|
totalQuota: 5000,
|
|
jamShiftPerHari: {
|
|
'Senin': [
|
|
{ dari: '07:00', sampai: '11:00', kuota: 600 },
|
|
{ dari: '13:00', sampai: '16:00', kuota: 400 }
|
|
],
|
|
'Selasa': [
|
|
{ dari: '07:00', sampai: '11:00', kuota: 600 },
|
|
{ dari: '13:00', sampai: '16:00', kuota: 400 }
|
|
],
|
|
'Rabu': [
|
|
{ dari: '07:00', sampai: '11:00', kuota: 600 },
|
|
{ dari: '13:00', sampai: '16:00', kuota: 400 }
|
|
],
|
|
'Kamis': [
|
|
{ dari: '07:00', sampai: '11:00', kuota: 600 },
|
|
{ dari: '13:00', sampai: '16:00', kuota: 400 }
|
|
],
|
|
'Jum\'at': [
|
|
{ dari: '07:00', sampai: '11:00', kuota: 600 },
|
|
{ dari: '13:00', sampai: '16:00', kuota: 400 }
|
|
]
|
|
},
|
|
jamShiftList: [],
|
|
autoShift: false,
|
|
jadwalKlinik: ['Senin', 'Selasa', 'Rabu', 'Kamis', 'Jum\'at'],
|
|
tanggalTutup: [],
|
|
jenisLayanan: "Eksekutif",
|
|
},
|
|
{
|
|
id: 1016,
|
|
kode: "ON",
|
|
name: "ONKOLOGI",
|
|
subtitle: "",
|
|
icon: "mdi-virus",
|
|
shift: "1 SHIFT",
|
|
schedule: "Mulai Pukul 07:00",
|
|
available: true,
|
|
doctors: ["dr. Dimas Prakoso, Sp.Onk-Rad"],
|
|
shifts: [],
|
|
totalQuota: 0,
|
|
jamShiftPerHari: {},
|
|
jamShiftList: [],
|
|
autoShift: false,
|
|
jadwalKlinik: [],
|
|
tanggalTutup: [],
|
|
jenisLayanan: "Eksekutif",
|
|
},
|
|
{
|
|
id: 1017,
|
|
kode: "PR",
|
|
name: "PARU",
|
|
subtitle: "",
|
|
icon: "mdi-lungs",
|
|
shift: "1 SHIFT",
|
|
schedule: "Mulai Pukul 07:00",
|
|
available: true,
|
|
doctors: ["dr. Nina Marlina, Sp.P", "dr. Arief Budiman, Sp.P"],
|
|
shifts: [],
|
|
totalQuota: 1400,
|
|
jamShiftPerHari: {
|
|
'Senin': [{ dari: '07:00', sampai: '11:00', kuota: 700 }],
|
|
'Rabu': [{ dari: '07:00', sampai: '11:00', kuota: 700 }]
|
|
},
|
|
jamShiftList: [],
|
|
autoShift: false,
|
|
jadwalKlinik: ['Senin', 'Rabu'],
|
|
tanggalTutup: [],
|
|
jenisLayanan: "Eksekutif",
|
|
},
|
|
{
|
|
id: 1018,
|
|
kode: "RM",
|
|
name: "REHAB MEDIK",
|
|
subtitle: "",
|
|
icon: "mdi-human-cane",
|
|
shift: "1 SHIFT",
|
|
schedule: "Mulai Pukul 07:00",
|
|
available: true,
|
|
doctors: ["dr. Gita Permata, Sp.KFR", "dr. Rian Saputra, Sp.KFR"],
|
|
shifts: [],
|
|
totalQuota: 1800,
|
|
jamShiftPerHari: {
|
|
'Senin': [{ dari: '07:00', sampai: '11:00', kuota: 600 }],
|
|
'Rabu': [{ dari: '07:00', sampai: '11:00', kuota: 600 }],
|
|
'Jumat': [{ dari: '07:00', sampai: '11:00', kuota: 600 }]
|
|
},
|
|
jamShiftList: [],
|
|
autoShift: false,
|
|
jadwalKlinik: ['Senin', 'Rabu', 'Jumat'],
|
|
tanggalTutup: [],
|
|
jenisLayanan: "Eksekutif",
|
|
},
|
|
{
|
|
id: 1019,
|
|
kode: "RD",
|
|
name: "RADIOTERAPI",
|
|
subtitle: "",
|
|
icon: "mdi-radioactive",
|
|
shift: "1 SHIFT",
|
|
schedule: "Mulai Pukul 07:00",
|
|
available: true,
|
|
doctors: ["dr. Wulan Safitri, Sp.Rad"],
|
|
shifts: [],
|
|
totalQuota: 2500,
|
|
jamShiftPerHari: {
|
|
'Senin': [{ dari: '07:00', sampai: '11:00', kuota: 500 }],
|
|
'Selasa': [{ dari: '07:00', sampai: '11:00', kuota: 500 }],
|
|
'Rabu': [{ dari: '07:00', sampai: '11:00', kuota: 500 }],
|
|
'Kamis': [{ dari: '07:00', sampai: '11:00', kuota: 500 }],
|
|
'Jum\'at': [{ dari: '07:00', sampai: '11:00', kuota: 500 }]
|
|
},
|
|
jamShiftList: [],
|
|
autoShift: false,
|
|
jadwalKlinik: ['Senin', 'Selasa', 'Rabu', 'Kamis', 'Jum\'at'],
|
|
tanggalTutup: [],
|
|
jenisLayanan: "Eksekutif",
|
|
},
|
|
{
|
|
id: 1020,
|
|
kode: "SR",
|
|
name: "SARAF",
|
|
subtitle: "",
|
|
icon: "mdi-head-cog",
|
|
shift: "1 SHIFT",
|
|
schedule: "Mulai Pukul 07:00",
|
|
available: false,
|
|
doctors: [],
|
|
shifts: [],
|
|
totalQuota: 1400,
|
|
jamShiftPerHari: {
|
|
'Senin': [{ dari: '07:00', sampai: '11:00', kuota: 700 }],
|
|
'Rabu': [{ dari: '07:00', sampai: '11:00', kuota: 700 }]
|
|
},
|
|
jamShiftList: [],
|
|
autoShift: false,
|
|
jadwalKlinik: ['Senin', 'Rabu'],
|
|
tanggalTutup: [],
|
|
jenisLayanan: "Eksekutif",
|
|
},
|
|
{
|
|
id: 1021,
|
|
kode: "RT",
|
|
name: "R. TINDAKAN",
|
|
subtitle: "",
|
|
icon: "mdi-waveform",
|
|
shift: "1 SHIFT",
|
|
schedule: "Mulai Pukul 07:00",
|
|
available: true,
|
|
doctors: ["dr. Fajar Nugroho, Sp.S"],
|
|
shifts: [],
|
|
totalQuota: 0,
|
|
jamShiftPerHari: {},
|
|
jamShiftList: [],
|
|
autoShift: false,
|
|
jadwalKlinik: [],
|
|
tanggalTutup: [],
|
|
jenisLayanan: "Eksekutif",
|
|
},
|
|
{
|
|
id: 1022,
|
|
kode: "TH",
|
|
name: "THT",
|
|
subtitle: "",
|
|
icon: "mdi-ear-hearing",
|
|
shift: "1 SHIFT",
|
|
schedule: "Mulai Pukul 07:00",
|
|
available: true,
|
|
doctors: ["dr. Reza Maulana, Sp.THT-KL"],
|
|
shifts: [],
|
|
totalQuota: 0,
|
|
jamShiftPerHari: {},
|
|
jamShiftList: [],
|
|
autoShift: false,
|
|
jadwalKlinik: [],
|
|
tanggalTutup: [],
|
|
jenisLayanan: "Eksekutif",
|
|
},
|
|
]);
|
|
|
|
console.log('📊 Initial clinics count:', clinics.value.length);
|
|
console.log('📋 Initial clinics:', clinics.value.map(c => ({ id: c.id, name: c.name, jenisLayanan: c.jenisLayanan })));
|
|
|
|
const isLoadingAPI = ref(false);
|
|
const apiError = ref(null);
|
|
|
|
// Helper: Convert day name from API to Indonesian
|
|
const mapDayToIndonesian = (day) => {
|
|
const mapping = {
|
|
'TUE': 'Selasa',
|
|
'MON': 'Senin',
|
|
'WED': 'Rabu',
|
|
'THU': 'Kamis',
|
|
'FRI': 'Jum\'at',
|
|
'SAT': 'Sabtu',
|
|
'SUN': 'Minggu'
|
|
};
|
|
return mapping[day] || day;
|
|
};
|
|
|
|
// Helper: Parse jam_operasional to create jamShiftPerHari structure
|
|
const parseJamOperasional = (jamOperasional) => {
|
|
console.log('🔄 Parsing jam operasional:', jamOperasional);
|
|
|
|
const jamShiftPerHari = {}; // { 'Senin': [{ dari, sampai, kuota }], 'Selasa': [...] }
|
|
const jadwalKlinikSet = new Set();
|
|
let totalQuota = 0;
|
|
|
|
if (!jamOperasional) {
|
|
console.log('⚠️ No jamOperasional provided, using defaults');
|
|
return {
|
|
jamShiftPerHari: {
|
|
'Senin': [{ dari: '07:00', sampai: '11:00', kuota: 100 }]
|
|
},
|
|
jadwalKlinik: ['Senin'],
|
|
totalQuota: 100,
|
|
shift: 1
|
|
};
|
|
}
|
|
|
|
if (!Array.isArray(jamOperasional)) {
|
|
console.log('⚠️ jamOperasional is not an array:', typeof jamOperasional);
|
|
return {
|
|
jamShiftPerHari: {
|
|
'Senin': [{ dari: '07:00', sampai: '11:00', kuota: 100 }]
|
|
},
|
|
jadwalKlinik: ['Senin'],
|
|
totalQuota: 100,
|
|
shift: 1
|
|
};
|
|
}
|
|
|
|
console.log(`📋 Processing ${jamOperasional.length} schedule items`);
|
|
|
|
// Group by day and create shift per day structure
|
|
jamOperasional.forEach((item, index) => {
|
|
console.log(` 📍 Schedule ${index + 1}:`, {
|
|
hari: item.hari,
|
|
jam_operasional: item.jam_operasional,
|
|
kuota: item.kuota
|
|
});
|
|
|
|
const dayIndo = mapDayToIndonesian(item.hari);
|
|
if (!dayIndo) {
|
|
console.log(` ⚠️ Could not map day: ${item.hari}`);
|
|
return;
|
|
}
|
|
|
|
jadwalKlinikSet.add(dayIndo);
|
|
|
|
const jamOp = item.jam_operasional || '';
|
|
const parts = jamOp.split(' - ');
|
|
|
|
if (parts.length === 2) {
|
|
const dari = parts[0]?.trim() || '07:00';
|
|
const sampai = parts[1]?.trim() || '11:00';
|
|
|
|
// Handle different kuota formats
|
|
let kuota = 100; // default
|
|
if (item.kuota) {
|
|
if (typeof item.kuota === 'number') {
|
|
kuota = item.kuota;
|
|
} else if (typeof item.kuota === 'object' && item.kuota.Intfd !== undefined) {
|
|
kuota = parseInt(item.kuota.Intfd) || 100;
|
|
} else if (typeof item.kuota === 'object' && item.kuota.Valid !== undefined) {
|
|
kuota = parseInt(item.kuota.Valid) || 100;
|
|
} else if (typeof item.kuota === 'string') {
|
|
kuota = parseInt(item.kuota) || 100;
|
|
}
|
|
}
|
|
|
|
console.log(` ✅ Shift added for ${dayIndo}: ${dari} - ${sampai}, kuota: ${kuota}`);
|
|
|
|
// Initialize array if not exists
|
|
if (!jamShiftPerHari[dayIndo]) {
|
|
jamShiftPerHari[dayIndo] = [];
|
|
}
|
|
|
|
jamShiftPerHari[dayIndo].push({
|
|
dari,
|
|
sampai,
|
|
kuota
|
|
});
|
|
|
|
totalQuota += kuota;
|
|
} else {
|
|
console.log(` ⚠️ Invalid jam_operasional format: "${jamOp}"`);
|
|
}
|
|
});
|
|
|
|
// If no valid shift found, add default
|
|
if (Object.keys(jamShiftPerHari).length === 0) {
|
|
console.log('⚠️ No valid shifts found, using default');
|
|
jamShiftPerHari['Senin'] = [{ dari: '07:00', sampai: '11:00', kuota: 100 }];
|
|
jadwalKlinikSet.add('Senin');
|
|
totalQuota = 100;
|
|
}
|
|
|
|
// Count total unique shifts across all days
|
|
const totalShifts = Object.values(jamShiftPerHari).reduce((sum, shifts) => sum + shifts.length, 0);
|
|
|
|
const result = {
|
|
jamShiftPerHari,
|
|
jadwalKlinik: Array.from(jadwalKlinikSet),
|
|
totalQuota,
|
|
shift: totalShifts
|
|
};
|
|
|
|
console.log('✅ Parse result:', result);
|
|
|
|
return result;
|
|
};
|
|
|
|
// Fetch Reguler clinics from API
|
|
const fetchRegulerClinics = async () => {
|
|
isLoadingAPI.value = true;
|
|
apiError.value = null;
|
|
|
|
try {
|
|
console.log('🔄 Fetching clinics from API...');
|
|
const response = await fetch('http://10.10.150.131:8089/api/v1/klinik/reguler');
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
}
|
|
|
|
const rawData = await response.json();
|
|
console.log('📦 Raw API Response:', rawData);
|
|
console.log('📦 Response type:', typeof rawData);
|
|
console.log('📦 Is Array?', Array.isArray(rawData));
|
|
|
|
// Handle different response formats
|
|
let data = rawData;
|
|
|
|
// If data is wrapped in an object (e.g., { data: [...], status: 200 })
|
|
if (rawData && typeof rawData === 'object' && !Array.isArray(rawData)) {
|
|
console.log('📦 Response is an object, checking for data property...');
|
|
if (rawData.data) {
|
|
data = rawData.data;
|
|
console.log('✅ Found data property:', data);
|
|
} else if (rawData.result) {
|
|
data = rawData.result;
|
|
console.log('✅ Found result property:', data);
|
|
} else if (rawData.response) {
|
|
data = rawData.response;
|
|
console.log('✅ Found response property:', data);
|
|
}
|
|
}
|
|
|
|
console.log('📊 Processed data:', data);
|
|
console.log('📊 Processed data is Array?', Array.isArray(data));
|
|
|
|
if (!data || !Array.isArray(data)) {
|
|
console.error('❌ Data is not an array after processing');
|
|
console.error('❌ Data type:', typeof data);
|
|
console.error('❌ Data value:', data);
|
|
return {
|
|
success: false,
|
|
message: `Data format tidak valid. Expected array, got ${typeof data}. Check console for details.`
|
|
};
|
|
}
|
|
|
|
console.log(`✅ Found ${data.length} items in API response`);
|
|
|
|
// Log first item for debugging
|
|
if (data.length > 0) {
|
|
console.log('📋 First item sample:', JSON.stringify(data[0], null, 2));
|
|
}
|
|
|
|
// Remove existing Reguler clinics
|
|
clinics.value = clinics.value.filter(c => c.jenisLayanan !== 'Reguler');
|
|
console.log(`🗑️ Removed existing Reguler clinics. Remaining: ${clinics.value.length}`);
|
|
|
|
// Filter and map clinics
|
|
const filteredData = data.filter(item => {
|
|
const isReguler = item.Tipe_Anjungan === 'KLINIK REGULER';
|
|
if (!isReguler) {
|
|
console.log(`⏭️ Skipping ${item.namaklinik} - Tipe: ${item.Tipe_Anjungan}`);
|
|
}
|
|
return isReguler;
|
|
});
|
|
|
|
console.log(`✅ Filtered ${filteredData.length} KLINIK REGULER items`);
|
|
|
|
// Add new Reguler clinics from API
|
|
const regulerClinics = filteredData.map((item, index) => {
|
|
console.log(`\n🏥 Processing clinic ${index + 1}/${filteredData.length}:`, item.namaklinik);
|
|
console.log(' - ID:', item.idklinik);
|
|
console.log(' - Code:', item.code);
|
|
console.log(' - Active:', item.active);
|
|
console.log(' - Jadwal:', item.jadwal);
|
|
|
|
const parsed = parseJamOperasional(item.jadwal);
|
|
console.log(' - Parsed jamShiftPerHari:', parsed.jamShiftPerHari);
|
|
console.log(' - Total quota:', parsed.totalQuota);
|
|
console.log(' - Jadwal klinik:', parsed.jadwalKlinik);
|
|
|
|
// Get first shift from first day for display purposes
|
|
const firstDay = parsed.jadwalKlinik[0];
|
|
const firstShift = firstDay ? parsed.jamShiftPerHari[firstDay]?.[0] : null;
|
|
|
|
return {
|
|
id: item.idklinik,
|
|
kode: item.code || 'XX',
|
|
name: item.namaklinik || 'Unknown',
|
|
subtitle: "",
|
|
icon: "mdi-hospital-box",
|
|
shift: `${parsed.shift} SHIFT`,
|
|
schedule: `Mulai Pukul ${firstShift?.dari || '07:00'}`,
|
|
available: item.active,
|
|
doctors: [],
|
|
shifts: [], // Legacy field, kept for compatibility
|
|
totalQuota: parsed.totalQuota,
|
|
jamShiftPerHari: parsed.jamShiftPerHari, // NEW: shift configuration per day
|
|
jamShiftList: [], // Legacy field, kept for compatibility
|
|
autoShift: false,
|
|
jadwalKlinik: parsed.jadwalKlinik,
|
|
tanggalTutup: [], // NEW: array of closed dates
|
|
jenisLayanan: "Reguler",
|
|
};
|
|
});
|
|
|
|
console.log(`✅ Created ${regulerClinics.length} clinic objects`);
|
|
|
|
// Add reguler clinics to the list
|
|
clinics.value = [...clinics.value, ...regulerClinics];
|
|
console.log(`✅ Total clinics after merge: ${clinics.value.length}`);
|
|
|
|
// Sort by kode, then jenisLayanan
|
|
clinics.value.sort((a, b) => {
|
|
if (a.kode < b.kode) return -1;
|
|
if (a.kode > b.kode) return 1;
|
|
if (a.jenisLayanan === 'Reguler' && b.jenisLayanan === 'Eksekutif') return -1;
|
|
if (a.jenisLayanan === 'Eksekutif' && b.jenisLayanan === 'Reguler') return 1;
|
|
return a.id - b.id;
|
|
});
|
|
console.log('✅ Clinics sorted by kode and jenisLayanan');
|
|
|
|
console.log('🎉 Final clinic list:', clinics.value.map(c => ({ id: c.id, name: c.name, jenisLayanan: c.jenisLayanan })));
|
|
|
|
return { success: true, message: `${regulerClinics.length} klinik reguler berhasil dimuat` };
|
|
|
|
} catch (error) {
|
|
console.error('❌ Error fetching reguler clinics:', error);
|
|
console.error('❌ Error stack:', error.stack);
|
|
apiError.value = error.message;
|
|
return { success: false, message: `Gagal memuat data: ${error.message}` };
|
|
} finally {
|
|
isLoadingAPI.value = false;
|
|
console.log('✅ API fetch completed');
|
|
}
|
|
};
|
|
|
|
// Get all clinics (sorted by kode first, then by jenisLayanan)
|
|
// This ensures same clinic code (e.g., "AN") appears together, with Reguler before Eksekutif
|
|
const getAllClinics = computed(() => {
|
|
const sorted = [...clinics.value].sort((a, b) => {
|
|
// First sort by kode
|
|
if (a.kode < b.kode) return -1;
|
|
if (a.kode > b.kode) return 1;
|
|
// If same kode, sort by jenisLayanan (Reguler before Eksekutif)
|
|
if (a.jenisLayanan === 'Reguler' && b.jenisLayanan === 'Eksekutif') return -1;
|
|
if (a.jenisLayanan === 'Eksekutif' && b.jenisLayanan === 'Reguler') return 1;
|
|
// Finally sort by ID if both are same
|
|
return a.id - b.id;
|
|
});
|
|
console.log('📊 getAllClinics computed:', sorted.length, 'items');
|
|
return sorted;
|
|
});
|
|
|
|
// Get clinics by jenis layanan
|
|
const getClinicsByJenisLayanan = (jenisLayanan) => {
|
|
return computed(() => clinics.value.filter(c => c.jenisLayanan === jenisLayanan));
|
|
};
|
|
|
|
// Get clinic by name (untuk mapping dengan kode klinik)
|
|
const getClinicByName = (name) => {
|
|
return clinics.value.find(c => c.name === name);
|
|
};
|
|
|
|
// Get clinic by kode (lebih stabil untuk integrasi dengan master klinik & anjungan)
|
|
const getClinicByKode = (kode) => {
|
|
return clinics.value.find(c => c.kode === kode);
|
|
};
|
|
|
|
// Get clinics list untuk dropdown (format: { name, kode, jenisLayanan })
|
|
// Sekarang langsung pakai kode dari clinic, tidak bergantung ke nama di masterStore
|
|
const getClinicsForDropdown = (jenisLayanan = null) => {
|
|
let filteredClinics = clinics.value;
|
|
if (jenisLayanan) {
|
|
filteredClinics = clinics.value.filter(c => c.jenisLayanan === jenisLayanan);
|
|
}
|
|
|
|
return filteredClinics
|
|
.sort((a, b) => {
|
|
if (a.kode < b.kode) return -1;
|
|
if (a.kode > b.kode) return 1;
|
|
if (a.jenisLayanan === 'Reguler' && b.jenisLayanan === 'Eksekutif') return -1;
|
|
if (a.jenisLayanan === 'Eksekutif' && b.jenisLayanan === 'Reguler') return 1;
|
|
return a.id - b.id;
|
|
})
|
|
.map(clinic => ({
|
|
name: clinic.name,
|
|
kode: clinic.kode,
|
|
icon: clinic.icon,
|
|
available: clinic.available,
|
|
id: clinic.id,
|
|
jenisLayanan: clinic.jenisLayanan
|
|
}));
|
|
};
|
|
|
|
// Actions untuk update master config (sync dengan masterStore operations)
|
|
const updateClinicMasterConfig = (kode, masterConfig) => {
|
|
const clinic = clinics.value.find(c => c.kode === kode);
|
|
if (clinic) {
|
|
clinic.totalQuota = masterConfig.totalQuota || clinic.totalQuota;
|
|
clinic.jamShiftPerHari = masterConfig.jamShiftPerHari || clinic.jamShiftPerHari;
|
|
clinic.autoShift = masterConfig.autoShift !== undefined ? masterConfig.autoShift : clinic.autoShift;
|
|
clinic.jadwalKlinik = masterConfig.jadwalKlinik || clinic.jadwalKlinik;
|
|
clinic.tanggalTutup = masterConfig.tanggalTutup || clinic.tanggalTutup;
|
|
return { success: true, clinic };
|
|
}
|
|
return { success: false, message: 'Clinic not found' };
|
|
};
|
|
|
|
return {
|
|
clinics,
|
|
isLoadingAPI,
|
|
apiError,
|
|
getAllClinics,
|
|
getClinicsByJenisLayanan,
|
|
getClinicByName,
|
|
getClinicByKode,
|
|
getClinicsForDropdown,
|
|
updateClinicMasterConfig,
|
|
fetchRegulerClinics,
|
|
};
|
|
}, {
|
|
persist: {
|
|
key: 'clinic-store-state',
|
|
storage: typeof window !== 'undefined' ? localStorage : undefined,
|
|
paths: ['clinics'],
|
|
},
|
|
});
|