Untitled

mail@pastecode.io avatar
unknown
plain_text
a year ago
37 kB
2
Indexable
Never
<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>