update komponen, stores, desain
This commit is contained in:
@@ -1,39 +1,60 @@
|
||||
// src/stores/payment.js
|
||||
// src/stores/payment.ts
|
||||
import { defineStore } from 'pinia';
|
||||
|
||||
// 1. Definisikan Tipe Data untuk qrData (penting untuk properti expired_at yang di-spread)
|
||||
interface QrData {
|
||||
qrvalue: string | null;
|
||||
display_nobill: string | null;
|
||||
display_name: string | null;
|
||||
display_amount: string | null;
|
||||
status: '1' | '2' | '0' | null; // "1": Pending, "2": Sukses, "0": Gagal/Expired
|
||||
ip: string | null;
|
||||
// Tambahkan properti yang di-spread dari API, termasuk expired_at
|
||||
expired_at?: string; // Tambahkan expired_at sebagai properti opsional
|
||||
[key: string]: any; // Indeks signature untuk properti dinamis (misal: transaction_id, reason)
|
||||
}
|
||||
|
||||
// 2. Definisikan Tipe Data untuk State
|
||||
interface PaymentState {
|
||||
currentStep: 1 | 2 | 3 | 4;
|
||||
patientInfo: {
|
||||
name: string;
|
||||
amount: string;
|
||||
expiry: string;
|
||||
};
|
||||
qrData: QrData;
|
||||
}
|
||||
|
||||
// Variabel di luar store untuk menyimpan timer, agar persistensi di luar state Pinia
|
||||
let autoResetTimer = null;
|
||||
let autoResetTimer: number | null = null;
|
||||
|
||||
export const usePaymentStore = defineStore('payment', {
|
||||
state: () => ({
|
||||
state: (): PaymentState => ({ // Gunakan tipedata PaymentState
|
||||
currentStep: 1, // 1: Menunggu Data, 2: Tampilkan QRIS, 3: Sukses, 4: Gagal
|
||||
patientInfo: {
|
||||
name: '',
|
||||
amount: '',
|
||||
expiry: '', // Dibiarkan kosong, waktu kedaluwarsa dihitung dari qrData.created_at
|
||||
expiry: '', // Waktu kedaluwarsa diambil dari qrData (via spread)
|
||||
},
|
||||
qrData: {
|
||||
qrvalue: null,
|
||||
display_nobill: null,
|
||||
display_name: null,
|
||||
display_amount: null,
|
||||
status: null, // Status pembayaran: "1" (Pending), "2" (Sukses), "0" (Gagal/Expired)
|
||||
status: null,
|
||||
ip: null,
|
||||
created_at: null, // Tambahkan ini agar properti ada secara eksplisit
|
||||
// ... properti lain dari API akan ditambahkan melalui spread operator
|
||||
},
|
||||
// created_at DIHAPUS
|
||||
} as QrData, // Type casting untuk QrData
|
||||
}),
|
||||
|
||||
getters: {
|
||||
hasQrData: (state) => state.qrData && state.qrData.qrvalue,
|
||||
safeQrValue: (state) => state.qrData?.qrvalue || 'https://www.google.com',
|
||||
hasQrData: (state): boolean => !!state.qrData.qrvalue,
|
||||
safeQrValue: (state): string => state.qrData.qrvalue || 'https://www.google.com',
|
||||
|
||||
// Getter untuk cek apakah data siap
|
||||
isReadyForStatusCheck: (state) => {
|
||||
return state.qrData.display_nobill && state.qrData.display_name;
|
||||
isReadyForStatusCheck: (state): boolean => {
|
||||
return !!(state.qrData.display_nobill && state.qrData.display_name);
|
||||
},
|
||||
|
||||
// Getter untuk debug
|
||||
debugInfo: (state) => ({
|
||||
step: state.currentStep,
|
||||
hasIdentifiers: !!(state.qrData.display_nobill && state.qrData.display_name),
|
||||
@@ -50,26 +71,22 @@ export const usePaymentStore = defineStore('payment', {
|
||||
this.currentStep--;
|
||||
},
|
||||
|
||||
setStep(step) {
|
||||
setStep(step: 1 | 2 | 3 | 4) {
|
||||
console.log(`[STORE] Setting step from ${this.currentStep} to ${step}`);
|
||||
this.currentStep = step;
|
||||
},
|
||||
|
||||
/**
|
||||
* @description Memulai timer untuk reset state kembali ke Step 1 (Home) setelah 20 detik
|
||||
*/
|
||||
startAutoReset() {
|
||||
|
||||
if (autoResetTimer) {
|
||||
clearTimeout(autoResetTimer);
|
||||
}
|
||||
console.log('🏠 [STORE] Starting auto return timer (20s) for reset.');
|
||||
|
||||
console.log('🏠 [STORE] Starting auto return timer (50s) for reset.');
|
||||
|
||||
// Di TypeScript, setTimeout mengembalikan number
|
||||
autoResetTimer = setTimeout(() => {
|
||||
console.log('🏠 [STORE] Auto return to home triggered');
|
||||
this.reset();
|
||||
}, 20000);
|
||||
}, 10000);
|
||||
},
|
||||
|
||||
reset() {
|
||||
@@ -87,25 +104,24 @@ export const usePaymentStore = defineStore('payment', {
|
||||
display_amount: null,
|
||||
status: null,
|
||||
ip: null,
|
||||
created_at: null,
|
||||
};
|
||||
} as QrData; // Pastikan tipe kembali ke QrData
|
||||
if (autoResetTimer) {
|
||||
clearTimeout(autoResetTimer);
|
||||
autoResetTimer = null;
|
||||
}
|
||||
},
|
||||
|
||||
updatePayment(apiResponse) {
|
||||
// Definisikan tipe untuk apiResponse
|
||||
updatePayment(apiResponse: { data: QrData[] }) {
|
||||
console.log("=== [STORE] UPDATE PAYMENT ===");
|
||||
|
||||
// Validasi response
|
||||
if (!apiResponse?.data || !Array.isArray(apiResponse.data) || apiResponse.data.length === 0) {
|
||||
if (!apiResponse?.data || apiResponse.data.length === 0) {
|
||||
console.error("Invalid API response structure or empty data array");
|
||||
return;
|
||||
}
|
||||
|
||||
const apiData = apiResponse.data[0];
|
||||
const oldStatus = this.qrData.status; // Simpan status lama
|
||||
const oldStatus = this.qrData.status;
|
||||
|
||||
// Update qrData dengan semua properti dari API
|
||||
this.qrData = {
|
||||
@@ -113,11 +129,10 @@ export const usePaymentStore = defineStore('payment', {
|
||||
display_nobill: apiData.display_nobill || this.qrData.display_nobill,
|
||||
display_name: apiData.display_name || this.qrData.display_name,
|
||||
display_amount: apiData.display_amount || apiData.nominal || this.qrData.display_amount,
|
||||
status: apiData.status || this.qrData.status,
|
||||
status: apiData.status as QrData['status'] || this.qrData.status, // Type casting untuk status
|
||||
ip: apiData.ip || this.qrData.ip,
|
||||
created_at: apiData.created_at || this.qrData.created_at, // Ambil 'created_at'
|
||||
// Spread untuk properti lain yang mungkin ada (misal: transaction_id, reason)
|
||||
...apiData
|
||||
// created_at DIHAPUS
|
||||
...apiData // expired_at akan masuk di sini
|
||||
};
|
||||
|
||||
// Update patientInfo
|
||||
@@ -130,28 +145,22 @@ export const usePaymentStore = defineStore('payment', {
|
||||
// --- LOGIKA TRANSISI STATUS OTOMATIS (SUCCESS/FAIL) ---
|
||||
const newStatus = this.qrData.status;
|
||||
|
||||
// Log perubahan status (jika ada)
|
||||
if (oldStatus !== newStatus) {
|
||||
console.log(`[STORE] Status changed: ${oldStatus} -> ${newStatus}`);
|
||||
}
|
||||
|
||||
// Proses transisi hanya jika kita berada di Step 2 (Menunggu Pembayaran)
|
||||
// DAN status yang diterima berbeda dari status sebelumnya
|
||||
if (this.currentStep === 2 && oldStatus !== newStatus) {
|
||||
if (newStatus === "2") {
|
||||
// Status Sukses
|
||||
console.log('🎉 [STORE] Status 2 (SUKSES) diterima. Pindah ke Step 3.');
|
||||
this.currentStep = 3;
|
||||
this.startAutoReset();
|
||||
} else if (newStatus === "0") {
|
||||
// Status Gagal
|
||||
console.log('❌ [STORE] Status 0 (GAGAL) diterima. Pindah ke Step 4.');
|
||||
this.currentStep = 4;
|
||||
this.startAutoReset();
|
||||
}
|
||||
}
|
||||
// ------------------------------------------------------
|
||||
|
||||
|
||||
console.log("Updated qrData:", this.qrData);
|
||||
console.log("Updated patientInfo:", this.patientInfo);
|
||||
console.log("===================");
|
||||
@@ -170,8 +179,8 @@ export const usePaymentStore = defineStore('payment', {
|
||||
},
|
||||
|
||||
// Method untuk validasi data
|
||||
validateData() {
|
||||
const issues = [];
|
||||
validateData(): boolean {
|
||||
const issues: string[] = [];
|
||||
|
||||
if (!this.qrData.display_nobill) {
|
||||
issues.push('display_nobill missing');
|
||||
@@ -181,7 +190,8 @@ export const usePaymentStore = defineStore('payment', {
|
||||
issues.push('display_name missing');
|
||||
}
|
||||
|
||||
if (!this.qrData.qrvalue && !this.qrData.qr_code) {
|
||||
// Perlu pengecekan properti qr_code pada apiData, bukan state
|
||||
if (!this.qrData.qrvalue) {
|
||||
issues.push('QR code missing');
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user