Changeset View
Changeset View
Standalone View
Standalone View
src/resources/vue/Wallet.vue
<template> | <template> | ||||
<div class="container" dusk="wallet-component"> | <div class="container" dusk="wallet-component"> | ||||
<div v-if="wallet.id" id="wallet" class="card"> | <div v-if="wallet.id" id="wallet" class="card"> | ||||
<div class="card-body"> | <div class="card-body"> | ||||
<div class="card-title">Account balance <span :class="wallet.balance < 0 ? 'text-danger' : 'text-success'">{{ $root.price(wallet.balance, wallet.currency) }}</span></div> | <div class="card-title">{{ $t('wallet.title') }} <span :class="wallet.balance < 0 ? 'text-danger' : 'text-success'">{{ $root.price(wallet.balance, wallet.currency) }}</span></div> | ||||
<div class="card-text"> | <div class="card-text"> | ||||
<p v-if="wallet.notice" id="wallet-notice">{{ wallet.notice }}</p> | <p v-if="wallet.notice" id="wallet-notice">{{ wallet.notice }}</p> | ||||
<div v-if="showPendingPayments" class="alert alert-warning"> | <div v-if="showPendingPayments" class="alert alert-warning"> | ||||
You have payments that are still in progress. See the "Pending Payments" tab below. | {{ $t('wallet.pending-payments-warning') }} | ||||
</div> | </div> | ||||
<p> | <p> | ||||
<button type="button" class="btn btn-primary" @click="paymentMethodForm('manual')">Add credit</button> | <button type="button" class="btn btn-primary" @click="paymentMethodForm('manual')">{{ $t('wallet.add-credit') }}</button> | ||||
</p> | </p> | ||||
<div id="mandate-form" v-if="!mandate.isValid && !mandate.isPending"> | <div id="mandate-form" v-if="!mandate.isValid && !mandate.isPending"> | ||||
<template v-if="mandate.id && !mandate.isValid"> | <template v-if="mandate.id && !mandate.isValid"> | ||||
<div class="alert alert-danger"> | <div class="alert alert-danger"> | ||||
The setup of automatic payments failed. Restart the process to enable automatic top-ups. | {{ $t('wallet.auto-payment-failed') }} | ||||
</div> | </div> | ||||
<button type="button" class="btn btn-danger" @click="autoPaymentDelete">Cancel auto-payment</button> | <button type="button" class="btn btn-danger" @click="autoPaymentDelete">{{ $t('wallet.auto-payment-cancel') }}</button> | ||||
</template> | </template> | ||||
<button type="button" class="btn btn-primary" @click="paymentMethodForm('auto')">Set up auto-payment</button> | <button type="button" class="btn btn-primary" @click="paymentMethodForm('auto')">{{ $t('wallet.auto-payment-setup') }}</button> | ||||
</div> | </div> | ||||
<div id="mandate-info" v-else> | <div id="mandate-info" v-else> | ||||
<div v-if="mandate.isDisabled" class="disabled-mandate alert alert-danger"> | <div v-if="mandate.isDisabled" class="disabled-mandate alert alert-danger"> | ||||
The configured auto-payment has been disabled. Top up your wallet or | {{ $t('wallet.auto-payment-disabled') }} | ||||
raise the auto-payment amount. | |||||
</div> | </div> | ||||
<template v-else> | <template v-else> | ||||
<p> | <p v-html="$t('wallet.auto-payment-info', { amount: mandate.amount, balance: mandate.balance })"></p> | ||||
Auto-payment is <b>set</b> to fill up your account by <b>{{ mandate.amount }} CHF</b> | <p>{{ $t('wallet.payment-method', { method: mandate.method }) }}</p> | ||||
every time your account balance gets under <b>{{ mandate.balance }} CHF</b>. | |||||
</p> | |||||
<p> | |||||
Method of payment: {{ mandate.method }} | |||||
</p> | |||||
</template> | </template> | ||||
<div v-if="mandate.isPending" class="alert alert-warning"> | <div v-if="mandate.isPending" class="alert alert-warning"> | ||||
The setup of the automatic payment is still in progress. | {{ $t('wallet.auto-payment-inprogress') }} | ||||
</div> | </div> | ||||
<p> | <p> | ||||
<button type="button" class="btn btn-danger" @click="autoPaymentDelete">Cancel auto-payment</button> | <button type="button" class="btn btn-danger" @click="autoPaymentDelete">{{ $t('wallet.auto-payment-cancel') }}</button> | ||||
<button type="button" class="btn btn-primary" @click="autoPaymentChange">Change auto-payment</button> | <button type="button" class="btn btn-primary" @click="autoPaymentChange">{{ $t('wallet.auto-payment-change') }}</button> | ||||
</p> | </p> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
<ul class="nav nav-tabs mt-3" role="tablist"> | <ul class="nav nav-tabs mt-3" role="tablist"> | ||||
<li class="nav-item"> | <li class="nav-item"> | ||||
<a class="nav-link active" id="tab-receipts" href="#wallet-receipts" role="tab" aria-controls="wallet-receipts" aria-selected="true"> | <a class="nav-link active" id="tab-receipts" href="#wallet-receipts" role="tab" aria-controls="wallet-receipts" aria-selected="true"> | ||||
Receipts | {{ $t('wallet.receipts') }} | ||||
</a> | </a> | ||||
</li> | </li> | ||||
<li class="nav-item"> | <li class="nav-item"> | ||||
<a class="nav-link" id="tab-history" href="#wallet-history" role="tab" aria-controls="wallet-history" aria-selected="false"> | <a class="nav-link" id="tab-history" href="#wallet-history" role="tab" aria-controls="wallet-history" aria-selected="false"> | ||||
History | {{ $t('wallet.history') }} | ||||
</a> | </a> | ||||
</li> | </li> | ||||
<li v-if="showPendingPayments" class="nav-item"> | <li v-if="showPendingPayments" class="nav-item"> | ||||
<a class="nav-link" id="tab-payments" href="#wallet-payments" role="tab" aria-controls="wallet-payments" aria-selected="false"> | <a class="nav-link" id="tab-payments" href="#wallet-payments" role="tab" aria-controls="wallet-payments" aria-selected="false"> | ||||
Pending Payments | {{ $t('wallet.pending-payments') }} | ||||
</a> | </a> | ||||
</li> | </li> | ||||
</ul> | </ul> | ||||
<div class="tab-content"> | <div class="tab-content"> | ||||
<div class="tab-pane active" id="wallet-receipts" role="tabpanel" aria-labelledby="tab-receipts"> | <div class="tab-pane active" id="wallet-receipts" role="tabpanel" aria-labelledby="tab-receipts"> | ||||
<div class="card-body"> | <div class="card-body"> | ||||
<div class="card-text"> | <div class="card-text"> | ||||
<p v-if="receipts.length"> | <p v-if="receipts.length"> | ||||
Here you can download receipts (in PDF format) for payments in specified period. | {{ $t('wallet.receipts-hint') }} | ||||
Select the period and press the Download button. | |||||
</p> | </p> | ||||
<div v-if="receipts.length" class="input-group"> | <div v-if="receipts.length" class="input-group"> | ||||
<select id="receipt-id" class="form-control"> | <select id="receipt-id" class="form-control"> | ||||
<option v-for="(receipt, index) in receipts" :key="index" :value="receipt">{{ receipt }}</option> | <option v-for="(receipt, index) in receipts" :key="index" :value="receipt">{{ receipt }}</option> | ||||
</select> | </select> | ||||
<div class="input-group-append"> | <div class="input-group-append"> | ||||
<button type="button" class="btn btn-secondary" @click="receiptDownload"> | <button type="button" class="btn btn-secondary" @click="receiptDownload"> | ||||
<svg-icon icon="download"></svg-icon> Download | <svg-icon icon="download"></svg-icon> {{ $t('btn.download') }} | ||||
</button> | </button> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
<p v-if="!receipts.length"> | <p v-if="!receipts.length"> | ||||
There are no receipts for payments in this account. Please, note that you can download | {{ $t('wallet.receipts-none') }} | ||||
receipts after the month ends. | |||||
</p> | </p> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
<div class="tab-pane" id="wallet-history" role="tabpanel" aria-labelledby="tab-history"> | <div class="tab-pane" id="wallet-history" role="tabpanel" aria-labelledby="tab-history"> | ||||
<div class="card-body"> | <div class="card-body"> | ||||
<transaction-log v-if="walletId && loadTransactions" class="card-text" :wallet-id="walletId"></transaction-log> | <transaction-log v-if="walletId && loadTransactions" class="card-text" :wallet-id="walletId"></transaction-log> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
<div class="tab-pane" id="wallet-payments" role="tabpanel" aria-labelledby="tab-payments"> | <div class="tab-pane" id="wallet-payments" role="tabpanel" aria-labelledby="tab-payments"> | ||||
<div class="card-body"> | <div class="card-body"> | ||||
<payment-log v-if="walletId && loadPayments" class="card-text" :wallet-id="walletId"></payment-log> | <payment-log v-if="walletId && loadPayments" class="card-text" :wallet-id="walletId"></payment-log> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
<div id="payment-dialog" class="modal" tabindex="-1" role="dialog"> | <div id="payment-dialog" class="modal" tabindex="-1" role="dialog"> | ||||
<div class="modal-dialog" role="document"> | <div class="modal-dialog" role="document"> | ||||
<div class="modal-content"> | <div class="modal-content"> | ||||
<div class="modal-header"> | <div class="modal-header"> | ||||
<h5 class="modal-title">{{ paymentDialogTitle }}</h5> | <h5 class="modal-title">{{ paymentDialogTitle }}</h5> | ||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"> | <button type="button" class="close" data-dismiss="modal" :aria-label="$t('btn.close')"> | ||||
<span aria-hidden="true">×</span> | <span aria-hidden="true">×</span> | ||||
</button> | </button> | ||||
</div> | </div> | ||||
<div class="modal-body"> | <div class="modal-body"> | ||||
<div id="payment-method" v-if="paymentForm == 'method'"> | <div id="payment-method" v-if="paymentForm == 'method'"> | ||||
<form data-validation-prefix="mandate_"> | <form data-validation-prefix="mandate_"> | ||||
<div id="payment-method-selection"> | <div id="payment-method-selection"> | ||||
<a :id="method.id" v-for="method in paymentMethods" :key="method.id" @click="selectPaymentMethod(method)" href="#" class="card link-profile"> | <a :id="method.id" v-for="method in paymentMethods" :key="method.id" @click="selectPaymentMethod(method)" href="#" class="card link-profile"> | ||||
<svg-icon v-if="method.icon" :icon="[method.icon.prefix, method.icon.name]" /> | <svg-icon v-if="method.icon" :icon="[method.icon.prefix, method.icon.name]" /> | ||||
<img v-if="method.image" :src="method.image" /> | <img v-if="method.image" :src="method.image" /> | ||||
<span class="name">{{ method.name }}</span> | <span class="name">{{ method.name }}</span> | ||||
</a> | </a> | ||||
</div> | </div> | ||||
</form> | </form> | ||||
</div> | </div> | ||||
<div id="manual-payment" v-if="paymentForm == 'manual'"> | <div id="manual-payment" v-if="paymentForm == 'manual'"> | ||||
<p v-if="wallet.currency != selectedPaymentMethod.currency"> | <p v-if="wallet.currency != selectedPaymentMethod.currency"> | ||||
Here is how it works: You specify the amount by which you want to to up your wallet in {{ wallet.currency }}. | {{ $t('wallet.currency-conv', { wc: wallet.currency, pc: selectedPaymentMethod.currency }) }} | ||||
We will then convert this to {{ selectedPaymentMethod.currency }}, and on the next page you will be provided with the bank-details | |||||
to transfer the amount in {{ selectedPaymentMethod.currency }}. | |||||
</p> | </p> | ||||
<p v-if="selectedPaymentMethod.id == 'banktransfer'"> | <p v-if="selectedPaymentMethod.id == 'banktransfer'"> | ||||
Please note that a bank transfer can take several days to complete. | {{ $t('wallet.banktransfer-hint') }} | ||||
</p> | |||||
<p> | |||||
{{ $t('wallet.payment-amount-hint') }} | |||||
</p> | </p> | ||||
<p>Choose the amount by which you want to top up your wallet.</p> | |||||
<form id="payment-form" @submit.prevent="payment"> | <form id="payment-form" @submit.prevent="payment"> | ||||
<div class="form-group"> | <div class="form-group"> | ||||
<div class="input-group"> | <div class="input-group"> | ||||
<input type="text" class="form-control" id="amount" v-model="amount" required> | <input type="text" class="form-control" id="amount" v-model="amount" required> | ||||
<span class="input-group-append"> | <span class="input-group-append"> | ||||
<span class="input-group-text">{{ wallet.currency }}</span> | <span class="input-group-text">{{ wallet.currency }}</span> | ||||
</span> | </span> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
<div v-if="wallet.currency != selectedPaymentMethod.currency && !isNaN(amount)" class="alert alert-warning"> | <div v-if="wallet.currency != selectedPaymentMethod.currency && !isNaN(amount)" class="alert alert-warning"> | ||||
You will be charged for {{ $root.price(amount * selectedPaymentMethod.exchangeRate * 100, selectedPaymentMethod.currency) }} | {{ $t('wallet.payment-warning', { price: $root.price(amount * selectedPaymentMethod.exchangeRate * 100, selectedPaymentMethod.currency) }) }} | ||||
</div> | </div> | ||||
</form> | </form> | ||||
</div> | </div> | ||||
<div id="auto-payment" v-if="paymentForm == 'auto'"> | <div id="auto-payment" v-if="paymentForm == 'auto'"> | ||||
<form data-validation-prefix="mandate_"> | <form data-validation-prefix="mandate_"> | ||||
<p> | <p> | ||||
Here is how it works: Every time your account runs low, | {{ $t('wallet.auto-payment-hint') }} | ||||
we will charge your preferred payment method for an amount you choose. | |||||
You can cancel or change the auto-payment option at any time. | |||||
</p> | </p> | ||||
<div class="form-group row"> | <div class="form-group row"> | ||||
<label for="mandate_amount" class="col-sm-6 col-form-label">Fill up by</label> | <label for="mandate_amount" class="col-sm-6 col-form-label">{{ $t('wallet.fill-up') }}</label> | ||||
<div class="input-group col-sm-6"> | <div class="input-group col-sm-6"> | ||||
<input type="text" class="form-control" id="mandate_amount" v-model="mandate.amount" required> | <input type="text" class="form-control" id="mandate_amount" v-model="mandate.amount" required> | ||||
<span class="input-group-append"> | <span class="input-group-append"> | ||||
<span class="input-group-text">{{ wallet.currency }}</span> | <span class="input-group-text">{{ wallet.currency }}</span> | ||||
</span> | </span> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
<div class="form-group row"> | <div class="form-group row"> | ||||
<label for="mandate_balance" class="col-sm-6 col-form-label">when account balance is below</label> | <label for="mandate_balance" class="col-sm-6 col-form-label">{{ $t('wallet.when-below') }}</label> | ||||
<div class="col-sm-6"> | <div class="col-sm-6"> | ||||
<div class="input-group"> | <div class="input-group"> | ||||
<input type="text" class="form-control" id="mandate_balance" v-model="mandate.balance" required> | <input type="text" class="form-control" id="mandate_balance" v-model="mandate.balance" required> | ||||
<span class="input-group-append"> | <span class="input-group-append"> | ||||
<span class="input-group-text">{{ wallet.currency }}</span> | <span class="input-group-text">{{ wallet.currency }}</span> | ||||
</span> | </span> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
<p v-if="!mandate.isValid"> | <p v-if="!mandate.isValid"> | ||||
Next, you will be redirected to the checkout page, where you can provide | {{ $t('wallet.auto-payment-next') }} | ||||
your credit card details. | |||||
</p> | </p> | ||||
<div v-if="mandate.isValid && mandate.isDisabled" class="disabled-mandate alert alert-danger"> | <div v-if="mandate.isValid && mandate.isDisabled" class="disabled-mandate alert alert-danger"> | ||||
The auto-payment is disabled. Immediately after you submit new settings we'll | {{ $t('wallet.auto-payment-disabled-next') }} | ||||
enable it and attempt to top up your wallet. | |||||
</div> | </div> | ||||
</form> | </form> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
<div class="modal-footer"> | <div class="modal-footer"> | ||||
<button type="button" class="btn btn-secondary modal-cancel" data-dismiss="modal">Cancel</button> | <button type="button" class="btn btn-secondary modal-cancel" data-dismiss="modal">{{ $t('btn.cancel') }}</button> | ||||
<button type="button" class="btn btn-primary modal-action" | <button type="button" class="btn btn-primary modal-action" | ||||
v-if="paymentForm == 'auto' && (mandate.isValid || mandate.isPending)" | v-if="paymentForm == 'auto' && (mandate.isValid || mandate.isPending)" | ||||
@click="autoPayment" | @click="autoPayment" | ||||
> | > | ||||
<svg-icon icon="check"></svg-icon> Submit | <svg-icon icon="check"></svg-icon> {{ $t('btn.submit') }} | ||||
</button> | </button> | ||||
<button type="button" class="btn btn-primary modal-action" | <button type="button" class="btn btn-primary modal-action" | ||||
v-if="paymentForm == 'auto' && !mandate.isValid && !mandate.isPending" | v-if="paymentForm == 'auto' && !mandate.isValid && !mandate.isPending" | ||||
@click="autoPayment" | @click="autoPayment" | ||||
> | > | ||||
<svg-icon icon="check"></svg-icon> Continue | <svg-icon icon="check"></svg-icon> {{ $t('btn.continue') }} | ||||
</button> | </button> | ||||
<button type="button" class="btn btn-primary modal-action" | <button type="button" class="btn btn-primary modal-action" | ||||
v-if="paymentForm == 'manual'" | v-if="paymentForm == 'manual'" | ||||
@click="payment" | @click="payment" | ||||
> | > | ||||
<svg-icon icon="check"></svg-icon> Continue | <svg-icon icon="check"></svg-icon> {{ $t('btn.continue') }} | ||||
</button> | </button> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
</template> | </template> | ||||
▲ Show 20 Lines • Show All 163 Lines • ▼ Show 20 Lines | export default { | ||||
this.dialog.modal('hide'); | this.dialog.modal('hide'); | ||||
this.mandate = response.data | this.mandate = response.data | ||||
this.$toast.success(response.data.message) | this.$toast.success(response.data.message) | ||||
} | } | ||||
} | } | ||||
}) | }) | ||||
}, | }, | ||||
autoPaymentChange(event) { | autoPaymentChange(event) { | ||||
this.autoPaymentForm(event, 'Update auto-payment') | this.autoPaymentForm(event, this.$t('wallet.auto-payment-update')) | ||||
}, | }, | ||||
autoPaymentDelete() { | autoPaymentDelete() { | ||||
axios.delete('/api/v4/payments/mandate') | axios.delete('/api/v4/payments/mandate') | ||||
.then(response => { | .then(response => { | ||||
this.mandate = { amount: 10, balance: 0 } | this.mandate = { amount: 10, balance: 0 } | ||||
if (response.data.status == 'success') { | if (response.data.status == 'success') { | ||||
this.$toast.success(response.data.message) | this.$toast.success(response.data.message) | ||||
} | } | ||||
}) | }) | ||||
}, | }, | ||||
paymentMethodForm(nextForm) { | paymentMethodForm(nextForm) { | ||||
const dialog = $('#payment-dialog') | const dialog = $('#payment-dialog') | ||||
this.formLock = false | this.formLock = false | ||||
this.paymentMethods = [] | this.paymentMethods = [] | ||||
this.paymentForm = 'method' | this.paymentForm = 'method' | ||||
this.nextForm = nextForm | this.nextForm = nextForm | ||||
if (nextForm == 'auto') { | if (nextForm == 'auto') { | ||||
this.paymentDialogTitle = 'Add auto-payment' | this.paymentDialogTitle = this.$t('wallet.auto-payment-setup') | ||||
} else { | } else { | ||||
this.paymentDialogTitle = 'Top up your wallet' | this.paymentDialogTitle = this.$t('wallet.top-up') | ||||
} | } | ||||
const methods = $('#payment-method') | const methods = $('#payment-method') | ||||
this.$root.addLoader(methods, false) | this.$root.addLoader(methods, false) | ||||
axios.get('/api/v4/payments/methods', {params: {type: nextForm == 'manual' ? 'oneoff' : 'recurring'}}) | axios.get('/api/v4/payments/methods', {params: {type: nextForm == 'manual' ? 'oneoff' : 'recurring'}}) | ||||
.then(response => { | .then(response => { | ||||
this.$root.removeLoader(methods) | this.$root.removeLoader(methods) | ||||
this.paymentMethods = response.data | this.paymentMethods = response.data | ||||
▲ Show 20 Lines • Show All 58 Lines • Show Last 20 Lines |