diff --git a/apps/machine/src/views/CashInView.vue b/apps/machine/src/views/CashInView.vue index 2ab193f..47c0eb2 100644 --- a/apps/machine/src/views/CashInView.vue +++ b/apps/machine/src/views/CashInView.vue @@ -16,15 +16,19 @@ const atmStore = useAtmStore() const isElectron = typeof window !== 'undefined' && window.electronAPI !== undefined // Whether the header cancel button should be visible -// Hide after bills are inserted — state machine routes to confirmAbandon instead +// State machine routes CANCEL to confirmAbandon when bills are present const showCancelButton = computed(() => { const state = atmStore.nestedState - const hasBills = (atmStore.context?.billsInserted.length ?? 0) > 0 - // Show in fetchingRate (no bills yet) and insertingBills only before bills are in - if (state === 'fetchingRate') return true - if (state === 'insertingBills' && !hasBills) return true - if (state === 'error' && !hasBills) return true - // Hide when bills are in the cash box + // Show cancel in states where user might want to exit + // State machine handles routing: no bills → idle, bills → confirmAbandon + if ( + state === 'fetchingRate' || + state === 'insertingBills' || + state === 'generatingNdebit' || + state === 'displayingQR' || + state === 'error' + ) + return true return false }) diff --git a/packages/state-machine/src/machine.ts b/packages/state-machine/src/machine.ts index 02edb04..39fa61f 100644 --- a/packages/state-machine/src/machine.ts +++ b/packages/state-machine/src/machine.ts @@ -449,7 +449,6 @@ export function createATMMachine( }, }, generatingNdebit: { - // No CANCEL here — bills are already in the cash box invoke: { src: 'generateNdebit', input: ({ context }) => context, @@ -465,8 +464,14 @@ export function createATMMachine( actions: 'setError', }, }, + on: { + CANCEL: 'confirmAbandon', + }, }, displayingQR: { + after: { + TIMEOUT_MS: 'confirmAbandon', + }, on: { PAYMENT_RECEIVED: { target: 'askForReceipt',