You've already forked AstralRinth
forked from didirus/AstralRinth
Add withdrawal amount validation and display details (#1549)
* Add withdrawal amount validation and display transfer details * Fixed amt should be consistent * Empty amount rather than clamp * Only mutate amount if fixed or 1 value * Add badge to giftcard withdraw methods
This commit is contained in:
@@ -47,12 +47,24 @@
|
|||||||
@click="() => (selectedMethodId = method.id)"
|
@click="() => (selectedMethodId = method.id)"
|
||||||
>
|
>
|
||||||
<div class="preview" :class="{ 'show-bg': !method.image_url || method.name === 'ACH' }">
|
<div class="preview" :class="{ 'show-bg': !method.image_url || method.name === 'ACH' }">
|
||||||
<img
|
<template v-if="method.image_url && method.name !== 'ACH'">
|
||||||
v-if="method.image_url && method.name !== 'ACH'"
|
<div class="preview-badges">
|
||||||
class="preview-img"
|
<span class="badge">
|
||||||
:src="method.image_url"
|
{{
|
||||||
:alt="method.name"
|
getRangeOfMethod(method)
|
||||||
/>
|
.map($formatMoney)
|
||||||
|
.map((i) => i.replace('.00', ''))
|
||||||
|
.join('–')
|
||||||
|
}}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<img
|
||||||
|
v-if="method.image_url && method.name !== 'ACH'"
|
||||||
|
class="preview-img"
|
||||||
|
:src="method.image_url"
|
||||||
|
:alt="method.name"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
<div v-else class="placeholder">
|
<div v-else class="placeholder">
|
||||||
<template v-if="method.type === 'venmo'">
|
<template v-if="method.type === 'venmo'">
|
||||||
<VenmoIcon class="enlarge" />
|
<VenmoIcon class="enlarge" />
|
||||||
@@ -87,15 +99,35 @@
|
|||||||
:format-label="(val) => '$' + val"
|
:format-label="(val) => '$' + val"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
<template v-else-if="minWithdrawAmount == maxWithdrawAmount">
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
This method has a fixed transfer amount of
|
||||||
|
<strong>{{ $formatMoney(minWithdrawAmount) }}</strong
|
||||||
|
>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<input
|
<div>
|
||||||
id="confirmation"
|
<p>
|
||||||
v-model="amount"
|
This method has a minimum transfer amount of
|
||||||
type="text"
|
<strong>{{ $formatMoney(minWithdrawAmount) }}</strong> and a maximum transfer amount of
|
||||||
pattern="^\d*(\.\d{0,2})?$"
|
<strong>{{ $formatMoney(maxWithdrawAmount) }}</strong
|
||||||
autocomplete="off"
|
>.
|
||||||
placeholder="Amount to transfer..."
|
</p>
|
||||||
/>
|
<input
|
||||||
|
id="confirmation"
|
||||||
|
v-model="amount"
|
||||||
|
type="text"
|
||||||
|
pattern="^\d*(\.\d{0,2})?$"
|
||||||
|
autocomplete="off"
|
||||||
|
placeholder="Amount to transfer..."
|
||||||
|
/>
|
||||||
|
<p>
|
||||||
|
You have entered <strong>{{ $formatMoney(parsedAmount) }}</strong> to transfer.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -206,6 +238,36 @@ const fees = computed(() => {
|
|||||||
selectedMethod.value.fee.max ?? Number.MAX_VALUE
|
selectedMethod.value.fee.max ?? Number.MAX_VALUE
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const getIntervalRange = (intervalType) => {
|
||||||
|
if (!intervalType) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
const { min, max, values } = intervalType
|
||||||
|
if (values) {
|
||||||
|
const first = values[0]
|
||||||
|
const last = values.slice(-1)[0]
|
||||||
|
return first === last ? [first] : [first, last]
|
||||||
|
}
|
||||||
|
|
||||||
|
return min === max ? [min] : [min, max]
|
||||||
|
}
|
||||||
|
|
||||||
|
const getRangeOfMethod = (method) => {
|
||||||
|
return getIntervalRange(method.interval?.fixed || method.interval?.standard)
|
||||||
|
}
|
||||||
|
|
||||||
|
const maxWithdrawAmount = computed(() => {
|
||||||
|
const interval = selectedMethod.value.interval
|
||||||
|
return interval?.standard ? interval.standard.max : interval?.fixed?.values.slice(-1)[0] ?? 0
|
||||||
|
})
|
||||||
|
|
||||||
|
const minWithdrawAmount = computed(() => {
|
||||||
|
const interval = selectedMethod.value.interval
|
||||||
|
return interval?.standard ? interval.standard.min : interval?.fixed?.values?.[0] ?? fees.value
|
||||||
|
})
|
||||||
|
|
||||||
const withdrawAccount = computed(() => {
|
const withdrawAccount = computed(() => {
|
||||||
if (selectedMethod.value.type === 'paypal') {
|
if (selectedMethod.value.type === 'paypal') {
|
||||||
return auth.value.user.payout_data.paypal_address
|
return auth.value.user.payout_data.paypal_address
|
||||||
@@ -234,12 +296,15 @@ const knownErrors = computed(() => {
|
|||||||
|
|
||||||
if (!parsedAmount.value && amount.value.length > 0) {
|
if (!parsedAmount.value && amount.value.length > 0) {
|
||||||
errors.push(`${amount.value} is not a valid amount`)
|
errors.push(`${amount.value} is not a valid amount`)
|
||||||
} else if (parsedAmount.value > auth.value.user.payout_data.balance) {
|
} else if (
|
||||||
errors.push(
|
parsedAmount.value > auth.value.user.payout_data.balance ||
|
||||||
`The amount must be no more than ${data.$formatMoney(auth.value.user.payout_data.balance)}`
|
parsedAmount.value > maxWithdrawAmount.value
|
||||||
)
|
) {
|
||||||
} else if (parsedAmount.value <= fees.value) {
|
const maxAmount = Math.min(auth.value.user.payout_data.balance, maxWithdrawAmount.value)
|
||||||
errors.push(`The amount must be at least ${data.$formatMoney(fees.value + 0.01)}`)
|
errors.push(`The amount must be no more than ${data.$formatMoney(maxAmount)}`)
|
||||||
|
} else if (parsedAmount.value <= fees.value || parsedAmount.value < minWithdrawAmount.value) {
|
||||||
|
const minAmount = Math.max(fees.value + 0.01, minWithdrawAmount.value)
|
||||||
|
errors.push(`The amount must be at least ${data.$formatMoney(minAmount)}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
return errors
|
return errors
|
||||||
@@ -256,6 +321,18 @@ watch(country, async () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
watch(selectedMethod, () => {
|
||||||
|
if (selectedMethod.value.interval?.fixed) {
|
||||||
|
amount.value = selectedMethod.value.interval.fixed.values[0]
|
||||||
|
}
|
||||||
|
if (maxWithdrawAmount.value === minWithdrawAmount.value) {
|
||||||
|
amount.value = maxWithdrawAmount.value
|
||||||
|
}
|
||||||
|
agreedTransfer.value = false
|
||||||
|
agreedFees.value = false
|
||||||
|
agreedTerms.value = false
|
||||||
|
})
|
||||||
|
|
||||||
async function withdraw() {
|
async function withdraw() {
|
||||||
startLoading()
|
startLoading()
|
||||||
try {
|
try {
|
||||||
@@ -353,6 +430,22 @@ async function withdraw() {
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
aspect-ratio: 30 / 19;
|
aspect-ratio: 30 / 19;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.preview-badges {
|
||||||
|
// These will float over the image in the bottom right corner
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
padding: var(--gap-sm) var(--gap-xs);
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
background-color: var(--color-button-bg);
|
||||||
|
border-radius: var(--radius-xs);
|
||||||
|
padding: var(--gap-xs) var(--gap-sm);
|
||||||
|
font-size: var(--font-size-xs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&.show-bg {
|
&.show-bg {
|
||||||
background-color: var(--color-bg);
|
background-color: var(--color-bg);
|
||||||
|
|||||||
Reference in New Issue
Block a user