import { defineStore } from 'pinia'; import spesialisData from '~/data/mock/spesialis.json'; import subSpesialisData from '~/data/mock/subSpesialis.json'; import api from '~/services/api'; import type { Dokter, DiagnosisItem, TindakanItem } from '~/types/pendaftaran'; import { STATUS } from '~/types/antrean'; interface FormData { noRekamMedis: string; noKtp: string; namaPasien: string; jenisKelamin: string; tanggalLahir: string; umur: string; alamat: string; nomorTelepon: string[]; } interface RencanaOperasiData { spesialis: number | null | undefined; subSpesialis: number | null | undefined; tanggalDaftar: string; kategoriOperasi: number | null | undefined; rencanaOperasi: string; keterangan: string; } interface StatusPasienData { tanggalSelesai: string; statusOperasi: string; keteranganStatus: string; } export const usePendaftaranStore = defineStore('pendaftaran', { state: () => ({ // Form data formData: { noRekamMedis: '', noKtp: '', namaPasien: '', jenisKelamin: '', tanggalLahir: '', umur: '', alamat: '', nomorTelepon: [] } as FormData, // Medical data diagnosisItems: [] as DiagnosisItem[], tindakanItems: [] as TindakanItem[], // Rencana Operasi data rencanaOperasiData: { spesialis: null as number | null | undefined, subSpesialis: null as number | null | undefined, tanggalDaftar: '', kategoriOperasi: null as number | null | undefined, rencanaOperasi: '', keterangan: '' } as RencanaOperasiData, dokterPelaksanaItems: [] as Dokter[], // Status Pasien data statusPasienData: { tanggalSelesai: '', statusOperasi: '1', keteranganStatus: '' } as StatusPasienData, // UI state loading: false, snackbar: false, snackbarMessage: '', snackbarColor: 'error' }), getters: { // Check if form has any data hasFormData: (state) => { return !!( state.formData.noRekamMedis || state.formData.namaPasien || state.diagnosisItems.length > 0 || state.tindakanItems.length > 0 || state.rencanaOperasiData.spesialis || state.dokterPelaksanaItems.length > 0 ); }, // Get all form data for submission getSubmissionData: (state) => { return { formData: state.formData, diagnosisItems: state.diagnosisItems, tindakanItems: state.tindakanItems, rencanaOperasiData: state.rencanaOperasiData, dokterPelaksanaItems: state.dokterPelaksanaItems, statusPasienData: state.statusPasienData }; } }, actions: { // Initialize form with query parameters async initializeFromQuery(kodeSpesialis?: string, kodeSubSpesialis?: string) { if (kodeSpesialis) { const spesialis = spesialisData.find(s => s.kode === kodeSpesialis); if (spesialis) { this.rencanaOperasiData.spesialis = spesialis.id; // Wait for next tick to ensure watch has processed if (kodeSubSpesialis) { await nextTick(); const subSpesialis = subSpesialisData.find(s => s.kode === kodeSubSpesialis); if (subSpesialis) { this.rencanaOperasiData.subSpesialis = subSpesialis.id; } } } } }, // Reset entire form resetForm() { this.formData = { noRekamMedis: '', noKtp: '', namaPasien: '', jenisKelamin: '', tanggalLahir: '', umur: '', alamat: '', nomorTelepon: [] }; this.diagnosisItems = []; this.tindakanItems = []; this.rencanaOperasiData = { spesialis: null, subSpesialis: null, tanggalDaftar: '', kategoriOperasi: null, rencanaOperasi: '', keterangan: '' }; this.dokterPelaksanaItems = []; this.statusPasienData = { tanggalSelesai: '', statusOperasi: STATUS.BELUM, keteranganStatus: '' }; }, // Validate form data validateForm(): { valid: boolean; errors: string[]; firstErrorField?: string } { const errors: string[] = []; let firstErrorField: string | undefined = undefined; // Validate formData if (!this.formData.noRekamMedis) { errors.push('No Rekam Medis'); if (!firstErrorField) firstErrorField = 'noRekamMedis'; } // Validate diagnosis items - must have at least 1 if (this.diagnosisItems.length === 0) { errors.push('Diagnosis (minimal 1 diagnosis harus diisi)'); if (!firstErrorField) firstErrorField = 'diagnosis'; } // Validate tindakan items - must have at least 1 if (this.tindakanItems.length === 0) { errors.push('Tindakan (minimal 1 tindakan harus diisi)'); if (!firstErrorField) firstErrorField = 'tindakan'; } // Validate rencanaOperasiData if (!this.rencanaOperasiData.spesialis) { errors.push('Spesialis'); if (!firstErrorField) firstErrorField = 'spesialis'; } if (!this.rencanaOperasiData.subSpesialis) { errors.push('Sub Spesialis'); if (!firstErrorField) firstErrorField = 'subSpesialis'; } if (!this.rencanaOperasiData.tanggalDaftar) { errors.push('Tanggal Daftar'); if (!firstErrorField) firstErrorField = 'tanggalDaftar'; } if (!this.rencanaOperasiData.kategoriOperasi) { errors.push('Kategori Operasi'); if (!firstErrorField) firstErrorField = 'kategoriOperasi'; } // Validate status operasi if (!this.statusPasienData.statusOperasi) { errors.push('Status Operasi'); if (!firstErrorField) firstErrorField = 'statusOperasi'; } // Conditional validation based on status operasi if (this.statusPasienData.statusOperasi === STATUS.SELESAI) { if (!this.statusPasienData.tanggalSelesai) { errors.push('Tanggal Selesai Operasi (wajib diisi untuk status Selesai)'); if (!firstErrorField) firstErrorField = 'tanggalSelesai'; } else if (this.rencanaOperasiData.tanggalDaftar && this.statusPasienData.tanggalSelesai < this.rencanaOperasiData.tanggalDaftar) { errors.push('Tanggal Selesai Operasi tidak boleh kurang dari Tanggal Daftar'); if (!firstErrorField) firstErrorField = 'tanggalSelesai'; } } if (this.statusPasienData.statusOperasi === STATUS.TUNDA || this.statusPasienData.statusOperasi === STATUS.BATAL) { if (!this.statusPasienData.keteranganStatus) { errors.push('Keterangan Status Pasien (wajib diisi untuk status Tunda/Batal)'); if (!firstErrorField) firstErrorField = 'keteranganStatus'; } } return { valid: errors.length === 0, errors, firstErrorField }; }, // Submit form async submitForm(id?: string | number) { this.loading = true; try { // Prepare submission data const submissionData = { formData: this.formData, diagnosisItems: this.diagnosisItems, tindakanItems: this.tindakanItems, rencanaOperasiData: { ...this.rencanaOperasiData, // Convert tanggalDaftar to ISO format if needed tanggalDaftar: this.rencanaOperasiData.tanggalDaftar ? new Date(this.rencanaOperasiData.tanggalDaftar).toISOString() : '' }, dokterPelaksanaItems: this.dokterPelaksanaItems.map(dokter => ({ id: dokter.id, nip: dokter.nip, nama: dokter.nama_lengkap, satuan_kerja: dokter.nama_ksm })), statusPasienData: { ...this.statusPasienData, // Convert tanggalSelesai to ISO format or null tanggalSelesai: this.statusPasienData.tanggalSelesai ? new Date(this.statusPasienData.tanggalSelesai).toISOString() : null } }; console.log('Submitting data:', submissionData); // Make API call - use PUT for edit mode, POST for create mode const response = id ? await api.put(`/antrian-operasi/${id}`, submissionData) : await api.post('/antrian-operasi', submissionData); console.log('API Response:', response.data); // Show success message const successMessage = id ? 'Data berhasil diupdate!' : 'Data berhasil disimpan!'; this.showSnackbar(successMessage, 'success'); return { success: true, data: response.data }; } catch (error: any) { console.error('Error submitting form:', error); // Handle error message const errorMessage = error.response?.data?.message || error.message || 'Terjadi kesalahan saat menyimpan data!'; this.showSnackbar(errorMessage, 'error'); return { success: false, error }; } finally { this.loading = false; } }, // Show snackbar notification showSnackbar(message: string, color: string = 'error') { this.snackbarMessage = message; this.snackbarColor = color; this.snackbar = true; }, // Close snackbar closeSnackbar() { this.snackbar = false; } } });