feat/payment-ux-story-1-1 #14

Merged
root merged 7 commits from feat/payment-ux-story-1-1 into dev 2025-11-28 01:14:26 +00:00
2 changed files with 150 additions and 140 deletions
Showing only changes of commit d08b0bd312 - Show all commits

View File

@ -5,6 +5,8 @@ import React from 'react'
import { PaymentInstructions } from './PaymentInstructions' import { PaymentInstructions } from './PaymentInstructions'
import { postCharge } from '../../../services/api' import { postCharge } from '../../../services/api'
import { InlinePaymentStatus } from './InlinePaymentStatus' import { InlinePaymentStatus } from './InlinePaymentStatus'
import { LoadingOverlay } from '../../../components/LoadingOverlay'
import { mapErrorToUserMessage } from '../../../lib/errorMessages'
type StoreKey = 'alfamart' | 'indomaret' type StoreKey = 'alfamart' | 'indomaret'
@ -36,7 +38,7 @@ export function CStorePanel({ orderId, amount, locked, onChargeInitiated, defaul
if (typeof res?.store === 'string') setStoreFromRes(res.store) if (typeof res?.store === 'string') setStoreFromRes(res.store)
} }
} catch (e) { } catch (e) {
if (!cancelled) toast.error(`Gagal membuat kode pembayaran: ${(e as Error).message}`) if (!cancelled) toast.error(mapErrorToUserMessage(e))
} finally { } finally {
if (!cancelled) setBusy(false) if (!cancelled) setBusy(false)
cstoreTasks.delete(chargeKey) cstoreTasks.delete(chargeKey)
@ -60,7 +62,7 @@ export function CStorePanel({ orderId, amount, locked, onChargeInitiated, defaul
if (typeof res?.store === 'string') setStoreFromRes(res.store) if (typeof res?.store === 'string') setStoreFromRes(res.store)
} }
} catch (e) { } catch (e) {
if (!cancelled) toast.error(`Gagal membuat kode pembayaran: ${(e as Error).message}`) if (!cancelled) toast.error(mapErrorToUserMessage(e))
attemptedCStoreKeys.delete(chargeKey) attemptedCStoreKeys.delete(chargeKey)
} finally { } finally {
if (!cancelled) setBusy(false) if (!cancelled) setBusy(false)
@ -78,6 +80,8 @@ export function CStorePanel({ orderId, amount, locked, onChargeInitiated, defaul
} }
return ( return (
<>
<LoadingOverlay isLoading={busy} message="Sedang membuat kode pembayaran..." />
<div className="space-y-3"> <div className="space-y-3">
<div className="font-medium">Convenience Store</div> <div className="font-medium">Convenience Store</div>
{selected && ( {selected && (
@ -126,5 +130,6 @@ export function CStorePanel({ orderId, amount, locked, onChargeInitiated, defaul
<InlinePaymentStatus orderId={orderId} method="cstore" /> <InlinePaymentStatus orderId={orderId} method="cstore" />
</div> </div>
</div> </div>
</>
) )
} }

View File

@ -6,6 +6,8 @@ import { GoPayLogosRow } from './PaymentLogos'
import { postCharge } from '../../../services/api' import { postCharge } from '../../../services/api'
import { InlinePaymentStatus } from './InlinePaymentStatus' import { InlinePaymentStatus } from './InlinePaymentStatus'
import { toast } from '../../../components/ui/toast' import { toast } from '../../../components/ui/toast'
import { LoadingOverlay } from '../../../components/LoadingOverlay'
import { mapErrorToUserMessage } from '../../../lib/errorMessages'
// Global guards/tasks to stabilize QR generation across StrictMode remounts // Global guards/tasks to stabilize QR generation across StrictMode remounts
const attemptedChargeKeys = new Set<string>() const attemptedChargeKeys = new Set<string>()
@ -52,7 +54,9 @@ export function GoPayPanel({ orderId, amount, locked, onChargeInitiated }: { ord
} }
} }
return ( return (
<>
<div className="space-y-3"> <div className="space-y-3">
<LoadingOverlay isLoading={busy} message="Sedang membuat kode QR..." />
<GoPayPanel_AutoEffect <GoPayPanel_AutoEffect
orderId={orderId} orderId={orderId}
amount={amount} amount={amount}
@ -147,6 +151,7 @@ export function GoPayPanel({ orderId, amount, locked, onChargeInitiated }: { ord
</div> </div>
</div> </div>
</div> </div>
</>
) )
} }
@ -175,7 +180,7 @@ export function GoPayPanel_AutoEffect({ orderId, amount, locked, mode, setBusy,
onChargeInitiated?.() onChargeInitiated?.()
} }
} catch (e) { } catch (e) {
if (!cancelled) toast.error(`Gagal membuat QR: ${(e as Error).message}`) if (!cancelled) toast.error(mapErrorToUserMessage(e))
} finally { } finally {
if (!cancelled) { if (!cancelled) {
setBusy(false) setBusy(false)
@ -204,7 +209,7 @@ export function GoPayPanel_AutoEffect({ orderId, amount, locked, mode, setBusy,
onChargeInitiated?.() onChargeInitiated?.()
} }
} catch (e) { } catch (e) {
if (!cancelled) toast.error(`Gagal membuat QR: ${(e as Error).message}`) if (!cancelled) toast.error(mapErrorToUserMessage(e))
attemptedChargeKeys.delete(chargeKey) attemptedChargeKeys.delete(chargeKey)
} finally { } finally {
if (!cancelled) { if (!cancelled) {