Files
docuseal/app/javascript/submission_form/verification_step.vue
T

224 lines
5.7 KiB
Vue
Raw Normal View History

2024-12-01 00:10:07 +02:00
<template>
2025-03-18 17:34:11 +02:00
<label class="label text-xl sm:text-2xl py-0 mb-2 sm:mb-3.5 field-name-label">
2024-12-01 00:10:07 +02:00
<MarkdownContent
v-if="field.title"
:string="field.title"
/>
<template v-else>{{ field.name || t('identity_verification') }}</template>
</label>
<div
v-if="field.description"
dir="auto"
2025-03-18 17:34:11 +02:00
class="mb-4 px-1 field-description-text"
2024-12-01 00:10:07 +02:00
>
<MarkdownContent :string="field.description" />
</div>
<div
2025-09-25 10:30:02 +03:00
v-if="isRequiredFieldEmpty"
2025-03-18 17:34:11 +02:00
class="px-1 field-description-text"
2024-12-01 00:10:07 +02:00
>
{{ t('complete_all_required_fields_to_proceed_with_identity_verification') }}
</div>
<div v-else>
2026-04-12 13:30:13 +03:00
<div v-if="errorMessage">
{{ errorMessage }}
</div>
2024-12-01 00:10:07 +02:00
<div
2026-04-12 13:30:13 +03:00
v-else-if="isLoading"
2024-12-01 00:10:07 +02:00
class="w-full flex space-x-2 justify-center mb-2"
>
<IconInnerShadowTop
width="40"
class="animate-spin h-10"
2026-04-16 12:41:42 +03:00
aria-hidden="true"
2024-12-01 00:10:07 +02:00
/>
</div>
2025-01-31 21:15:05 +02:00
<div v-else-if="redirectUrl">
<a
:href="redirectUrl"
target="_blank"
class="white-button w-full"
>
{{ t('verify_id') }}
</a>
</div>
2024-12-01 00:10:07 +02:00
<div
ref="widgetContainer"
/>
</div>
</template>
<script>
import MarkdownContent from './markdown_content'
import { IconInnerShadowTop } from '@tabler/icons-vue'
import phoneData from './phone_data'
export default {
name: 'VerificationStep',
components: {
MarkdownContent,
IconInnerShadowTop
},
inject: ['baseUrl', 't'],
props: {
modelValue: {
type: String,
required: false,
default: ''
},
submitter: {
type: Object,
required: true
},
field: {
type: Object,
required: true
},
emptyValueRequiredStep: {
type: Object,
required: false,
default: null
},
values: {
type: Object,
required: true
},
locale: {
type: String,
required: false,
default: 'en'
},
submitterSlug: {
type: String,
required: true
}
},
emits: ['focus', 'submit', 'update:model-value', 'attached'],
data () {
return {
isCreatingCheckout: false,
isMathLoaded: false,
2025-01-31 21:15:05 +02:00
redirectUrl: '',
2024-12-01 00:10:07 +02:00
isLoading: false,
2026-04-12 13:30:13 +03:00
errorMessage: '',
2024-12-01 00:10:07 +02:00
eidEasyData: {}
}
},
computed: {
2025-09-25 10:30:02 +03:00
isRequiredFieldEmpty () {
return this.emptyValueRequiredStep && this.emptyValueRequiredStep[0] !== this.field
},
2024-12-01 00:10:07 +02:00
countryCode () {
const browserTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone
const browserTz = browserTimeZone.split('/')[1]
2024-12-03 20:49:28 +02:00
const country = phoneData.find(([a, b, c, e, tz]) => tz.includes(browserTz))
2024-12-01 00:10:07 +02:00
return country[0]
},
browserCountry () {
return (navigator.language || navigator.userLanguage || 'en').split('-')[1]
},
widgetSettings () {
return {
clientId: this.eidEasyData.client_id,
docId: this.eidEasyData.doc_id,
language: this.locale,
2024-12-04 17:40:46 +02:00
countryCode: this.countryCode,
2026-02-01 08:07:15 +02:00
sandbox: ['demo.docuseal.tech'].includes(location.host),
2024-12-01 00:10:07 +02:00
enabledMethods: {
signature: this.eidEasyData.available_methods
},
selectedMethod: null,
enabledCountries: 'all',
onSuccess: (data) => {
this.$emit('submit')
},
onFail: (error) => {
console.error(error)
}
}
}
},
async mounted () {
2025-09-25 10:30:02 +03:00
if (!this.isRequiredFieldEmpty) {
this.isLoading = true
2024-12-01 00:10:07 +02:00
2025-09-25 10:30:02 +03:00
if (new URLSearchParams(window.location.search).get('submit') === 'true') {
this.$emit('submit')
} else {
Promise.all([
import('@eid-easy/eideasy-widget'),
this.start()
]).finally(() => {
this.isLoading = false
})
}
2025-01-10 11:50:54 +02:00
}
2024-12-01 00:10:07 +02:00
},
methods: {
start () {
return fetch(this.baseUrl + `/api/identity_verification/${this.field.uuid}`, {
method: 'PUT',
body: JSON.stringify({
2025-07-17 18:33:24 +03:00
submitter_slug: this.submitterSlug,
redirect_url: document.location.href
2024-12-01 00:10:07 +02:00
}),
headers: { 'Content-Type': 'application/json' }
}).then(async (resp) => {
this.eidEasyData = await resp.json()
2026-04-12 13:30:13 +03:00
if (this.eidEasyData.error) {
this.errorMessage = this.eidEasyData.error
return
}
2025-09-18 10:48:29 +03:00
if (this.eidEasyData.check_completed) {
this.$emit('submit')
}
2025-01-31 21:15:05 +02:00
if (this.eidEasyData.available_methods[0] === 'itsme-qes-signature' &&
this.eidEasyData.available_methods.length === 1) {
const redirectUrl = new URL('https://id.eideasy.com/sign_contract_external')
2024-12-01 00:10:07 +02:00
2025-01-31 21:15:05 +02:00
redirectUrl.searchParams.append('client_id', this.eidEasyData.client_id)
redirectUrl.searchParams.append('doc_id', this.eidEasyData.doc_id)
redirectUrl.searchParams.append('country', this.countryCode)
redirectUrl.searchParams.append('lang', this.locale)
this.redirectUrl = redirectUrl.toString()
2025-09-25 10:30:02 +03:00
} else if (this.$refs.widgetContainer) {
2025-01-31 21:15:05 +02:00
const eidEasyWidget = document.createElement('eideasy-widget')
2024-12-01 00:10:07 +02:00
2025-01-31 21:15:05 +02:00
for (const key in this.widgetSettings) {
eidEasyWidget[key] = this.widgetSettings[key]
}
this.$refs.widgetContainer.innerHTML = ''
this.$refs.widgetContainer.appendChild(eidEasyWidget)
}
2024-12-01 00:10:07 +02:00
})
},
async submit () {
2025-09-18 10:48:29 +03:00
const resp = await fetch(this.baseUrl + '/api/identity_verification', {
2024-12-01 00:10:07 +02:00
method: 'POST',
body: JSON.stringify({
submitter_slug: this.submitterSlug
}),
headers: { 'Content-Type': 'application/json' }
})
2025-09-18 10:48:29 +03:00
if (resp.status === 404) {
throw new Error('Verification not completed yet')
}
if (resp.ok) {
return resp
} else {
throw new Error('Verification failed')
}
2024-12-01 00:10:07 +02:00
}
}
}
</script>