@ecomplus/storefront-app
Version:
Vue.js ecommerce app with cart, checkout and account pages
264 lines (250 loc) • 6.6 kB
HTML
<form
class="credit-card needs-validation"
@submit.prevent="submit"
novalidate
>
<transition
enter-active-class="animated fadeIn"
leave-active-class="animated fadeOut"
>
<div
v-show="isWaitingCardHash"
class="credit-card__loading"
>
<div
class="spinner-border"
role="status"
>
<span class="sr-only">Loading...</span>
</div>
</div>
</transition>
<div
v-if="gatewayOptions && gatewayOptions.length"
class="form-group"
>
<label
v-if="gatewayOptionsLabel"
for="credit-card-gateway"
>
{{ gatewayOptionsLabel }}
</label>
<select
class="custom-select"
id="credit-card-gateway"
@change="ev => $emit('select-gateway', gatewayOptions[ev.target.value])"
required
>
<option
v-if="gatewayOptionsLabel"
value=""
>--</option>
<option
v-for="({ label }, i) in gatewayOptions"
:value="i"
>
{{ label.replace(creditCardRegex, '') }}
</option>
</select>
</div>
<div class="form-group credit-card__bin">
<label for="credit-card-bin">
{{ i19cardNumber }}
</label>
<div class="input-group">
<input
v-if="!canFormatBinInput"
type="tel"
class="form-control"
:class="!isNumberPotentiallyValid && alert.bin ? 'is-invalid': null"
v-model="formattedCardBin"
@blur="alert.bin = card.bin && !isNumberPotentiallyValid"
autocomplete="cc-number"
required
/>
<cleave-input
v-else
ref="binInput"
type="tel"
class="form-control"
:class="!isNumberPotentiallyValid && alert.bin ? 'is-invalid': null"
id="credit-card-bin"
v-model="formattedCardBin"
:raw="false"
@blur="alert.bin = card.bin && !isNumberPotentiallyValid"
:options="{ creditCard: true }"
autocomplete="off"
required
/>
<div
class="input-group-append"
v-if="activeBrand && brands.indexOf(activeBrand) > -1"
>
<span class="input-group-text">
<i
class="pay-icon"
:class="`pay-icon--${activeBrand}`"
></i>
</span>
</div>
</div>
</div>
<div class="form-group credit-card__name">
<label for="credit-card-name">
{{ i19holderName }}
</label>
<div class="input-group">
<input
type="text"
pattern="[^\d\s]+.*"
maxlength="64"
class="form-control"
id="credit-card-name"
:placeholder="i19nameOnCard"
v-model="card.name"
@change="checkName"
autocomplete="cc-name"
required
/>
</div>
</div>
<transition
enter-active-class="animated fadeInDown"
leave-active-class="animated fadeOutUp position-absolute"
>
<div v-if="!canHideHolderFields">
<div class="form-group">
<label for="credit-card-birth">
{{ i19birthdate }}
</label>
<input-date
id="credit-card-birth"
v-model="card.birth"
:required="isPayerDocRequired"
/>
</div>
<div class="form-group">
<label for="credit-card-doc">
{{ i19bearersDocument }}
</label>
<input-doc-number
id="credit-card-doc"
:is-company="isCompany"
v-model="card.doc"
:required="isPayerDocRequired"
/>
</div>
</div>
</transition>
<div class="form-row">
<div class="form-group col-lg-6">
<label for="credit-card-validate">
{{ i19validThru }}
</label>
<input
v-if="!canFormatExpInput"
type="tel"
class="form-control"
:class="alert.date ? 'is-invalid': null"
:placeholder="`mm/${(lang === 'pt_br' ? 'aa' : 'yy')}`"
@blur="() => { alert.date = card.date && !validateDate() }"
v-model="rawCardExp"
autocomplete="cc-exp"
required
/>
<cleave-input
v-else
ref="expInput"
type="tel"
class="form-control"
:class="alert.date ? 'is-invalid': null"
id="credit-card-validate"
:placeholder="`mm/${(lang === 'pt_br' ? 'aa' : 'yy')}`"
@blur="() => { alert.date = card.date && !validateDate() }"
v-model="rawCardExp"
:options="{
date: true,
datePattern: ['m', 'y']
}"
autocomplete="off"
required
/>
</div>
<div class="form-group col-lg-6">
<label for="credit-card-cvv">
CVV
<span
class="text-muted"
:title="i19securityCode"
data-container="body"
data-toggle="popover"
data-trigger="hover"
data-placement="top"
:data-content="i19aboutCvvMsg"
v-once
>
<i class="i-question-circle"></i>
</span>
</label>
<input
type="tel"
class="form-control"
:class="alert.cvv ? 'is-invalid': null"
id="credit-card-cvv"
pattern="\d{3,4}"
placeholder="123"
v-model="card.cvv"
@blur="() => { alert.cvv = card.cvv && !validateCvv() }"
autocomplete="cc-csc"
required
/>
</div>
</div>
<div
v-if="installmentList.length || isLoadingInstallments"
class="form-group"
>
<label for="credit-card-installment">
{{ i19parcelIn }}
</label>
<transition-group
enter-active-class="animated fadeInDown"
leave-active-class="d-none"
>
<select
key="installments"
v-if="!isLoadingInstallments"
class="custom-select"
id="credit-card-installment"
v-model="card.installment"
>
<option :value="1">
{{ formatMoney(amount.total) }}
{{ i19atSight }}
</option>
<option
v-for="({ number, value, tax }) in installmentList"
v-if="number > 1"
:value="number"
>
{{ `${number}x ${i19of} ${formatMoney(value)}` }}
<template v-if="!tax">
{{ i19interestFree }}
</template>
</option>
</select>
<div
key="loading"
v-else
class="mx-2 spinner-grow"
role="status"
>
<span class="sr-only">Loading...</span>
</div>
</transition-group>
</div>
<button class="btn btn-lg btn-block btn-success" type="submit">
<i class="i-lock mr-1"></i>
{{ i19confirmPurchase }}
</button>
</form>