polish: withdraw flow fixes (#4713)

* fix: negative value stuff

* fix: mobile responsiveness for modal min-w

* feat: better error handling on withdraw

* fix: empty state positioning + svg sizing

* fix: title case -> sentence case

* fix: re-add virtual visa under gift cards

* fix: hide <1% segments
This commit is contained in:
Calum H.
2025-11-04 21:29:47 +00:00
committed by GitHub
parent 6e47de06bb
commit f054f39c5d
9 changed files with 285 additions and 121 deletions

View File

@@ -38,7 +38,7 @@
</template>
</div>
</template>
<div class="w-full max-w-[496px] lg:min-w-[496px]">
<div class="mx-auto w-full max-w-[496px] sm:mx-0 sm:min-w-[496px]">
<TaxFormStage
v-if="currentStage === 'tax-form'"
:balance="balance"
@@ -326,6 +326,73 @@ function continueWithLimit() {
setStage(nextStep.value)
}
// TODO: God we need better errors from the backend (e.g error ids), this shit is insane
function getWithdrawalError(error: any): { title: string; text: string } {
const description = error?.data?.description?.toLowerCase() || ''
// Tax form error
if (description.includes('tax form')) {
return {
title: formatMessage(messages.errorTaxFormTitle),
text: formatMessage(messages.errorTaxFormText),
}
}
// Invalid crypto wallet address
if (
(description.includes('wallet') && description.includes('invalid')) ||
description.includes('wallet_address') ||
(description.includes('blockchain') && description.includes('invalid'))
) {
return {
title: formatMessage(messages.errorInvalidWalletTitle),
text: formatMessage(messages.errorInvalidWalletText),
}
}
// Invalid bank details
if (
(description.includes('bank') || description.includes('account')) &&
(description.includes('invalid') || description.includes('failed'))
) {
return {
title: formatMessage(messages.errorInvalidBankTitle),
text: formatMessage(messages.errorInvalidBankText),
}
}
// Invalid/fraudulent address
if (
description.includes('address') &&
(description.includes('invalid') ||
description.includes('verification') ||
description.includes('fraudulent'))
) {
return {
title: formatMessage(messages.errorInvalidAddressTitle),
text: formatMessage(messages.errorInvalidAddressText),
}
}
// Minimum amount not met
if (
description.includes('payoutminimumnotmeterror') ||
description.includes('minimum') ||
(description.includes('amount') && description.includes('less'))
) {
return {
title: formatMessage(messages.errorMinimumNotMetTitle),
text: formatMessage(messages.errorMinimumNotMetText),
}
}
// Generic fallback
return {
title: formatMessage(messages.errorGenericTitle),
text: formatMessage(messages.errorGenericText),
}
}
async function handleWithdraw() {
if (isSubmitting.value) return
@@ -336,19 +403,12 @@ async function handleWithdraw() {
} catch (error) {
console.error('Withdrawal failed:', error)
if ((error as any)?.data?.description?.toLower?.()?.includes('Tax form')) {
addNotification({
title: 'Please complete tax form',
text: 'You must complete a tax form to submit your withdrawal request.',
type: 'error',
})
} else {
addNotification({
title: 'Unable to withdraw',
text: 'We were unable to submit your withdrawal request, please check your details or contact support.',
type: 'error',
})
}
const { title, text } = getWithdrawalError(error)
addNotification({
title,
text,
type: 'error',
})
} finally {
isSubmitting.value = false
}
@@ -453,5 +513,58 @@ const messages = defineMessages({
id: 'dashboard.withdraw.completion.transactions-button',
defaultMessage: 'Transactions',
},
errorTaxFormTitle: {
id: 'dashboard.withdraw.error.tax-form.title',
defaultMessage: 'Please complete tax form',
},
errorTaxFormText: {
id: 'dashboard.withdraw.error.tax-form.text',
defaultMessage: 'You must complete a tax form to submit your withdrawal request.',
},
errorInvalidWalletTitle: {
id: 'dashboard.withdraw.error.invalid-wallet.title',
defaultMessage: 'Invalid wallet address',
},
errorInvalidWalletText: {
id: 'dashboard.withdraw.error.invalid-wallet.text',
defaultMessage:
'The crypto wallet address you provided is invalid. Please double-check and try again.',
},
errorInvalidBankTitle: {
id: 'dashboard.withdraw.error.invalid-bank.title',
defaultMessage: 'Invalid bank details',
},
errorInvalidBankText: {
id: 'dashboard.withdraw.error.invalid-bank.text',
defaultMessage:
'The bank account details you provided are invalid. Please verify your information.',
},
errorInvalidAddressTitle: {
id: 'dashboard.withdraw.error.invalid-address.title',
defaultMessage: 'Address verification failed',
},
errorInvalidAddressText: {
id: 'dashboard.withdraw.error.invalid-address.text',
defaultMessage:
'The address you provided could not be verified. Please check your address details.',
},
errorMinimumNotMetTitle: {
id: 'dashboard.withdraw.error.minimum-not-met.title',
defaultMessage: 'Amount too low',
},
errorMinimumNotMetText: {
id: 'dashboard.withdraw.error.minimum-not-met.text',
defaultMessage:
"The withdrawal amount (after fees) doesn't meet the minimum requirement. Please increase your withdrawal amount.",
},
errorGenericTitle: {
id: 'dashboard.withdraw.error.generic.title',
defaultMessage: 'Unable to withdraw',
},
errorGenericText: {
id: 'dashboard.withdraw.error.generic.text',
defaultMessage:
'We were unable to submit your withdrawal request, please check your details or contact support.',
},
})
</script>

View File

@@ -8,7 +8,8 @@
type="number"
step="0.01"
:min="minAmount"
:max="maxAmount"
:max="safeMaxAmount"
:disabled="isDisabled"
:placeholder="formatMessage(formFieldPlaceholders.amountPlaceholder)"
class="w-full rounded-[14px] bg-surface-4 py-2.5 pl-4 pr-4 text-contrast placeholder:text-secondary"
@input="handleInput"
@@ -26,13 +27,13 @@
</template>
</Combobox>
<ButtonStyled>
<button class="px-4 py-2" @click="setMaxAmount">
<button class="px-4 py-2" :disabled="isDisabled" @click="setMaxAmount">
{{ formatMessage(commonMessages.maxButton) }}
</button>
</ButtonStyled>
</div>
<div>
<span class="my-1 mt-0 text-secondary">{{ formatMoney(maxAmount) }} available.</span>
<span class="my-1 mt-0 text-secondary">{{ formatMoney(safeMaxAmount) }} available.</span>
<Transition name="fade">
<span v-if="isBelowMinimum" class="text-red">
Amount must be at least {{ formatMoney(minAmount) }}.
@@ -40,7 +41,7 @@
</Transition>
<Transition name="fade">
<span v-if="isAboveMaximum" class="text-red">
Amount cannot exceed {{ formatMoney(maxAmount) }}.
Amount cannot exceed {{ formatMoney(safeMaxAmount) }}.
</span>
</Transition>
</div>
@@ -77,6 +78,14 @@ const emit = defineEmits<{
const { formatMessage } = useVIntl()
const amountInput = ref<HTMLInputElement | null>(null)
const safeMaxAmount = computed(() => {
return Math.max(0, props.maxAmount)
})
const isDisabled = computed(() => {
return safeMaxAmount.value < 0.01
})
const isBelowMinimum = computed(() => {
return (
props.modelValue !== undefined && props.modelValue > 0 && props.modelValue < props.minAmount
@@ -84,11 +93,11 @@ const isBelowMinimum = computed(() => {
})
const isAboveMaximum = computed(() => {
return props.modelValue !== undefined && props.modelValue > props.maxAmount
return props.modelValue !== undefined && props.modelValue > safeMaxAmount.value
})
async function setMaxAmount() {
const maxValue = props.maxAmount
const maxValue = safeMaxAmount.value
emit('update:modelValue', maxValue)
await nextTick()
@@ -119,11 +128,11 @@ watch(
() => props.modelValue,
async (newAmount) => {
if (newAmount !== undefined && newAmount !== null) {
if (newAmount > props.maxAmount) {
emit('update:modelValue', props.maxAmount)
if (newAmount > safeMaxAmount.value) {
emit('update:modelValue', safeMaxAmount.value)
await nextTick()
if (amountInput.value) {
amountInput.value.value = props.maxAmount.toFixed(2)
amountInput.value.value = safeMaxAmount.value.toFixed(2)
}
} else if (newAmount < 0) {
emit('update:modelValue', 0)

View File

@@ -325,7 +325,7 @@ const dynamicDocumentNumberField = computed(() => {
return {
name: 'documentNumber',
type: 'text' as const,
label: labelMap[documentType] || 'Document Number',
label: labelMap[documentType] || 'Document number',
placeholder: placeholderMap[documentType] || 'Enter document number',
required: true,
}
@@ -474,23 +474,23 @@ const messages = defineMessages({
},
documentNumberNationalId: {
id: 'dashboard.creator-withdraw-modal.muralpay-details.document-number-national-id',
defaultMessage: 'National ID Number',
defaultMessage: 'National ID number',
},
documentNumberPassport: {
id: 'dashboard.creator-withdraw-modal.muralpay-details.document-number-passport',
defaultMessage: 'Passport Number',
defaultMessage: 'Passport number',
},
documentNumberResidentId: {
id: 'dashboard.creator-withdraw-modal.muralpay-details.document-number-resident-id',
defaultMessage: 'Resident ID Number',
defaultMessage: 'Resident ID number',
},
documentNumberRuc: {
id: 'dashboard.creator-withdraw-modal.muralpay-details.document-number-ruc',
defaultMessage: 'RUC Number',
defaultMessage: 'RUC number',
},
documentNumberTaxId: {
id: 'dashboard.creator-withdraw-modal.muralpay-details.document-number-tax-id',
defaultMessage: 'Tax ID Number',
defaultMessage: 'Tax ID number',
},
documentNumberNationalIdPlaceholder: {
id: 'dashboard.creator-withdraw-modal.muralpay-details.document-number-national-id-placeholder',

View File

@@ -529,7 +529,11 @@ onMounted(async () => {
rewardOptions.value = methods
.filter((m) => m.type === 'tremendous')
.filter((m) => m.category === selectedMethod)
.filter(
(m) =>
m.category === selectedMethod ||
(selectedMethod === 'merchant_card' && m.category === 'visa_card'),
)
.map((m) => ({
value: m.id,
label: m.name,

View File

@@ -702,31 +702,31 @@
"message": "Confirm your wallet address"
},
"dashboard.creator-withdraw-modal.muralpay-details.document-number-national-id": {
"message": "National ID Number"
"message": "National ID number"
},
"dashboard.creator-withdraw-modal.muralpay-details.document-number-national-id-placeholder": {
"message": "Enter national ID number"
},
"dashboard.creator-withdraw-modal.muralpay-details.document-number-passport": {
"message": "Passport Number"
"message": "Passport number"
},
"dashboard.creator-withdraw-modal.muralpay-details.document-number-passport-placeholder": {
"message": "Enter passport number"
},
"dashboard.creator-withdraw-modal.muralpay-details.document-number-resident-id": {
"message": "Resident ID Number"
"message": "Resident ID number"
},
"dashboard.creator-withdraw-modal.muralpay-details.document-number-resident-id-placeholder": {
"message": "Enter resident ID number"
},
"dashboard.creator-withdraw-modal.muralpay-details.document-number-ruc": {
"message": "RUC Number"
"message": "RUC number"
},
"dashboard.creator-withdraw-modal.muralpay-details.document-number-ruc-placeholder": {
"message": "Enter RUC number"
},
"dashboard.creator-withdraw-modal.muralpay-details.document-number-tax-id": {
"message": "Tax ID Number"
"message": "Tax ID number"
},
"dashboard.creator-withdraw-modal.muralpay-details.document-number-tax-id-placeholder": {
"message": "Enter tax ID number"
@@ -920,6 +920,42 @@
"dashboard.withdraw.completion.wallet": {
"message": "Wallet"
},
"dashboard.withdraw.error.generic.text": {
"message": "We were unable to submit your withdrawal request, please check your details or contact support."
},
"dashboard.withdraw.error.generic.title": {
"message": "Unable to withdraw"
},
"dashboard.withdraw.error.invalid-address.text": {
"message": "The address you provided could not be verified. Please check your address details."
},
"dashboard.withdraw.error.invalid-address.title": {
"message": "Address verification failed"
},
"dashboard.withdraw.error.invalid-bank.text": {
"message": "The bank account details you provided are invalid. Please verify your information."
},
"dashboard.withdraw.error.invalid-bank.title": {
"message": "Invalid bank details"
},
"dashboard.withdraw.error.invalid-wallet.text": {
"message": "The crypto wallet address you provided is invalid. Please double-check and try again."
},
"dashboard.withdraw.error.invalid-wallet.title": {
"message": "Invalid wallet address"
},
"dashboard.withdraw.error.minimum-not-met.text": {
"message": "The withdrawal amount (after fees) doesn't meet the minimum requirement. Please increase your withdrawal amount."
},
"dashboard.withdraw.error.minimum-not-met.title": {
"message": "Amount too low"
},
"dashboard.withdraw.error.tax-form.text": {
"message": "You must complete a tax form to submit your withdrawal request."
},
"dashboard.withdraw.error.tax-form.title": {
"message": "Please complete tax form"
},
"error.collection.404.list_item.1": {
"message": "You may have mistyped the collection's URL."
},
@@ -1512,25 +1548,25 @@
"message": "Tax ID"
},
"muralpay.field.account-number": {
"message": "Account Number"
"message": "Account number"
},
"muralpay.field.account-number-cbu-cvu": {
"message": "Account Number (CBU/CVU)"
"message": "Account number (CBU/CVU)"
},
"muralpay.field.account-number-cci": {
"message": "Account Number (CCI)"
"message": "Account number (CCI)"
},
"muralpay.field.account-number-type": {
"message": "Account Number Type"
"message": "Account number type"
},
"muralpay.field.account-type": {
"message": "Account Type"
"message": "Account type"
},
"muralpay.field.bank-account-number": {
"message": "Account Number"
"message": "Account number"
},
"muralpay.field.branch-code": {
"message": "Branch Code"
"message": "Branch code"
},
"muralpay.field.clabe": {
"message": "CLABE"
@@ -1545,31 +1581,31 @@
"message": "CUIT/CUIL"
},
"muralpay.field.document-type": {
"message": "Document Type"
"message": "Document type"
},
"muralpay.field.iban": {
"message": "IBAN"
},
"muralpay.field.phone-number": {
"message": "Phone Number"
"message": "Phone number"
},
"muralpay.field.pix-email": {
"message": "PIX Email"
"message": "PIX email"
},
"muralpay.field.pix-key-type": {
"message": "PIX Key Type"
"message": "PIX key type"
},
"muralpay.field.pix-phone": {
"message": "PIX Phone"
"message": "PIX phone"
},
"muralpay.field.routing-number": {
"message": "Routing Number"
"message": "Routing number"
},
"muralpay.field.swift-bic": {
"message": "SWIFT/BIC"
},
"muralpay.field.wallet-address": {
"message": "Wallet Address"
"message": "Wallet address"
},
"muralpay.help.cbu-cvu": {
"message": "Clave Bancaria Uniforme or Clave Virtual Uniforme"
@@ -1593,7 +1629,7 @@
"message": "Bank Identifier Code"
},
"muralpay.pix-type.bank-account": {
"message": "Bank Account"
"message": "Bank account"
},
"muralpay.pix-type.document": {
"message": "CPF/CNPJ"
@@ -1602,7 +1638,7 @@
"message": "Email"
},
"muralpay.pix-type.phone": {
"message": "Phone Number"
"message": "Phone number"
},
"muralpay.placeholder.account-number": {
"message": "Enter account number"

View File

@@ -193,67 +193,66 @@
@cancelled="refreshPayouts"
/>
</div>
<div v-else class="mx-auto flex flex-col justify-center p-6 text-center">
<div data-svg-wrapper className="relative w-full">
<div v-else class="mx-auto flex flex-col justify-center gap-4 p-6 text-center">
<div data-svg-wrapper>
<svg
width="250"
height="200"
viewBox="0 0 250 200"
viewBox="0 0 154 94"
fill="none"
class="h-[94px] w-[154px]"
xmlns="http://www.w3.org/2000/svg"
class="h-auto w-full"
>
<rect width="250" height="200" fill="var(--surface-1)" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M207 65C210.866 65 214 68.134 214 72C214 75.866 210.866 79 207 79H167C170.866 79 174 82.134 174 86C174 89.866 170.866 93 167 93H189C192.866 93 196 96.134 196 100C196 103.866 192.866 107 189 107H178.826C173.952 107 170 110.134 170 114C170 116.577 172 118.911 176 121C179.866 121 183 124.134 183 128C183 131.866 179.866 135 176 135H93C89.134 135 86 131.866 86 128C86 124.134 89.134 121 93 121H54C50.134 121 47 117.866 47 114C47 110.134 50.134 107 54 107H94C97.866 107 101 103.866 101 100C101 96.134 97.866 93 94 93H69C65.134 93 62 89.866 62 86C62 82.134 65.134 79 69 79H109C105.134 79 102 75.866 102 72C102 68.134 105.134 65 109 65H207ZM207 93C210.866 93 214 96.134 214 100C214 103.866 210.866 107 207 107C203.134 107 200 103.866 200 100C200 96.134 203.134 93 207 93Z"
fill="var(--surface-2)"
d="M147.545 13.8413C151.11 13.8413 154 16.7333 154 20.3006C154 23.868 151.11 26.76 147.545 26.76H110.659C114.224 26.76 117.114 29.6519 117.114 33.2193C117.114 36.7867 114.224 39.6786 110.659 39.6786H130.946C134.511 39.6786 137.401 42.5706 137.401 46.138C137.401 49.7054 134.511 52.5973 130.946 52.5973H121.564C117.069 52.5973 113.425 55.4892 113.425 59.0566C113.425 61.4349 115.269 63.588 118.958 65.516C122.523 65.516 125.413 68.4079 125.413 71.9753C125.413 75.5427 122.523 78.4346 118.958 78.4346H42.4192C38.8541 78.4346 35.9641 75.5427 35.9641 71.9753C35.9641 68.4079 38.8541 65.516 42.4192 65.516H6.45509C2.89004 65.516 0 62.624 0 59.0566C0 55.4892 2.89004 52.5973 6.45509 52.5973H43.3413C46.9064 52.5973 49.7964 49.7054 49.7964 46.138C49.7964 42.5706 46.9064 39.6786 43.3413 39.6786H20.2874C16.7224 39.6786 13.8323 36.7867 13.8323 33.2193C13.8323 29.6519 16.7224 26.76 20.2874 26.76H57.1737C53.6086 26.76 50.7186 23.868 50.7186 20.3006C50.7186 16.7333 53.6086 13.8413 57.1737 13.8413H147.545ZM147.545 39.6786C151.11 39.6786 154 42.5706 154 46.138C154 49.7054 151.11 52.5973 147.545 52.5973C143.98 52.5973 141.09 49.7054 141.09 46.138C141.09 42.5706 143.98 39.6786 147.545 39.6786Z"
fill="var(--surface-2, #1D1F23)"
/>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M153.672 63.9999L162.974 131.843L163.809 138.649C164.079 140.842 162.519 142.837 160.327 143.107L101.767 150.297C99.5739 150.566 97.5781 149.007 97.3089 146.814L88.2931 73.3867C88.1585 72.2904 88.9381 71.2925 90.0345 71.1579C90.0414 71.157 90.0483 71.1562 90.0553 71.1554L94.9136 70.6104M98.8422 70.1698L103.429 69.6552L98.8422 70.1698Z"
fill="var(--surface-1)"
d="M98.3725 12.9186L106.946 75.5171L107.717 81.7973C107.965 83.8205 106.527 85.6621 104.505 85.9107L50.499 92.5499C48.4769 92.7984 46.6365 91.3599 46.3883 89.3367L38.0786 21.585C37.9545 20.5734 38.6735 19.6526 39.6846 19.5283C39.691 19.5275 39.6974 19.5267 39.7038 19.526L44.1843 19.0228M47.8065 18.612L52.0365 18.1369Z"
fill="var(--surface-1, #16181C)"
/>
<path
d="M154.91 63.8302C154.817 63.1462 154.186 62.6678 153.502 62.7615C152.818 62.8553 152.34 63.4858 152.433 64.1697L153.672 63.9999L154.91 63.8302ZM162.974 131.843L164.214 131.69C164.214 131.685 164.213 131.679 164.212 131.673L162.974 131.843ZM163.809 138.649L165.05 138.497L163.809 138.649ZM160.327 143.107L160.479 144.347L160.327 143.107ZM101.767 150.297L101.919 151.538L101.767 150.297ZM97.3089 146.814L98.5496 146.662L97.3089 146.814ZM90.0553 71.1554L90.1946 72.3976L90.0553 71.1554ZM95.053 71.8527C95.739 71.7757 96.2328 71.1572 96.1558 70.4711C96.0789 69.7851 95.4603 69.2913 94.7743 69.3682L94.9136 70.6104L95.053 71.8527ZM98.7028 68.9276C98.0168 69.0045 97.523 69.6231 97.5999 70.3091C97.6769 70.9952 98.2954 71.4889 98.9815 71.412L98.8422 70.1698L98.7028 68.9276ZM103.569 70.8974C104.255 70.8205 104.748 70.2019 104.671 69.5159C104.594 68.8298 103.976 68.3361 103.29 68.413L103.429 69.6552L103.569 70.8974ZM153.672 63.9999L152.433 64.1697L161.735 132.012L162.974 131.843L164.212 131.673L154.91 63.8302L153.672 63.9999ZM162.974 131.843L161.733 131.995L162.569 138.801L163.809 138.649L165.05 138.497L164.214 131.69L162.974 131.843ZM163.809 138.649L162.569 138.801C162.754 140.309 161.682 141.681 160.174 141.866L160.327 143.107L160.479 144.347C163.357 143.994 165.404 141.375 165.05 138.497L163.809 138.649ZM160.327 143.107L160.174 141.866L101.614 149.056L101.767 150.297L101.919 151.538L160.479 144.347L160.327 143.107ZM101.767 150.297L101.614 149.056C100.107 149.241 98.7347 148.169 98.5496 146.662L97.3089 146.814L96.0682 146.967C96.4216 149.844 99.041 151.891 101.919 151.538L101.767 150.297ZM97.3089 146.814L98.5496 146.662L89.5338 73.2344L88.2931 73.3867L87.0524 73.539L96.0682 146.967L97.3089 146.814ZM88.2931 73.3867L89.5338 73.2344C89.4833 72.8232 89.7757 72.449 90.1868 72.3986L90.0345 71.1579L89.8821 69.9172C88.1006 70.1359 86.8337 71.7575 87.0524 73.539L88.2931 73.3867ZM90.0345 71.1579L90.1868 72.3986C90.1894 72.3982 90.192 72.3979 90.1946 72.3976L90.0553 71.1554L89.9159 69.9132C89.9046 69.9145 89.8934 69.9158 89.8821 69.9172L90.0345 71.1579ZM90.0553 71.1554L90.1946 72.3976L95.053 71.8527L94.9136 70.6104L94.7743 69.3682L89.9159 69.9132L90.0553 71.1554ZM98.8422 70.1698L98.9815 71.412L103.569 70.8974L103.429 69.6552L103.29 68.413L98.7028 68.9276L98.8422 70.1698Z"
fill="var(--surface-4)"
d="M99.6109 12.7488C99.5172 12.0648 98.8868 11.5864 98.2028 11.6802C97.5189 11.774 97.0404 12.4045 97.1341 13.0884L98.3725 12.9186L99.6109 12.7488ZM106.946 75.5171L108.187 75.3647C108.186 75.3589 108.186 75.3531 108.185 75.3473L106.946 75.5171ZM107.717 81.7973L108.957 81.6449L107.717 81.7973ZM104.505 85.9107L104.657 87.1514L104.505 85.9107ZM50.499 92.5499L50.6514 93.7905L50.499 92.5499ZM46.3883 89.3367L47.629 89.1843L46.3883 89.3367ZM38.0786 21.585L36.8379 21.7374L36.8379 21.7374L38.0786 21.585ZM39.6846 19.5283L39.8369 20.769L39.6846 19.5283ZM39.7038 19.526L39.8431 20.7682L39.7038 19.526ZM44.3236 20.265C45.0096 20.1879 45.5034 19.5693 45.4265 18.8833C45.3495 18.1972 44.731 17.7035 44.0449 17.7806L44.1843 19.0228L44.3236 20.265ZM47.6672 17.3698C46.9811 17.4468 46.4874 18.0654 46.5643 18.7515C46.6412 19.4375 47.2598 19.9312 47.9458 19.8542L47.8065 18.612L47.6672 17.3698ZM52.1758 19.3791C52.8619 19.3021 53.3557 18.6835 53.2787 17.9974C53.2018 17.3114 52.5833 16.8177 51.8972 16.8947L52.0365 18.1369L52.1758 19.3791ZM98.3725 12.9186L97.1341 13.0884L105.708 75.6869L106.946 75.5171L108.185 75.3473L99.6109 12.7488L98.3725 12.9186ZM106.946 75.5171L105.706 75.6695L106.476 81.9497L107.717 81.7973L108.957 81.6449L108.187 75.3647L106.946 75.5171ZM107.717 81.7973L106.476 81.9497C106.64 83.2883 105.689 84.5057 104.352 84.67L104.505 85.9107L104.657 87.1514C107.365 86.8185 109.29 84.3527 108.957 81.6449L107.717 81.7973ZM104.505 85.9107L104.352 84.67L50.3467 91.3092L50.499 92.5499L50.6514 93.7905L104.657 87.1514L104.505 85.9107ZM50.499 92.5499L50.3467 91.3092C49.0104 91.4734 47.7932 90.5228 47.629 89.1843L46.3883 89.3367L45.1476 89.489C45.4798 92.1969 47.9434 94.1234 50.6514 93.7905L50.499 92.5499ZM46.3883 89.3367L47.629 89.1843L39.3192 21.4326L38.0786 21.585L36.8379 21.7374L45.1476 89.489L46.3883 89.3367ZM38.0786 21.585L39.3192 21.4326C39.2791 21.1056 39.5116 20.809 39.8369 20.769L39.6846 19.5283L39.5323 18.2876C37.8355 18.4962 36.6298 20.0412 36.8379 21.7374L38.0786 21.585ZM39.6846 19.5283L39.8369 20.769C39.839 20.7687 39.841 20.7685 39.8431 20.7682L39.7038 19.526L39.5645 18.2838C39.5537 18.285 39.543 18.2863 39.5323 18.2876L39.6846 19.5283ZM39.7038 19.526L39.8431 20.7682L44.3236 20.265L44.1843 19.0228L44.0449 17.7806L39.5645 18.2838L39.7038 19.526ZM47.8065 18.612L47.9458 19.8542L52.1758 19.3791L52.0365 18.1369L51.8972 16.8947L47.6672 17.3698L47.8065 18.612Z"
fill="var(--surface-4, #34363C)"
/>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M151.14 68.2691L159.56 129.753L160.317 135.921C160.561 137.908 159.167 139.714 157.203 139.956L104.761 146.395C102.798 146.636 101.008 145.22 100.764 143.233L92.6142 76.8567C92.4795 75.7603 93.2592 74.7625 94.3555 74.6278L100.843 73.8313"
fill="var(--surface-2)"
d="M96.0333 16.8579L103.797 73.5927L104.496 79.2845C104.721 81.1182 103.435 82.785 101.625 83.0074L53.2649 88.9492C51.4542 89.1716 49.8039 87.8655 49.5789 86.0319L42.0821 24.9356C41.9476 23.8392 42.7273 22.8412 43.8236 22.7065L49.6517 21.9905"
fill="var(--surface-2, #1D1F23)"
/>
<path
d="M110.672 51.25H156.229C156.958 51.25 157.657 51.5393 158.173 52.0547L171.616 65.4902C172.132 66.0059 172.422 66.7053 172.422 67.4346V130C172.422 131.519 171.191 132.75 169.672 132.75H110.672C109.153 132.75 107.922 131.519 107.922 130V54C107.922 52.4812 109.153 51.25 110.672 51.25Z"
fill="var(--surface-1)"
stroke="var(--surface-4)"
d="M59.0267 1.25H100.596C101.325 1.25 102.025 1.53995 102.54 2.05566L114.756 14.2715C115.272 14.7872 115.561 15.4867 115.561 16.2158V73.5117C115.561 75.0305 114.33 76.2617 112.811 76.2617H59.0267C57.508 76.2617 56.2767 75.0305 56.2767 73.5117V4C56.2767 2.48122 57.508 1.25 59.0267 1.25Z"
fill="var(--surface-1, #16181C)"
stroke="var(--surface-4, #34363C)"
stroke-width="2.5"
/>
<path
d="M156.672 52.4028V64C156.672 65.6569 158.015 67 159.672 67H167.605"
stroke="var(--surface-4)"
d="M101.135 2.21729V12.9187C101.135 14.4476 102.373 15.687 103.901 15.687H111.217"
stroke="var(--surface-4, #34363C)"
stroke-width="2.5"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M118 118H144M118 67H144H118ZM118 79H161H118ZM118 92H161H118ZM118 105H161H118Z"
stroke="var(--surface-3)"
d="M65.473 62.7479H89.4491M65.473 15.687H89.4491H65.473ZM65.473 26.7602H105.126H65.473ZM65.473 38.7561H105.126H65.473ZM65.473 50.752H105.126H65.473Z"
stroke="var(--surface-3, #27292E)"
stroke-width="2.5"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</div>
<span class="text-lg text-contrast md:text-xl">{{
formatMessage(messages.noTransactions)
}}</span>
<span class="max-w-[256px] text-lg leading-none text-secondary">{{
formatMessage(messages.noTransactionsDesc)
}}</span>
<div class="flex flex-col gap-1">
<span class="text-lg text-contrast md:text-xl">{{
formatMessage(messages.noTransactions)
}}</span>
<span class="max-w-[256px] text-lg leading-6 text-secondary">{{
formatMessage(messages.noTransactionsDesc)
}}</span>
</div>
</div>
</div>
</div>
@@ -556,7 +555,7 @@ const segments = computed<RevenueBarSegment[]>(() => {
return { key: s.key, class: s.class, pct, amount: s.amount }
})
const filtered = normalized.filter((s) => s.pct > 0)
const filtered = normalized.filter((s) => s.pct >= 1)
if (!filtered.length) return [] as RevenueBarSegment[]
const sumExceptLast = filtered.slice(0, -1).reduce((sum, s) => sum + s.pct, 0)

View File

@@ -449,12 +449,12 @@ export function createWithdrawContext(
const formCompleted = balance?.form_completion_status === 'complete'
if (formCompleted) {
return availableBalance
return Math.max(0, availableBalance)
}
const usedLimit = balance?.withdrawn_ytd ?? 0
const remainingLimit = Math.max(0, TAX_THRESHOLD_ACTUAL - usedLimit)
return Math.min(remainingLimit, availableBalance)
return Math.max(0, Math.min(remainingLimit, availableBalance))
})
const paymentOptions = computed<PaymentOption[]>(() => {
@@ -486,7 +486,10 @@ export function createWithdrawContext(
}
const merchantMethods = tremendousMethods.filter(
(m) => m.category === 'merchant_card' || m.category === 'merchant_cards',
(m) =>
m.category === 'merchant_card' ||
m.category === 'merchant_cards' ||
m.category === 'visa_card',
)
if (merchantMethods.length > 0) {
options.push({

View File

@@ -84,7 +84,7 @@ export const MURALPAY_RAILS: Record<string, RailConfig> = {
{
name: 'accountType',
type: 'select',
label: defineMessage({ id: 'muralpay.field.account-type', defaultMessage: 'Account Type' }),
label: defineMessage({ id: 'muralpay.field.account-type', defaultMessage: 'Account type' }),
required: true,
options: ACCOUNT_TYPE_OPTIONS,
autocomplete: 'off',
@@ -94,7 +94,7 @@ export const MURALPAY_RAILS: Record<string, RailConfig> = {
type: 'text',
label: defineMessage({
id: 'muralpay.field.bank-account-number',
defaultMessage: 'Account Number',
defaultMessage: 'Account number',
}),
required: true,
placeholder: defineMessage({
@@ -108,7 +108,7 @@ export const MURALPAY_RAILS: Record<string, RailConfig> = {
type: 'text',
label: defineMessage({
id: 'muralpay.field.routing-number',
defaultMessage: 'Routing Number',
defaultMessage: 'Routing number',
}),
required: true,
placeholder: defineMessage({
@@ -295,13 +295,13 @@ export const MURALPAY_RAILS: Record<string, RailConfig> = {
{
name: 'pixAccountType',
type: 'select',
label: defineMessage({ id: 'muralpay.field.pix-key-type', defaultMessage: 'PIX Key Type' }),
label: defineMessage({ id: 'muralpay.field.pix-key-type', defaultMessage: 'PIX key type' }),
required: true,
autocomplete: 'off',
options: [
{
value: 'PHONE',
label: defineMessage({ id: 'muralpay.pix-type.phone', defaultMessage: 'Phone Number' }),
label: defineMessage({ id: 'muralpay.pix-type.phone', defaultMessage: 'Phone number' }),
},
{
value: 'EMAIL',
@@ -315,7 +315,7 @@ export const MURALPAY_RAILS: Record<string, RailConfig> = {
value: 'BANK_ACCOUNT',
label: defineMessage({
id: 'muralpay.pix-type.bank-account',
defaultMessage: 'Bank Account',
defaultMessage: 'Bank account',
}),
},
],
@@ -323,7 +323,7 @@ export const MURALPAY_RAILS: Record<string, RailConfig> = {
{
name: 'pixEmail',
type: 'email',
label: defineMessage({ id: 'muralpay.field.pix-email', defaultMessage: 'PIX Email' }),
label: defineMessage({ id: 'muralpay.field.pix-email', defaultMessage: 'PIX email' }),
required: true,
placeholder: defineMessage({
id: 'muralpay.placeholder.enter-pix-email',
@@ -334,7 +334,7 @@ export const MURALPAY_RAILS: Record<string, RailConfig> = {
{
name: 'pixPhone',
type: 'tel',
label: defineMessage({ id: 'muralpay.field.pix-phone', defaultMessage: 'PIX Phone' }),
label: defineMessage({ id: 'muralpay.field.pix-phone', defaultMessage: 'PIX phone' }),
required: true,
placeholder: defineMessage({
id: 'muralpay.placeholder.pix-phone',
@@ -345,7 +345,7 @@ export const MURALPAY_RAILS: Record<string, RailConfig> = {
{
name: 'branchCode',
type: 'text',
label: defineMessage({ id: 'muralpay.field.branch-code', defaultMessage: 'Branch Code' }),
label: defineMessage({ id: 'muralpay.field.branch-code', defaultMessage: 'Branch code' }),
required: true,
placeholder: defineMessage({
id: 'muralpay.placeholder.enter-branch-code',
@@ -386,7 +386,7 @@ export const MURALPAY_RAILS: Record<string, RailConfig> = {
{
name: 'phoneNumber',
type: 'tel',
label: defineMessage({ id: 'muralpay.field.phone-number', defaultMessage: 'Phone Number' }),
label: defineMessage({ id: 'muralpay.field.phone-number', defaultMessage: 'Phone number' }),
required: true,
placeholder: defineMessage({
id: 'muralpay.placeholder.phone-cop',
@@ -397,7 +397,7 @@ export const MURALPAY_RAILS: Record<string, RailConfig> = {
{
name: 'accountType',
type: 'select',
label: defineMessage({ id: 'muralpay.field.account-type', defaultMessage: 'Account Type' }),
label: defineMessage({ id: 'muralpay.field.account-type', defaultMessage: 'Account type' }),
required: true,
options: ACCOUNT_TYPE_OPTIONS,
autocomplete: 'off',
@@ -407,7 +407,7 @@ export const MURALPAY_RAILS: Record<string, RailConfig> = {
type: 'text',
label: defineMessage({
id: 'muralpay.field.bank-account-number',
defaultMessage: 'Account Number',
defaultMessage: 'Account number',
}),
required: true,
placeholder: defineMessage({
@@ -421,7 +421,7 @@ export const MURALPAY_RAILS: Record<string, RailConfig> = {
type: 'select',
label: defineMessage({
id: 'muralpay.field.document-type',
defaultMessage: 'Document Type',
defaultMessage: 'Document type',
}),
required: true,
options: DOCUMENT_TYPE_OPTIONS,
@@ -447,7 +447,7 @@ export const MURALPAY_RAILS: Record<string, RailConfig> = {
type: 'text',
label: defineMessage({
id: 'muralpay.field.account-number-cbu-cvu',
defaultMessage: 'Account Number (CBU/CVU)',
defaultMessage: 'Account number (CBU/CVU)',
}),
required: true,
placeholder: defineMessage({
@@ -480,7 +480,7 @@ export const MURALPAY_RAILS: Record<string, RailConfig> = {
type: 'text',
label: defineMessage({
id: 'muralpay.field.account-number-type',
defaultMessage: 'Account Number Type',
defaultMessage: 'Account number type',
}),
required: true,
placeholder: defineMessage({
@@ -507,7 +507,7 @@ export const MURALPAY_RAILS: Record<string, RailConfig> = {
{
name: 'accountType',
type: 'select',
label: defineMessage({ id: 'muralpay.field.account-type', defaultMessage: 'Account Type' }),
label: defineMessage({ id: 'muralpay.field.account-type', defaultMessage: 'Account type' }),
required: true,
options: ACCOUNT_TYPE_OPTIONS,
autocomplete: 'off',
@@ -517,7 +517,7 @@ export const MURALPAY_RAILS: Record<string, RailConfig> = {
type: 'text',
label: defineMessage({
id: 'muralpay.field.account-number',
defaultMessage: 'Account Number',
defaultMessage: 'Account number',
}),
required: true,
placeholder: defineMessage({
@@ -531,7 +531,7 @@ export const MURALPAY_RAILS: Record<string, RailConfig> = {
type: 'select',
label: defineMessage({
id: 'muralpay.field.document-type',
defaultMessage: 'Document Type',
defaultMessage: 'Document type',
}),
required: true,
options: DOCUMENT_TYPE_OPTIONS,
@@ -568,7 +568,7 @@ export const MURALPAY_RAILS: Record<string, RailConfig> = {
type: 'select',
label: defineMessage({
id: 'muralpay.field.document-type',
defaultMessage: 'Document Type',
defaultMessage: 'Document type',
}),
required: true,
options: DOCUMENT_TYPE_OPTIONS,
@@ -594,7 +594,7 @@ export const MURALPAY_RAILS: Record<string, RailConfig> = {
type: 'select',
label: defineMessage({
id: 'muralpay.field.document-type',
defaultMessage: 'Document Type',
defaultMessage: 'Document type',
}),
required: true,
options: DOCUMENT_TYPE_OPTIONS,
@@ -605,7 +605,7 @@ export const MURALPAY_RAILS: Record<string, RailConfig> = {
type: 'text',
label: defineMessage({
id: 'muralpay.field.account-number-cci',
defaultMessage: 'Account Number (CCI)',
defaultMessage: 'Account number (CCI)',
}),
required: true,
placeholder: defineMessage({
@@ -621,7 +621,7 @@ export const MURALPAY_RAILS: Record<string, RailConfig> = {
{
name: 'accountType',
type: 'select',
label: defineMessage({ id: 'muralpay.field.account-type', defaultMessage: 'Account Type' }),
label: defineMessage({ id: 'muralpay.field.account-type', defaultMessage: 'Account type' }),
required: true,
options: ACCOUNT_TYPE_OPTIONS,
autocomplete: 'off',
@@ -646,7 +646,7 @@ export const MURALPAY_RAILS: Record<string, RailConfig> = {
// type: 'text',
// label: defineMessage({
// id: 'muralpay.field.account-number',
// defaultMessage: 'Account Number',
// defaultMessage: 'Account number',
// }),
// required: true,
// placeholder: defineMessage({
@@ -660,7 +660,7 @@ export const MURALPAY_RAILS: Record<string, RailConfig> = {
// type: 'select',
// label: defineMessage({
// id: 'muralpay.field.document-type',
// defaultMessage: 'Document Type',
// defaultMessage: 'Document type',
// }),
// required: true,
// options: DOCUMENT_TYPE_OPTIONS,
@@ -684,7 +684,7 @@ export const MURALPAY_RAILS: Record<string, RailConfig> = {
{
name: 'accountType',
type: 'select',
label: defineMessage({ id: 'muralpay.field.account-type', defaultMessage: 'Account Type' }),
label: defineMessage({ id: 'muralpay.field.account-type', defaultMessage: 'Account type' }),
required: true,
options: ACCOUNT_TYPE_OPTIONS,
autocomplete: 'off',
@@ -694,7 +694,7 @@ export const MURALPAY_RAILS: Record<string, RailConfig> = {
type: 'text',
label: defineMessage({
id: 'muralpay.field.account-number',
defaultMessage: 'Account Number',
defaultMessage: 'Account number',
}),
required: true,
placeholder: defineMessage({
@@ -721,7 +721,7 @@ export const MURALPAY_RAILS: Record<string, RailConfig> = {
{
name: 'accountType',
type: 'select',
label: defineMessage({ id: 'muralpay.field.account-type', defaultMessage: 'Account Type' }),
label: defineMessage({ id: 'muralpay.field.account-type', defaultMessage: 'Account type' }),
required: true,
options: ACCOUNT_TYPE_OPTIONS,
autocomplete: 'off',
@@ -731,7 +731,7 @@ export const MURALPAY_RAILS: Record<string, RailConfig> = {
type: 'text',
label: defineMessage({
id: 'muralpay.field.account-number',
defaultMessage: 'Account Number',
defaultMessage: 'Account number',
}),
required: true,
placeholder: defineMessage({
@@ -745,7 +745,7 @@ export const MURALPAY_RAILS: Record<string, RailConfig> = {
type: 'select',
label: defineMessage({
id: 'muralpay.field.document-type',
defaultMessage: 'Document Type',
defaultMessage: 'Document type',
}),
required: true,
options: DOCUMENT_TYPE_OPTIONS,
@@ -780,7 +780,7 @@ export const MURALPAY_RAILS: Record<string, RailConfig> = {
// {
// name: 'accountType',
// type: 'select',
// label: defineMessage({ id: 'muralpay.field.account-type', defaultMessage: 'Account Type' }),
// label: defineMessage({ id: 'muralpay.field.account-type', defaultMessage: 'Account type' }),
// required: true,
// options: ACCOUNT_TYPE_OPTIONS,
// autocomplete: 'off',
@@ -790,7 +790,7 @@ export const MURALPAY_RAILS: Record<string, RailConfig> = {
// type: 'text',
// label: defineMessage({
// id: 'muralpay.field.account-number',
// defaultMessage: 'Account Number',
// defaultMessage: 'Account number',
// }),
// required: true,
// placeholder: defineMessage({
@@ -804,7 +804,7 @@ export const MURALPAY_RAILS: Record<string, RailConfig> = {
// type: 'select',
// label: defineMessage({
// id: 'muralpay.field.document-type',
// defaultMessage: 'Document Type',
// defaultMessage: 'Document type',
// }),
// required: true,
// options: DOCUMENT_TYPE_OPTIONS,
@@ -813,7 +813,7 @@ export const MURALPAY_RAILS: Record<string, RailConfig> = {
// {
// name: 'phoneNumber',
// type: 'tel',
// label: defineMessage({ id: 'muralpay.field.phone-number', defaultMessage: 'Phone Number' }),
// label: defineMessage({ id: 'muralpay.field.phone-number', defaultMessage: 'Phone number' }),
// required: true,
// placeholder: defineMessage({
// id: 'muralpay.placeholder.phone-china',
@@ -867,7 +867,7 @@ export const MURALPAY_RAILS: Record<string, RailConfig> = {
type: 'text',
label: defineMessage({
id: 'muralpay.field.wallet-address',
defaultMessage: 'Wallet Address',
defaultMessage: 'Wallet address',
}),
required: true,
placeholder: defineMessage({
@@ -900,7 +900,7 @@ export const MURALPAY_RAILS: Record<string, RailConfig> = {
type: 'text',
label: defineMessage({
id: 'muralpay.field.wallet-address',
defaultMessage: 'Wallet Address',
defaultMessage: 'Wallet address',
}),
required: true,
placeholder: defineMessage({
@@ -936,7 +936,7 @@ export const MURALPAY_RAILS: Record<string, RailConfig> = {
type: 'text',
label: defineMessage({
id: 'muralpay.field.wallet-address',
defaultMessage: 'Wallet Address',
defaultMessage: 'Wallet address',
}),
required: true,
placeholder: defineMessage({
@@ -969,7 +969,7 @@ export const MURALPAY_RAILS: Record<string, RailConfig> = {
type: 'text',
label: defineMessage({
id: 'muralpay.field.wallet-address',
defaultMessage: 'Wallet Address',
defaultMessage: 'Wallet address',
}),
required: true,
placeholder: defineMessage({