From fa2d439ea4b0154cec586b5f3a4859b8b379f631 Mon Sep 17 00:00:00 2001 From: bagus-arie05 Date: Fri, 17 Oct 2025 15:12:20 +0700 Subject: [PATCH] update komponen --- assets/qrislogo.png | Bin 0 -> 6905 bytes assets/rssalogo.png | Bin 0 -> 6186 bytes components/Home.vue | 89 ++++++----- components/PembayaranGagal.vue | 23 ++- components/PembayaranSukses.vue | 35 ++-- components/QRISPayment.vue | 225 +++++++++++++++++++++----- composables/useWebSocket.js | 79 +++++++++ composables/useWebSocket.ts | 43 ----- config/websocket.js | 185 ++++++++++++++++++++++ nuxt.config.ts | 10 +- package-lock.json | 1 + package.json | 1 + pages/SetupIP.vue | 2 +- pages/index.vue | 273 ++++++++++++++++---------------- stores/payment.ts | 88 +++++++--- 15 files changed, 747 insertions(+), 307 deletions(-) create mode 100644 assets/qrislogo.png create mode 100644 assets/rssalogo.png create mode 100644 composables/useWebSocket.js delete mode 100644 composables/useWebSocket.ts create mode 100644 config/websocket.js diff --git a/assets/qrislogo.png b/assets/qrislogo.png new file mode 100644 index 0000000000000000000000000000000000000000..80723ffdf49bd23c76871e8c85347c0c8b369f3e GIT binary patch literal 6905 zcmbtZ^-~m%)25~KfFlKw7C1suI*#rJ@c`lIZs{%oQM$WBrSn5~cjq0QN9XJNH+*;I z*=KfVc6R3ZX(LKq6^w^XiH(GWgr^`cqxp|-|3L{8lte@SFlO|TSF^*HsxzW@y?sUnGl^gABs$rK$4i84+>MpD}g`Q$U!FJqmwj$00$ zwJh{R)yP01OrW|pT_7lTyYxdrJ_|6k;2n?fAc#T!*T>jkRQ!=mTta;OKaoAc)E-@7 zCv?Gql|5{dnDq1sNeON`?XU;G+jYI`7R|ZObD!7THvRY7s&7vpHej!30k5rf|4RQy zW58ymrl#)yv}~bGt6#o zQhQ!cHkcv7D9!ElNzjCBzNW$(?6+8N-b6H_W&?#;fSOyI=i|Y4mmTY-f}c8ltM!d%Eq_WdxTd90g3I=`R)wPM!WBHV-%hnn> zPq^O{)~yCfTSL9CIsf%=%M$&fOH_um6yk`^cV2QKS zkgnQ@GfBcsrk%S|-+RofLxDt1YX+KP^}FBaZRUNLD9SoPoh>C5|9@c6)>Jn<_JPfFxS+byXE-$&e@1FKZ=plW7~ zYMP8fdPBFG65jbFp{C>l40gmy)K)2sV(@G0VX`@FB_gLgwu$o2q`dOmids6GIIh}w zQN87$b$vE8$pduZ;#)(45um$!Xll{%#Bfn4l%5V@h>g`_a0|X=E)ZN-U>YKtcl;!G zoN@d}$-|!tH~Y2o_pW+hm=nNB{w!im{C}2(;weoKUO2dyvvfxRL+sq&D{^h`h|D;lZ<+MgWoC_nZbD3Ai~dta5Ttiv2VJ3 zhcu>-W6K{G?auO!(|{7!RV{Tg=Bh)|kjN2AH32njvD2rMTm5<7`Wq;{-#eI<(#wDz zwQS5tje$~MP{0~G*r?I`MAW3fH=cu9WQnmx-17zOrHqyClF5>Adil(bG5rktVX#oku5bW{r4yg{^B%^iEEiTIt9GIS}GQ}mg)yZ0|;EVfv6_JKu9 z(A?kD*l-anqQ+V4eA---FVTD@QJ_^^!+|PVz8V>3xUD_m@@Q0QVrKYN2ezp*v;8Mu)9c6#@1$745P)aiL1ojWZzeH41}{oV?wUPyV1qwV_zx=QF@ZWV$XE zy@Rw6O$&-}J!$>QKKW*-X4xuA;~rr+EQ;{fXY$1s;Dli%gc@vR)FfUpgWEGB`N&hD zQm$P_etwB&LIUCi8;usXvCA`OM-aZ!YfxPQ_MbrAoWX0`yetD<)3ZA-xFOcvY`qF~ zB>P>iIY4Qr(P!1*U(317M|cj-tAqQbd0LKm*ALQOdXPe`Fz&=TKG66G-eOQvDR%?0 zy15XWYg06P(i+h#IkBrB2kxgcbNR1tCU=4k;v8jE|yIg`6p&# zFs;l@w@2-Z=Tt#4f7EOa(-hM*%+M@ zicZLUqhd{EMLG~QZq-90xe_XobU@UPKcj1$D(xeSv!cUl+(#z`9&uq6dZo_Z>gLmS zH{tJ&Tng$vpX5zoPCX)>#SyufpO4BCP!K))X=txo?n8!D7wYqJ>@C9Z^aHpBcR?eq zzb{Vc5Z`E^2uKuOhl<4siBAP8qa%>_`^p@oM#_?!l~} zbOjHtyW^qn9+Ndm5?)X+^KrCTI~i1b*zHqm4Z$s&Lo@l|mh2P-aSb9=$@HfvA#dXs z`t18Ev{fToJhFh0ArwS*QQp}`xJ{;@gr;ec_Cw%4VQzBroYeQb82@1eH17OtIK8ESpV0VuqYdzu2*#g5l2ryn1E$dTHf4$Nju=@*UsNL)O{XJCVy2Bgk$YbRKPsrXMlrQnJ5uhiKNm(%lL+hlDNmI zfrod4Q6J_-fQzCR*btJgt>ZryP&S9HA2*@M#VV!QU>jYxyU|?2+(Il4|NJhOzK77(>Of+2ZHT7o!)vLXrUVmfW&15=#XEc~ z%R-xmS(H|_Cy}d3@RX!y;IQZ$j6$L1h~g4I&!A3bFu$?X|lFChr_zgyu zN78hK88-&Ze4R*vskn6jN>I^?{!WZ6!d@GJxusuyz%roX?k*_|c4?TI$i?3GY_*NQvOqpKQuBn4Rc>&D}$qA*s zL-9|US`5SfmW&Kp@<&SEvfcFH$9}<1O~Cjto<<-Y;5X!P>1%`r>BV_xj_eP3e!%+_ zAlp(Rq5cKGXI_sE2&b=-9rR`OKMN|#JQOKj9=ax!+d!pZr$Zx?lwKro8wJxg@|see z;@`E$c{v6rKT153%T)O>*0npXz*@qT-#P^R*Ooq_QnTevi+D0mc;UJ0EY9DT|LQ~7 zk+NAPA)gh<(~fC>fFJrfcn>|aRj*O9S-A=!inR+1)J2jd4r6_tM z|EMx6W4btcM%+hYc*8u2;d?pW-x=yI4)Of1Go&e#7z;|op2K0|uoP=wbd447)cYcp zZJ*>~IsaK7MfbY+8wfX@u<4R*nZ&;SqZB1=w`Y~uK`NWpGd$9RFkHY~JC!XQ%Ocr8 zZUpIFUU4=3BRNTgOjjiBYDTeU06pr1?S8b8OZGg*0B|&n1THiMo z;9Iho+jm=x`mBpel>vjm8l~A&Y)BUCNyk<=N$+sdYSet(wb8=I`GtW0U|=987g<&W z@!DEOxZ*P{e+6@GqH8V?-ER0hCX4>-8wdTDhc>*QCp(O&fMb&7v;0zyimzaFD$zOn zkioO1ho{=m;>JXbwKb)StWAZ5Jgigwz0aIB8G;xgwC&A+c{&aldCUZC7>uh#(&aLD z|NXKI4z+TOtF9h1ASlh@`}W~GRrC$luvM(o7OI`2SpKySwbp-{hj9(r`ZWUDYppHt z8BxsOHJJNkvvsoQ{HOkNGq-v4*&xVDDQU9P^hn(8q zdU;gdfE+SJH!>@^MYVe#$V%zdZkwl{%f%SRJ!nx_i2?j(1S0;K8-=C z$dZrcAU;crF~|s()^9EBtSSi;OdmMY+)0j5Be^_HAbQB{^xh zZcVI+ISZ_j~c6;)c19NPJSD7%(+O!G=E_n>KQ&h(pOIj zcxj(<;~EXKB~#1y`j;({qJ%)B2qq`9W% zpu3oa%@w29t$Asv9r-H#9OVT<<8fPycOVU9ZTY0pi^?y`B^sw~JTqpM$uYHl7^rxH(Q~cgBAM zto^W0YtBCiG-h?j>%HTCvGo$%b}}cd@p-_08j%EMtKbn7OlkTRk~lwASFQ%x+`We3uJTa*98H zMECu>t~PKs($W#r2ex14UX7QeNQPbqU7EZ%{L6aHRSXm>P3F@6{$a!VK?LT#Ixjfs z{*f3FA+aA~dW|NPYQ1`!)Gtr!MAtTT*zYB)_HWj|i%EE$9#{ z4^(mw1g&zOKM#2AlDHEcj*#8iSC>&nsMduuke#Dt6J!|Cm!}gp#xA6yG%|;an zq$B+Bn@45d-lyRP7mRAy(m-)qTQ4Si5!v{k;=AcrCOGVIcsKMUoBygx8a@eN(Y$F3c1>m(X%fIqR zKIs13Q~&gghpMS6Xv+^a)p4=89Qe zs$uxPfYdXKe)9nt<~6h}&RKWl;;@9=tqXjbd4w3_DEjw@L6*?%Q_RjJK8y*@(#93t z{QaMiTAR(*PDfbjViPM2sxv~})ZmXNC*Hi*^a(7&cv6q9tHd#aMqPUze!qkFPU1in zb|yUE^HEvbE=Id&a4gqR+|J5Gla@;jIjn3;`#U9k(EWOoV@c3fK34Yd!HNh3E+8ri z#R8?rg$0^BJBqMlmN-wD&nmKp85#CT=~&+i+vzc2t=KO=&9gN>kd?p^}Z!U^wEDpJe+yJ4n=G{-A=wz*w|zHp8Y((u%6REfRGf0no} znx>w(0+n+}fbTIoIxW|rW@yko5#3w83GT?&%6_Uwb#c}ngA{5|9OU=)6w4|l2tF~X{Xnzvj(2Cr}^$dFd$U;n$onzGHFD=V2 ztc~3)forp-wYgGkgnt=Ya4j1nCAqWNV~(N*-_wQ~Fu3?hJEEmrb{a5QI24oS4^fi_ zpM*fRrLV@~H60@A#D2`>~hD-uT%)G zlN|1;p67%K9MK~G2h&Hxnp!?uR&DCEQ6l_j8yCY)og=gjvJIo}u5}fC6UDF)n zO86^nL29oNqh{>0a{dv9{U6i-jW_HlN-5@IV!M_%l?lUM8m+oFjcoh z#3Z7+r_|MH`nAx6p_13kDQ?tt9vGHW;`IJjN+n>?hY2#+N0_=X9DLMiExa(_nJrxc z&+M|~Z;#$SVb*-Hev#;D?B=6h)WI~;HB(5^i^~mJ@{_FL~BmB<@yJ9py zdXWdIv^SK=woy(8T zrdPw4UJum3jaGo-zY~xOtPcB_<3$UMc(CIXMa`V8P)9)UTQn$L``CY`I2WI5VI#?v zK3DB~9ttm)|u%xGgHb6J&eMY z{C0UHouN5>WlQH57}~3NrtNz?n&mUMZO3u$VoTSWj`ZtcZabvoESM99KeHXE8dz*# z3(H}A0v%Up=96e{wDk|hac*36Yr_6{Agu0lTj94GuML|PaeU=zb){t=klQyxBoRE} z5y>vNtIV@@{`pjfGdJlx%HPz%8}%vrPuM3;REH3Aqnx#5!7qF0Ni=>}x?YtsnPn_H zW5*E<_DtOphf7YVCXGpXB=auqfdnY3az*tYx1a}*NJTc-rC1utEFW!ej_zAP7Tj0g zK!^)2PS%ba9;G5%jasl=vgl^=mJTdxQ;_(AMH5mEVelc*J_fvhqT-uWC=Ps)Ockef z*z@F;*)HQXEjSQuFJBxYCr zICCqU_Ylw|FXn0bxZyFkel3m^h7aHnP&h%s($b0PyyYj#J ziu-#lI_%PlL_*qx3|wBh z=Y2EKgS+C6dNWwet=_FGxT-|pn~ib{;O_4r-iaMG58swZRFRy04Rp5tvCiXJo98Tu z=y`1&v(Hxw4UtBT{a7~Pt?wV;?qL?Qu|zaQB=Fj)0z9l@I^_qv`Clz!YunN51)&+H TSe*LrQ-!1;t14411quE?5+Nrd literal 0 HcmV?d00001 diff --git a/assets/rssalogo.png b/assets/rssalogo.png new file mode 100644 index 0000000000000000000000000000000000000000..7f0842d71f1ca9caa9efd30ca65ff981445f469e GIT binary patch literal 6186 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 IM6N<$f{|j->;M1& literal 0 HcmV?d00001 diff --git a/components/Home.vue b/components/Home.vue index 44219b7..da91ec5 100644 --- a/components/Home.vue +++ b/components/Home.vue @@ -83,11 +83,7 @@ @error="onVideoError" > -
+
Video thumbnail
-
+
@@ -175,7 +171,7 @@ const carouselItems = ref([ isImage: false, }, { - src: "https://scontent.fcgk22-2.fna.fbcdn.net/v/t39.30808-6/481267190_3904366386504845_1409667601717073976_n.jpg?stp=dst-jpg_s960x960_tt6&_nc_cat=110&ccb=1-7&_nc_sid=cc71e4&_nc_ohc=w6wAp5Df1lAQ7kNvwHL8Snq&_nc_oc=Adnq0LOV2vro6n7DGZu9GfUYGx3iBXzZ7LlUk7oWYi_lZ_OYDD7LVYe5zogYKxEEJdU&_nc_zt=23&_nc_ht=scontent.fcgk22-2.fna&_nc_gid=Dir3R7zaEbm2b0HPtrmGiQ&oh=00_AfaERSA1GyvNKkfajBF5yIv_JrijpizdmUqgy9528oAszQ&oe=68D12398", + src: "https://rsusaifulanwar.jatimprov.go.id/wp-content/uploads/2023/08/siam-2-scaled.jpg", alt: "Medical Services", title: "Pelayanan Terbaik", description: "Tim medis profesional siap melayani 24 jam", @@ -184,31 +180,30 @@ const carouselItems = ref([ ]); const getYouTubeEmbedUrl = (videoId) => { - const baseUrl = 'https://www.youtube.com/embed/'; + const baseUrl = "https://www.youtube.com/embed/"; const params = new URLSearchParams({ - autoplay: '1', - mute: '0', - controls: '1', - modestbranding: '1', - rel: '0', - showinfo: '0', - fs: '1', - cc_load_policy: '0', - iv_load_policy: '3', - autohide: '0' + autoplay: "1", + mute: "0", + controls: "1", + modestbranding: "1", + rel: "0", + showinfo: "0", + fs: "1", + cc_load_policy: "0", + iv_load_policy: "3", + autohide: "0", }); return `${baseUrl}${videoId}?${params.toString()}`; }; const onVideoLoad = () => { - console.log('Video iframe loaded successfully'); + console.log("Video iframe loaded successfully"); }; const onVideoError = (error) => { - console.error('Video iframe error:', error); + console.error("Video iframe error:", error); }; -// Fungsi untuk memulai carousel otomatis const startCarousel = () => { if (carouselInterval.value) { clearInterval(carouselInterval.value); @@ -216,10 +211,9 @@ const startCarousel = () => { carouselInterval.value = setInterval(() => { const nextSlide = (currentSlide.value + 1) % carouselItems.value.length; currentSlide.value = nextSlide; - }, 10000); // Ganti gambar setiap 10 detik + }, 10000); }; -// Fungsi untuk menghentikan carousel otomatis const stopCarousel = () => { if (carouselInterval.value) { clearInterval(carouselInterval.value); @@ -227,40 +221,33 @@ const stopCarousel = () => { } }; -// Fungsi untuk memutar video (menghentikan carousel) const playVideo = (index) => { currentSlide.value = index; - stopCarousel(); // Hentikan carousel saat video diputar + stopCarousel(); }; -// Tonton perubahan slide watch(currentSlide, (newSlide) => { const currentItem = carouselItems.value[newSlide]; if (currentItem && !currentItem.isImage) { - // Jika slide adalah video, hentikan carousel - console.log('Video detected, stopping carousel'); + console.log("Video detected, stopping carousel"); stopCarousel(); } else { - // Jika slide adalah gambar, mulai kembali carousel - console.log('Image detected, starting carousel'); + console.log("Image detected, starting carousel"); startCarousel(); } }); onMounted(() => { - // Mulai carousel saat komponen dimuat startCarousel(); }); onUnmounted(() => { - // Hentikan carousel saat komponen dihancurkan stopCarousel(); }); -// Fungsi untuk simulasi pembayaran debug const startDebugPayment = () => { console.log("Simulasi Pembayaran (Debug) dimulai."); - // Mengisi data dummy untuk simulasi + const dummyData = { posdevice: "GRANDPAV", invoice_number: "000000000000012000615", @@ -268,14 +255,15 @@ const startDebugPayment = () => { created_at: "2024-11-21T11:52:25.805965+07:00", display_name: "KASIH", id: "1", - status: "1", // Status awal untuk simulasi + status: "1", display_amount: "90", - qrvalue: "000201010212262710019ID.CO.BANKJATIM.WWW01189360011400001347728215ID02400134529083038ES1459015ID.OR.GPMQR.MM0215ID202431094996960309ES2049939530536054029605802D5923-RSUD SAIFUL ANWAR MLG-100000MALANG0556111622901250000000000000000000000000000012800061563040C9B", + qrvalue: + "000201010212262710019ID.CO.BANKJATIM.WWW01189360011400001347728215ID02400134529083038ES1459015ID.OR.GPMQR.MM0215ID202431094996960309ES2049939530536054029605802D5923-RSUD SAIFUL ANWAR MLG-100000MALANG0556111622901250000000000000000000000000000012800061563040C9B", ip: "10.10.150.106", display_nobill: "24072579/10000675", }; paymentStore.updatePayment({ data: [dummyData] }); - paymentStore.currentStep = 2; // Pindah ke QRISPayment + paymentStore.currentStep = 2; }; @@ -388,10 +376,13 @@ const startDebugPayment = () => { width: 100%; height: 100%; position: relative; - background: #000; + + background: white; display: flex; align-items: center; justify-content: center; + /* PASTIKAN INI ADA untuk membatasi iframe */ + overflow: hidden; } .youtube-iframe { @@ -399,8 +390,26 @@ const startDebugPayment = () => { height: 100%; border: none; border-radius: 15px; + + position: absolute; + top: 50%; + left: 50%; + + transform: translate(-50%, -50%); + + min-width: 100%; + min-height: 100%; + + aspect-ratio: 16 / 9; } +.thumbnail-img { + width: 100%; + height: 100%; + + object-fit: cover; + border-radius: 15px; +} .video-thumbnail { width: 100%; height: 100%; @@ -558,4 +567,4 @@ const startDebugPayment = () => { :deep(.v-carousel__controls--bottom) { bottom: 40px !important; } - \ No newline at end of file + diff --git a/components/PembayaranGagal.vue b/components/PembayaranGagal.vue index 9273fa7..3f01666 100644 --- a/components/PembayaranGagal.vue +++ b/components/PembayaranGagal.vue @@ -12,6 +12,19 @@

Terjadi kesalahan saat memproses
pembayaran Anda.

+
+ + mdi-home + Kembali ke Awal + +
- \ No newline at end of file + diff --git a/stores/payment.ts b/stores/payment.ts index 746ae20..642b359 100644 --- a/stores/payment.ts +++ b/stores/payment.ts @@ -1,21 +1,26 @@ // src/stores/payment.js import { defineStore } from 'pinia'; +// Variabel di luar store untuk menyimpan timer, agar persistensi di luar state Pinia +let autoResetTimer = null; + export const usePaymentStore = defineStore('payment', { state: () => ({ - currentStep: 1, + currentStep: 1, // 1: Menunggu Data, 2: Tampilkan QRIS, 3: Sukses, 4: Gagal patientInfo: { name: '', amount: '', - expiry: '', + expiry: '', // Dibiarkan kosong, waktu kedaluwarsa dihitung dari qrData.created_at }, qrData: { qrvalue: null, display_nobill: null, display_name: null, display_amount: null, - status: null, // Tambahkan status untuk tracking - ip: null, // Tambahkan IP untuk reference + status: null, // Status pembayaran: "1" (Pending), "2" (Sukses), "0" (Gagal/Expired) + ip: null, + created_at: null, // Tambahkan ini agar properti ada secara eksplisit + // ... properti lain dari API akan ditambahkan melalui spread operator }, }), @@ -23,12 +28,12 @@ export const usePaymentStore = defineStore('payment', { hasQrData: (state) => state.qrData && state.qrData.qrvalue, safeQrValue: (state) => state.qrData?.qrvalue || 'https://www.google.com', - // Getter untuk cek apakah data siap untuk polling status + // Getter untuk cek apakah data siap isReadyForStatusCheck: (state) => { return state.qrData.display_nobill && state.qrData.display_name; }, - // Getter untuk informasi debug + // Getter untuk debug debugInfo: (state) => ({ step: state.currentStep, hasIdentifiers: !!(state.qrData.display_nobill && state.qrData.display_name), @@ -46,12 +51,29 @@ export const usePaymentStore = defineStore('payment', { }, setStep(step) { - console.log(`Setting step from ${this.currentStep} to ${step}`); + 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.'); + + + autoResetTimer = setTimeout(() => { + console.log('🏠 [STORE] Auto return to home triggered'); + this.reset(); + }, 20000); + }, reset() { - console.log('Resetting payment store'); + console.log('--- [STORE] Resetting payment store ---'); this.currentStep = 1; this.patientInfo = { name: '', @@ -65,25 +87,26 @@ export const usePaymentStore = defineStore('payment', { display_amount: null, status: null, ip: null, + created_at: null, }; + if (autoResetTimer) { + clearTimeout(autoResetTimer); + autoResetTimer = null; + } }, updatePayment(apiResponse) { - console.log("=== UPDATE PAYMENT ==="); - console.log("API Response:", apiResponse); + console.log("=== [STORE] UPDATE PAYMENT ==="); // Validasi response if (!apiResponse?.data || !Array.isArray(apiResponse.data) || apiResponse.data.length === 0) { - console.error("Invalid API response structure"); + console.error("Invalid API response structure or empty data array"); return; } const apiData = apiResponse.data[0]; - console.log("API Data:", apiData); - - // Simpan data lama untuk comparison - const oldQrData = { ...this.qrData }; - + const oldStatus = this.qrData.status; // Simpan status lama + // Update qrData dengan semua properti dari API this.qrData = { qrvalue: apiData.qrvalue || apiData.qr_code || this.qrData.qrvalue, @@ -92,22 +115,43 @@ export const usePaymentStore = defineStore('payment', { display_amount: apiData.display_amount || apiData.nominal || this.qrData.display_amount, status: apiData.status || this.qrData.status, ip: apiData.ip || this.qrData.ip, - // Spread untuk properti lain yang mungkin ada + created_at: apiData.created_at || this.qrData.created_at, // Ambil 'created_at' + // Spread untuk properti lain yang mungkin ada (misal: transaction_id, reason) ...apiData }; // Update patientInfo this.patientInfo = { - name: apiData.display_name || this.patientInfo.name || 'Unknown', - amount: apiData.display_amount || apiData.nominal || this.patientInfo.amount || '0', + name: this.qrData.display_name || this.patientInfo.name || 'Unknown', + amount: this.qrData.display_amount || this.patientInfo.amount || '0', expiry: this.patientInfo.expiry, }; - // Log changes - if (oldQrData.status !== this.qrData.status) { - console.log(`Status changed: ${oldQrData.status} -> ${this.qrData.status}`); + // --- 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("===================");