- {{ $t('thank-you-card.receive.pin-subtitle', { amount: amount }) }}
+
+
+ {{ $t('thank-you-card.receive.amount', { amount: amount }) }}
-
-
- {{ $t('thank-you-card.receive.card', { label: cardLabel }) }}
+
+
+ {{ cardLabel }}
+
{{ $t('thank-you-card.receive.thanks') }}
-
- {{ $t('thank-you-card.receive.received', { amount: amount, name: payerName }) }}
+
+ {{ $t('thank-you-card.receive.amount', { amount: amount }) }}
+
+
+ {{ $t('thank-you-card.receive.sent-from-to', { from: payerName, to: recipientName }) }}
{{ $t('thank-you-card.receive.next-payment') }}
@@ -144,8 +174,9 @@
* which one it is still holding.
*/
import { BButton, BFormCheckbox, BFormInput } from 'bootstrap-vue-next'
-import { computed, nextTick, onMounted, ref } from 'vue'
+import { computed, nextTick, onMounted, ref, watch } from 'vue'
import { useI18n } from 'vue-i18n'
+import { useStore } from 'vuex'
import { useMutation, useQuery } from '@vue/apollo-composable'
import { useRoute } from 'vue-router'
import {
@@ -165,6 +196,7 @@ const pinType = pinInputType()
const route = useRoute()
const { t } = useI18n()
+const store = useStore()
const { toastError } = useAppToast()
const { readRememberedMemo, writeRememberedMemo } = useThankYouCardMemo()
@@ -181,6 +213,17 @@ const payerName = ref('')
const busy = ref(false)
const targetStatus = ref(null)
const cardLabel = ref('')
+const pinField = ref(null)
+
+/**
+ * Whoever is signed in on this device, which on this page is always the RECIPIENT -- the
+ * merchant. Read from the store rather than asked of the server: the wallet has known it
+ * since the login, and the closing screen has to name both sides (see the comment on the
+ * done step) without a round trip at the moment the phone changes hands.
+ */
+const recipientName = computed(() =>
+ `${store.state.firstName ?? ''} ${store.state.lastName ?? ''}`.trim(),
+)
const unusable = computed(() => targetStatus.value !== null && targetStatus.value !== 'SUCCESS')
const statusKey = computed(() => targetStatus.value ?? 'CARD_UNKNOWN')
@@ -214,6 +257,23 @@ onMounted(() => {
memo.value = readRememberedMemo()
})
+/**
+ * The cursor waits in the field, so the payer can start typing the moment the phone reaches
+ * them. At a counter that saves the one step nobody should have to be told about — the
+ * merchant hands the phone over and the keyboard is already up.
+ *
+ * `nextTick` because the step is a `v-else-if` branch: at the moment `step` changes, the
+ * field does not exist yet. And `focus` is the method BFormInput exposes for exactly this
+ * (`__expose({ blur, element: input, focus })`), so there is no reaching through `$el`.
+ */
+watch(step, async (value) => {
+ if (value !== 'pin') {
+ return
+ }
+ await nextTick()
+ pinField.value?.focus()
+})
+
const startPayment = async () => {
busy.value = true
try {