Untitled
unknown
plain_text
2 years ago
37 kB
9
Indexable
<template>
<zendo-form
v-if="orderForm && formData"
v-slot="{ invalid, submit, loading }"
class="d-flex"
:class="$vuetify.breakpoint.smAndDown && 'secondary lighten-5'"
:style="!isInApp ? 'height: calc(100% - 84px)' : 'height: 100%'"
>
<v-container
v-if="orderForm"
fluid
class="order-page__body pt-2 pb-0 px-3"
>
<v-row :class="$vuetify.breakpoint.mdAndUp && 'h-100'">
<v-col
class="d-flex justify-end secondary lighten-5 pt-5 pt-md-10 px-8 px-md-8 px-lg-15 pb-5 pb-md-10 h-100"
cols="12"
md="7"
>
<div :style="$vuetify.breakpoint.width >= $constants.orderPage.maxContainerWidth ? 'width: 700px' : 'max-width: 100%'">
<div
class="d-flex justify-space-between align-center mb-5"
>
<div class="d-flex align-center">
<zendo-back-btn class="mr-6" @click="onClickBackBtn" />
<h3
class="text-h5 pr-2"
v-text="orderForm.offer.type === Types.Free ? $t('pages.order.index.slug.index.summary.label') : $t('pages.order.index.slug.index.checkout.label')"
/>
</div>
</div>
<div class="d-flex flex-wrap mb-3">
<v-img
v-if="orderForm.image_url"
:lazy-src="orderForm.image_url"
:src="orderForm.image_url"
:alt="orderForm.image_url"
max-width="200px"
max-height="11rem"
class="rounded-lg mb-5 mr-8"
/>
<div
class="partial-description"
:class="{
'partial-description-fade': orderForm.description && orderForm.description.length > 200
}"
>
<h3
v-if="orderForm.title"
class="text-h6 mb-2"
v-text="orderForm.title"
/>
<markdown-it-vue
v-if="orderForm.description"
class="pb-5 message-content text-body-2"
:content="orderForm.description"
/>
</div>
</div>
<div v-if="formData.selectedPackage.package">
<zendo-orderpage-packages-item-preview
summary
:currency="orderForm.offer.settings.currency"
:cycle="formData.selectedPackage.billing_cycle"
:value="formData.selectedPackage.package"
/>
</div>
<div v-if="!orderForm.form_enabled && !isSubscriptionType && orderForm.offer.services.length && quantityArr.length" class="services-select rounded-lg white pa-6 mt-3 pb-8">
<div class="text-h6 pb-4" v-text="$t('pages.order.slug.form.input.services.label')" />
<div
v-for="service in orderForm.offer.services"
:key="service.id"
class="d-flex flex-column justify-center align-center"
>
<div class="d-flex flex-column flex-md-row justify-space-between w-100 text-body-2 align-center item">
<div class="d-flex flex-column w-100 pr-8 pb-2 pb-md-0">
<v-checkbox
v-if="service.is_addon"
v-model="formData.services"
class="align-center text-body-2 font-weight-bold"
color="accent"
:value="service"
:name="service.name"
:label="`${service.name}`"
/>
<span
v-else
class="font-weight-bold"
v-text="service.name"
/>
<span v-if="service.is_quantifiable" class="font-italic secondary--text text--lighten">
<span v-if="service.max_quantity && service.min_quantity" v-text="$t('pages.order.index.slug.index.validation_between', {min: service.min_quantity, max: service.max_quantity})" />
<span v-else-if="service.max_quantity && !service.min_quantity" v-text="`${$t('pages.order.index.slug.index.validation_min')} ${service.max_quantity}`" />
<span v-else-if="service.min_quantity && !service.max_quantity" v-text="`${$t('pages.order.index.slug.index.validation_max')} ${service.min_quantity}`" />
</span>
</div>
<div class="d-flex align-center justify-space-between w-100" :style="$vuetify.breakpoint.mdAndUp && 'max-width: 220px'">
<div class="d-flex align-center mr-2">
<zendo-forms-quantity
v-if="service.is_quantifiable"
:disabled="service.is_addon && !formData.services.includes(service)"
:value="quantityArr.find(item => item.id === service.id).qty"
:name="`services.${service.id}.quantity`"
:class="`services.${service.id}.quantity`"
style="max-width: 110px"
small
inline
:min="service.min_quantity ? service.min_quantity : 1"
:max="service.max_quantity ? service.max_quantity : 9999"
center
controls
@change="updateLocalQuantityValues($event, service)"
/>
<div
v-else-if="quantityArr.find(item => item.id === service.id).qty > 1"
style="width: 110px; height: 45px"
class="d-flex align-center justify-center text-center secondary lighten-5 rounded-sm"
v-text="`${quantityArr.find(item => item.id === service.id).qty} x`"
/>
</div>
<div class="d-flex text-right font-weight-bold">
<div style="width: 90px">
<span v-if="service.price === null" v-text="$t('pages.order.slug.form.text.custom_price')" />
<span v-else v-text="service.price ? displayPrice(service.price) : $t('pages.order.slug.form.text.free')" />
</div>
</div>
</div>
</div>
<zendo-divider class="w-100 my-4" />
</div>
<p
v-if="totalPrice"
class="text-h5 mb-0 text-right mt-4"
v-text="displayPrice(totalPrice)"
/>
</div>
<div v-else-if="formData.services.length" class="white pa-6 rounded-lg">
<zendo-items-list
:headers-prop="headersConfig"
:type="offer.type"
:value="formData.services"
:is-tax-enabled="offer.settings.enabled_tax_support"
:currency="offer.settings.currency"
/>
</div>
</div>
</v-col>
<v-col
cols="12"
md="5"
class="d-flex justify-start pt-5 pt-md-10 px-8 px-md-8 px-lg-15"
>
<div :style="$vuetify.breakpoint.mdAndUp && 'max-width: 462px;'" class="h-100">
<div class="d-flex flex-column h-100">
<v-row class="align-content-start">
<template v-if="showInvoiceDetails">
<v-col cols="12">
<h3 class="text-h5" v-text="$t('pages.order.index.slug.index.checkout.invoice_details_title')" />
<p class="mb-0" v-text="$t('pages.order.index.slug.index.checkout.invoice_details_subtitle')" />
</v-col>
<v-col cols="12" sm="6">
<zendo-forms-text-field
v-model="formData.invoiceDetails.firstname"
name="firstname"
color="accent"
rules="required"
:label="$t('modules.settings.finances.details.first_name')"
/>
</v-col>
<v-col cols="12" sm="6">
<zendo-forms-text-field
v-model="formData.invoiceDetails.lastname"
name="lastname"
color="accent"
rules="required"
:label="$t('modules.settings.finances.details.last_name')"
/>
</v-col>
<v-col cols="12" sm="6">
<zendo-forms-text-field
v-model="formData.invoiceDetails.company_name"
name="invoice.company_name"
color="accent"
:label="$t('modules.settings.finances.details.company_name')"
/>
</v-col>
<v-col cols="12" sm="6">
<zendo-forms-select
v-model="formData.invoiceDetails.country"
color="accent"
name="invoice.country"
:label="$t('modules.settings.finances.details.country')"
:rules="$constants.validation.invoice.country"
:items="countryItems"
/>
</v-col>
<v-col cols="12" sm="6">
<zendo-forms-text-field
v-model="formData.invoiceDetails.st_address_1"
name="invoice.st_address_1"
:rules="$constants.validation.invoice.st_address_1"
color="accent"
:label="$t('modules.settings.finances.details.address_1')"
/>
</v-col>
<v-col cols="12" sm="6">
<zendo-forms-text-field
v-model="formData.invoiceDetails.st_address_2"
name="invoice.st_address_2"
:rules="$constants.validation.invoice.st_address_2"
color="accent"
:label="$t('modules.settings.finances.details.address_2')"
/>
</v-col>
<v-col cols="12" sm="6">
<zendo-forms-text-field
v-model="formData.invoiceDetails.city"
name="invoice.city"
:rules="$constants.validation.invoice.city"
color="accent"
:label="$t('modules.settings.finances.details.city')"
/>
</v-col>
<v-col cols="12" sm="6">
<zendo-forms-text-field
v-model="formData.invoiceDetails.state"
name="invoice.state"
:rules="$constants.validation.invoice.state"
color="accent"
:label="$t('modules.settings.finances.details.state')"
/>
</v-col>
<v-col cols="12" sm="6">
<zendo-forms-text-field
v-model="formData.invoiceDetails.zip"
name="invoice.zip"
:rules="$constants.validation.invoice.zip"
color="accent"
:label="$t('modules.settings.finances.details.zip')"
/>
</v-col>
<v-col cols="12" sm="6">
<zendo-forms-text-field
v-model="formData.invoiceDetails.tax_id"
name="invoice.tax_id"
rules="max:40"
color="accent"
:placeholder="$t('modules.settings.finances.details.tax.placeholder')"
:label="$t('modules.settings.finances.details.tax.label')"
/>
</v-col>
</template>
<template v-if="!$services.auth.isSignedIn">
<v-col cols="12" class="mt-5">
<h3 class="text-h5" v-text="$t('pages.order.index.slug.index.checkout.register_title')" />
<p class="mb-0" v-text="$t('pages.order.index.slug.index.checkout.register_subtitle')" />
</v-col>
<v-col
v-if="!showInvoiceDetails"
cols="12"
sm="6"
>
<zendo-forms-text-field
v-model="formData.firstname"
name="firstname"
color="accent"
rules="required"
:label="$t('modules.settings.finances.details.first_name')"
/>
</v-col>
<v-col
v-if="!showInvoiceDetails"
cols="12"
sm="6"
>
<zendo-forms-text-field
v-model="formData.lastname"
name="lastname"
color="accent"
rules="required"
:label="$t('modules.settings.finances.details.last_name')"
/>
</v-col>
<v-col cols="12">
<zendo-forms-text-field
v-model="formData.email"
:label="$t('pages.register.index.form.email.label')"
:placeholder="$t('pages.register.index.form.email.placeholder')"
:rules="$constants.validation.register.email"
color="accent"
name="email"
autocomplete="on"
type="email"
:disabled="loading || !!$route.query.email"
:debounce="500"
/>
</v-col>
<v-col cols="12" class="position-relative">
<zendo-forms-password-field
v-model="formData.password"
:label="$t('pages.register.index.form.password.label')"
:placeholder="$t('pages.register.index.form.password.placeholder')"
:rules="$constants.validation.register.password('@password_meter')"
color="accent"
name="password"
autocomplete="new-password"
type="password"
:disabled="loading"
:debounce="500"
/>
<zendo-forms-password-meter
name="password_meter"
:value="formData.password"
class="mt-5"
/>
</v-col>
<zendo-forms-text-field
v-model="formData.honeypot"
class="honeypot"
name="honeypot"
type="text"
/>
<v-col cols="12">
<zendo-forms-checkbox
:input-value.sync="formData.terms"
:rules="{ required: { allowFalse: false } }"
color="accent"
name="terms"
:disabled="loading"
class="terms"
>
<template #content>
{{ $t('pages.register.index.form.toc.message') }}
<zendo-link
class="px-1"
:href="$services.settingsWorkspace.termsOfServiceUrl"
target="_blank"
@click.stop
v-text="$t('pages.register.index.form.toc.link')"
/>
</template>
</zendo-forms-checkbox>
</v-col>
</template>
<template v-if="$services.auth.isSignedIn && !$services.auth.current.access.isClient">
<zendo-alert
v-if="orderForm.offer.type === Types.Subscription || (orderForm.offer.type === Types.Productized && orderForm.offer.settings.collect_payment === 'upfront')"
inline
type="warning"
>
{{ $t('modules.subcscriptions.components.premium_tokens.overlimit.owner') }}
</zendo-alert>
<v-col cols="12">
<h3 class="text-h5" v-text="$t('pages.order.index.slug.checkout.select_client_title')" />
<p class="mb-0" v-text="$t('pages.order.index.slug.checkout.select_client_subtitle')" />
</v-col>
<v-col cols="12" class="position-relative">
<zendo-clients-form-search
v-model="selectedUser"
name="email"
item-value="id"
rules="required"
:label="$t('pages.order.index.slug.checkout.select_client_label')"
/>
</v-col>
</template>
<v-col
cols="12"
class="d-sm-flex flex-wrap justify-end"
>
<zendo-btn
block
:disabled="invalid || (blockByFeatureToken && orderForm.offer.type === Types.Subscription) || ((orderForm.offer.type === Types.Subscription || (orderForm.offer.type === Types.Productized && orderForm.offer.settings.collect_payment === 'upfront')) && ($services.auth.isSignedIn && !$services.auth.current.access.isClient))"
:loading="loading"
type="submit"
color="accent"
class="mt-5 mt-sm-1 my-1"
@click.prevent="! invalid ? submit(orderForm.offer.type === Types.Subscription ? createSubscriptionRequest : createTaskRequest) : null"
>
{{ orderForm.offer.type !== Types.Subscription ? $t('pages.order.submit_request') : $t('pages.order.index.slug.index.go_to_checkout_btn_text') }}
</zendo-btn>
</v-col>
<v-col v-if="!$services.auth.isSignedIn" class="pt-0">
<p class="text-body-2 d-flex align-center">
{{ $t('pages.order.index.slug.checkout.login_text') }}
<zendo-link-btn
class="ml-1"
color="accent"
@click="onLogin"
>
{{ $t('pages.order.thank_you.log_in') }}
</zendo-link-btn>
</p>
</v-col>
</v-row>
<div class="d-flex justify-end w-100 pr-2 pt-10 pb-5 mt-auto">
<zendo-signet />
</div>
</div>
</div>
</v-col>
</v-row>
</v-container>
</zendo-form>
</template>
<script lang="ts">
import {
computed,
defineComponent, onMounted,
reactive,
ref,
useContext, useRoute, useRouter, watch,
} from '@nuxtjs/composition-api'
import MarkdownItVue from 'markdown-it-vue'
import { Component } from 'vue'
import OrderFormModel from '~/modules/orderpage/models/OrderForm'
import { TaskGuestCredentials } from '~/modules/tasks/types/tasks'
import { CustomFieldsResponse } from '~/modules/tasks/types/fields'
import { Nullable } from '~/types/type-utils'
import { LocalStorageRedirect } from '~/modules/core/types/localStorage'
import Task from '~/modules/tasks/models/Task'
import Item from '~/modules/items/models/Item'
import countryItems from '~/config/countries'
import headersConfig from '~/modules/items/config/table-headers/order-checkout'
import { Types } from '~/modules/documents/types'
import OrderForm from '~/modules/orderpage/types'
import OfferResponse = OrderForm.OfferResponse
import { CreateSubscriptionCredentials } from '~/modules/client-subscriptions/types'
import Permissions from '~/modules/subscriptions/models/Permissions'
interface Props {
orderForm: OrderFormModel
formImage: Nullable<string>
}
export default defineComponent<Props>({
components: {
MarkdownItVue: MarkdownItVue as Component,
},
setup (_, ctx) {
const { app, $config, $services, $localforage } = useContext()
const route = useRoute()
const router = useRouter()
const orderForm = ref<OrderFormModel>()
const quantityArr = ref([])
// @ts-ignore
const fields: CustomFieldsResponse = {}
const offer = ref<OfferResponse>()
const selectedUser = ref()
const isInApp = computed(() => $services.auth.current?.access.isClient)
const rewardful = $services.settingsWorkspace.integrations.rewardful
// const serviceURL = /\/service\//
const featureTokens = ref()
const blockByFeatureToken = ref(false)
const stripeStatus = $services.settingsWorkspace.payments.stripe_connect.status
const isSubscriptionType = ref(null)
$services.orderPage.get(route.value.params.slug).then(({ data }) => {
offer.value = data.offer
orderForm.value = data
isSubscriptionType.value = orderForm.value?.offer.type === 'subscription'
if (orderForm.value.fields) {
orderForm.value.fields.forEach((field) => {
// @ts-ignore
fields[field.id] = field.value
})
}
if (!data.form_enabled) {
setQuantityArr()
orderForm.value.offer.services.forEach((item) => {
updateLocalQuantityValues(item.quantity, item)
})
}
if (orderForm.value.offer.type) {
console.log(orderForm.value.offer.type)
}
console.log(isSubscriptionType.value)
}).catch(() => {
router.push({ name: '404' })
})
const formData = reactive<TaskGuestCredentials>({
email: $services.auth.current?.access.isClient ? $services.auth.current.email : null,
password: '',
title: '',
description: '',
invoiceDetails: {
firstname: '',
lastname: '',
company_name: '',
country: '',
st_address_1: '',
st_address_2: '',
city: '',
state: '',
zip: '',
tax_id: '',
},
fields: {
title: '',
},
services: [],
// @ts-ignore
selectedPackage: '',
// @ts-ignore
honeypot: '',
})
const appendFields = (fd: FormData, fields: Record<string, any>) => {
for (const [key, value] of Object.entries(fields)) {
if (value !== null && value !== undefined) {
fd.append(key, value)
}
}
}
const appendUserName = (fd: FormData) => {
const firstname = orderForm.value.offer.type === Types.Free ? formData.firstname : formData.invoiceDetails.firstname
const lastname = orderForm.value.offer.type === Types.Free ? formData.lastname : formData.invoiceDetails.lastname
fd.append('firstname', firstname)
fd.append('lastname', lastname)
}
const appendInvoiceDetails = (fd: FormData, isSubscription = false) => {
const prefix = 'invoice'
for (const [key, value] of Object.entries(formData.invoiceDetails)) {
if (value) {
fd.append(`${prefix}[${key}]`, value)
}
}
}
const appendServices = (fd: FormData) => {
formData.services.forEach((service) => {
if ((service.is_quantifiable && !service.is_addon) ||
(service.is_addon && formData.services.find(item => item.id === service.id))) {
fd.append(`selected_services[${service.id}]`, String(service.quantity))
}
})
}
const appendFormDataFields = (fd: FormData, expectedFieldsIds: string[]) => {
Object.entries(formData.fields)
.filter(([key]) => expectedFieldsIds.includes(key))
.forEach(([key, value]: [string, string | string[]]) => {
const fieldName = `order_submissions[${key}]`
if (Array.isArray(value)) {
value.forEach(item => fd.append(`${fieldName}[]`, item))
} else {
fd.append(fieldName, value as string)
}
})
}
const redirectToUrl = (url: string) => {
if (url) { window.location.replace(url) }
}
const createTaskRequest = async () => {
const fd = new FormData() as TaskGuestCredentials
const expectedFieldsIds = orderForm.value.fields.map(({ id }) => id)
const basicFields = {
offer: orderForm.value?.offer.id as string,
email: formData.email,
client: formData.email,
password: formData.password,
title: formData.fields.title,
// @ts-ignore
honeypot: formData.honeypot,
}
if (formData.fields.title === '' || formData.fields.title === undefined) {
formData.fields.title = orderForm.value.offer.title
}
if (!orderForm.value.form_enabled) {
const selectedServices = orderForm.value.offer.services.map((service) => {
if (service.is_addon && !formData.services.find(item => item.id === service.id)) {
return null
}
service.quantity = parseInt(setQtyToSend(service))
service.price_total = service.quantity * service.price
service.gross_price_total = service.price_total * (service.tax + 1)
return service
}).filter(el => el !== null)
formData.services = selectedServices
}
appendFields(fd, basicFields)
appendUserName(fd)
appendInvoiceDetails(fd)
appendServices(fd)
appendFormDataFields(fd, expectedFieldsIds)
if ($services.auth.isSignedIn) {
if (orderForm.value.offer.settings.collect_payment === 'upfront') {
return $services.tasks.createWithAuthorizedUpFront(fd)
.then(({ data }) => {
const url = data.url
url && redirectToUrl(url)
})
.catch(() => $services.alerts.error(app.i18n.t('pages.order.slug.form.alert.error') as string))
} else {
return $services.tasks.create(fd)
.then(({ data }) => onTaskCreated(data))
.catch(() => $services.alerts.error(app.i18n.t('pages.order.slug.form.alert.error') as string))
}
} else if (orderForm.value.offer.settings.collect_payment === 'upfront') {
return $services.tasks.createWithGuestUpFront(fd)
.then(({ data }) => {
const url = data.url
url && redirectToUrl(url)
})
.catch(() => $services.alerts.error(app.i18n.t('pages.order.slug.form.alert.error') as string))
} else {
return $services.tasks.createAsGuest(fd)
.then(({ data }) => onTaskCreated(data))
.catch(() => $services.alerts.error(app.i18n.t('pages.order.slug.form.alert.error') as string))
}
}
const createSubscriptionRequest = async () => {
const fd = new FormData() as CreateSubscriptionCredentials
const expectedFieldsIds = orderForm.value.fields.map(({ id }) => id)
const basicSubscriptionFields = {
offer_subscription_package: formData.selectedPackage.package.id,
time_interval: formData.selectedPackage.billing_cycle, // Added here
email: formData.email,
client: formData.email,
password: formData.password,
title: formData.fields.title,
// @ts-ignore
honeypot: formData.honeypot,
}
appendFields(fd, basicSubscriptionFields)
appendUserName(fd)
appendInvoiceDetails(fd)
appendFormDataFields(fd, expectedFieldsIds)
if ($services.auth.isSignedIn) {
return $services.clientSubscriptions.createSubscription(fd)
.then(({ data }) => {
if (
rewardful?.enabled &&
rewardful?.public_key &&
($services.auth.current?.access.isClient || !$services.auth.isSignedIn)
) {
window.rewardful('ready', () => {
window.rewardful('convert', { email: formData.email })
})
}
const url = data.url
if (url) { redirectToUrl(url) }
})
.catch(() => $services.alerts.error(app.i18n.t('pages.order.slug.form.alert.error') as string))
} else {
return $services.clientSubscriptions.createSubscriptionGuest(fd)
.then(({ data }) => {
const url = data.url
if (url) { redirectToUrl(url) }
})
.catch(() => $services.alerts.error(app.i18n.t('pages.order.slug.form.alert.error') as string))
}
}
const hasPermission = (permission: Nullable<string>) => {
if (!permission) {
return true
}
return Permissions.have(permission)
}
const prepareRedirectionUrl = (task?: Task) => {
$services.localStorage.remove('cache.redirect')
let url = `${window.location.origin}/requests`
if (task) {
url = `${window.location.origin}/requests/${task.slug}`
}
const localStorageRedirectData: LocalStorageRedirect = { url, type: 'order' }
$services.localStorage.set('cache.redirect', localStorageRedirectData)
}
const authPageRedirect = async (task: Task, checkout: boolean = false) => {
let routeName = 'login'
await $services.account.isRegistered({ hash: task.owner.getData().email_hash as string })
.then(({ data }) => {
if (!data.registered) {
routeName = 'register'
}
})
if (checkout) {
$services.alerts.success(app.i18n.t('pages.order.alert.success') as string)
}
router.push({
name: routeName,
query: { email: task.owner.email },
})
}
const onTaskCreated = (data: any) => {
$localforage.removeItem('checkout.order')
if (data.token) {
app.router?.push({
name: 'auth.confirmation.email',
query: {
type: 'email-verify',
token: data.token,
email: formData.email,
},
})
} else {
const task = new Task(data)
if ($services.auth.isSignedIn) {
$services.settingsProfile.fetch()
router.push({ name: 'requests.id', params: { id: task.slug } })
} else {
prepareRedirectionUrl(task)
authPageRedirect(task)
}
}
}
// New
const displayPrice = (price: string | number) =>
$services.utils.formatCurrency(offer.value.settings.currency, price)
const setQuantityArr = () => {
offer.value.services.forEach((item) => {
quantityArr.value.push({
id: item.id,
qty: item.quantity,
})
})
}
const setQtyToSend = (service: Item) => {
return String(quantityArr.value.find(item => item.id === service.id).qty)
}
const totalPrice = computed(() => {
let price = 0
if (orderForm.value.offer?.services?.length) {
orderForm.value.offer.services.forEach((item) => {
if (!item.is_addon) {
if (item.is_quantifiable) {
if (quantityArr.value.find(val => val.id === item.id)) {
price += item.price * quantityArr.value.find(val => val.id === item.id).qty
} else {
price += item.price * 1
}
} else {
price += item.price * item.quantity
}
} else if (formData.services.includes(item)) {
price += item.price * quantityArr.value.find(val => val.id === item.id).qty
}
})
}
return price
})
const updateLocalQuantityValues = (qtyValue: number, service: Item) => {
if (quantityArr.value.find(item => item.id === service.id)) {
quantityArr.value.find(item => item.id === service.id).qty = qtyValue
} else {
quantityArr.value.push({
id: service.id,
qty: qtyValue,
})
}
}
// End
watch(selectedUser, (value) => {
if (!value) { return }
$services.clients.get(value).then(({ data }) => {
Object.assign(formData, { invoiceDetails: data.settings.invoice })
formData.email = data.email
})
})
onMounted(async () => {
if ($services.auth.isSignedIn && $services.settingsProfile.data.invoice) {
$services.settingsProfile.fetch().then((data) => {
// @ts-ignore
Object.assign(formData, { invoiceDetails: data.invoice })
})
}
quantityArr.value = []
$localforage.getItem('checkout.order').then((data) => {
if (data) {
Object.assign(formData, data)
}
})
$services.settingsWorkspace.featureTokens().then((response) => {
featureTokens.value = response.feature_tokens.premium_token
if (stripeStatus !== 'connected') {
blockByFeatureToken.value = true
}
if (featureTokens.value.remaining <= 0 && !hasPermission('subscriptions')) {
blockByFeatureToken.value = true
}
})
})
const onLogin = () => {
$services.localStorage.remove('cache.redirect')
const url = orderForm.value.offer.type === Types.Free
? `${window.location.origin}/order/${route.value.params.slug}`
: `${window.location.origin}/order/${route.value.params.slug}/checkout`
const localStorageRedirectData: LocalStorageRedirect = { url, type: 'order' }
$services.localStorage.set('cache.redirect', localStorageRedirectData)
router.push({ name: 'login' })
}
const onClickBackBtn = () => {
// if ((serviceURL.test(route.value.path))) {
// router.push({ path: `/service/${route.value.params.slug}` })
// } else {
// router.push({ name: 'order.slug', params: { slug: route.value.params.slug } })
// }
if (!orderForm.value.form_enabled) {
router.push({ name: 'order' })
} else {
history.back()
}
}
const showInvoiceDetails = computed(() => {
return orderForm.value?.offer.type !== Types.Free && (!$services.auth.isSignedIn || ($services.auth.isSignedIn && $services.auth.current.access.isClient))
})
return {
isInApp,
headersConfig,
formData,
orderForm,
offer,
quantityArr,
currencyFormat: $services.settingsWorkspace.data.documents.currency,
countryItems,
selectedUser,
onLogin,
createTaskRequest,
createSubscriptionRequest,
onClickBackBtn,
Types,
showInvoiceDetails,
blockByFeatureToken,
displayPrice,
isSubscriptionType,
totalPrice,
updateLocalQuantityValues,
}
},
})
</script>
<style lang="sass">
.order-page__body
.password-helper
position: absolute
left: 100%
top: 2.75rem
width: 14em
.honeypot
width: 0
height: 0
opacity: 0
.items-table-preview.v-data-table
.v-data-table__wrapper
border: none !important
margin: 0 !important
table
border-collapse: collapse
.v-data-table-header tr th
height: 30px
tr
&:hover
background: transparent !important
td:first-child, th:first-child
padding-left: 0
td:last-child, th:last-child
padding-right: 0
table th
background: #FFF !important
border: none !important
.theme--light.v-data-table tbody tr
border-top: none !important
border-bottom: 1px solid #ccc !important
.item
min-height: 40px
.services-select .v-input--selection-controls .v-messages
height: 0
display: none
.services-select .v-messages__message
font-size: 10px
margin-top: 2px
.services-select .v-input--selection-controls__input
width: 1rem !important
height: 1rem !important
color: #FFF !important
background: #FFF !important
margin-top: 1px
.services-select .v-input__slot
margin-bottom: 0
.services-select .v-input__wrapper .theme--light.v-input__elem input
height: 21px
width: 55px
text-align: right
.services-select .v-input__wrapper .theme--light.v-input__elem .v-input__append-inner .v-input__icon
height: 20px
.v-label
font-weight: bold !important
.theme--light.v-btn.link-btn.v-btn--text:not([disabled]):not(.v-btn--active).link-btn.task-upload-btn
color: #000 !important
.terms
.v-label
font-weight: normal !important
.partial-description
flex: 1% 1 1
.partial-description-fade
position: relative
max-height: 11rem
overflow: hidden
&::after
content: ''
position: absolute
bottom: 0
left: 0
height: 3rem
width: 100%
background: linear-gradient(0, var(--v-secondary-lighten5), transparent)
</style>
Editor is loading...