HEX
Server: nginx/1.18.0
System: Linux test-ipsremont 5.4.0-214-generic #234-Ubuntu SMP Fri Mar 14 23:50:27 UTC 2025 x86_64
User: ips (1000)
PHP: 8.0.30
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: //var/www/quadcode.com/src/components/popup/PopupForm.svelte
<script lang="ts">
  import InputField from '../../components/form/input/InputField.svelte';
  import InputFieldPhone from '../../components/form/input/InputFieldPhone.svelte';
  import TextareaField from '../../components/form/input/TextareaField.svelte';
  import CheckboxField from '../../components/form/input/CheckboxField.svelte';
  import closeIcon from '../../assets/icons/close.svg';
  import Button from '../../components/button/Button.svelte';
  import Recaptcha from '../../components/form/input/Recaptcha.svelte';
  import Message from '../../components/form/message/Message.svelte';
  import { browser } from '$app/environment';
  import type { IForm } from '$type/form';
  import Validation from '$utils/Validation';
  import { popupForm } from '../../store';
  import createEvent from '$utils/createEvents';
  import { localeLink, t } from '$lib/translations';
  import { getCookieByName } from '$utils/cookie';

  let roistatId = null;

  if (browser) {
    const urlParams = new URLSearchParams(window.location.search);
    const entries = urlParams.entries();
    for (const entry of entries) {
      localStorage.setItem('param__' + entry[0], entry[1]);
    }
    roistatId = getCookieByName('roistat_visit', document.cookie);
  }

  let recaptcha: { getResponse: () => string; reset: () => void };

  const formState: IForm = {
    loading: false,
    error: false,
    data: {
      name: '',
      email: '',
      phone: '',
      text: '',
      initialInvestment: '',
      agreement: false,
      roistatId,
    },
    response: {},
    status: 0,
  };

  createEvent({ event: 'saas_form_opening' });

  const sendForm = async () => {
    formState.loading = true;

    const code = document.querySelector('.iti__selected-dial-code');

    for (let i = 0; i < localStorage.length; i++) {
      let key = localStorage.key(i);
      if (key && key.includes('param__')) {
        formState.data[key.replace('param__', '')] = localStorage.getItem(key) || null;
      }
    }

    if (code) {
      formState.data.code = code.innerHTML;
    }

    let phone = formState.data.phone;

    if (phone) {
      if (String(phone).includes(String(formState.data.code))) {
        phone = formState.data.phone;
      } else {
        phone = String(formState.data.code) + String(formState.data.phone);
      }
      delete formState.data.code;
    }

    formState.data.token = recaptcha?.getResponse() ?? '';

    formState.data['landing_url'] = window.location.host + window.location.pathname;
    formState.data['language'] = document.documentElement.lang;
    formState.data['lang_by_browser'] = document.documentElement.lang;

    for (const [key, value] of Object.entries(formState.data)) {
      Validation({ name: key, value: value, formState });
    }

    if (Object.values(formState.response).length) {
      formState.loading = false;
      return;
    }

    createEvent({ event: 'saas_form_sent' });

    await fetch(`/api/send`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        ...formState.data,
        phone: String(phone).replace(/[^+\d]/g, ''),
      }),
    })
      .then((response) => {
        formState.status = response.status;
        return response.json();
      })
      .then((response) => {
        formState.response = response;
      })
      .finally(() => {
        formState.loading = false;
        recaptcha?.reset();
      });
  };

  const clickSendMore = () => {
    formState.data = {};
    formState.response = {};
    formState.status = 0;
    popupForm.set(false);
    recaptcha?.reset();
  };

  $: showMessage = formState.response?.status === 'ok' || [500, 502, 429].includes(formState.status);
</script>

<div class="popupForm">
  <div class="container">
    <div class="block-feedback">
      <div class="block-feedback__wrapper" on:click={() => popupForm.set(false)}>
        <div class="block-feedback__form" on:click|stopPropagation class:show-message={showMessage}>
          {#if !showMessage}
            <div class="test">
              <button
                class="block-feedback__close"
                on:click={() => popupForm.set(false)}
                aria-label="Close"
              >
                <img src={closeIcon} alt="Close" />
              </button>
              <p class="block-feedback__formTitle">{$t('Leave your request')}</p>
              <p class="block-feedback__formSubtitle">{$t('You are on the right path to creating your own broker')}</p>
              <div class="block-feedback__formItems">
                <div class="block-feedback__formItem">
                  <InputField
                    className="popup-form-input"
                    placeholder={$t('Full name')}
                    name="name"
                    error={formState.response.name}
                    value={String(formState.data.name || '')}
                    onChange={(e) => {
                      formState.data.name = e.currentTarget.value;
                      Validation({ name: 'name', value: e.currentTarget.value, formState });
                    }}
                  />
                </div>
                <div class="block-feedback__formItem">
                  <InputField
                    className="popup-form-input"
                    placeholder={$t('Email *')}
                    name="email"
                    error={formState.response.email}
                    value={String(formState.data.email || '')}
                    onChange={(e) => {
                      formState.data.email = e.currentTarget.value;
                      Validation({ name: 'email', value: e.currentTarget.value, formState });
                    }}
                  />
                </div>
                <div class="block-feedback__formItem">
                  <InputFieldPhone
                    className="popup-form-input phone-input"
                    placeholder={$t('Phone')}
                    name="phone"
                    error={formState.response.phone}
                    value={String(formState.data.phone || '')}
                    useFullscreenPopup={false}
                    onChange={(e) => {
                      formState.data.phone = e.currentTarget.value;
                      Validation({ name: 'phone', value: e.currentTarget.value, formState });
                    }}
                  />
                </div>
                <div class="block-feedback__formItem">
                  <InputField
                    className="popup-form-input"
                    placeholder={$t('Initial investment')}
                    name="initialInvestment"
                    error={formState.response.initialInvestment}
                    value={String(formState.data.initialInvestment || '')}
                    onChange={(e) => {
                      formState.data.initialInvestment = e.currentTarget.value;
                    }}
                  />
                </div>
                <div class="block-feedback__formItem">
                  <TextareaField
                    className="popup-form-textarea"
                    placeholder={$t('Message')}
                    name="text"
                    error={formState.response.text}
                    value={String(formState.data.text || '')}
                    onChange={(e) => {
                      formState.data.text = e.currentTarget.value;
                    }}
                  />
                </div>
                <div class="block-feedback__formItem">
                  <CheckboxField
                    placeholder={`${$t('I read and agree with')} <a href="${localeLink()}/terms-and-conditions">${$t('terms and conditions')}</a> ${$t('and')} <a href="${localeLink()}/privacy-policy">${$t('privacy policy')}</a> ${$t('of this website')}`}
                    name="agreement"
                    error={formState.response.agreement}
                    checked={Boolean(formState.data.agreement)}
                    onChange={(e) => {
                      formState.data.agreement = e.currentTarget.checked;
                      Validation({ name: 'agreement', value: e.currentTarget.checked, formState });
                    }}
                  />
                </div>
                <div class="block-feedback__formItem recaptcha">
                  <Recaptcha bind:this={recaptcha} error={formState.response.token} />
                </div>
                <div class="block-feedback__formItem">
                  <Button
                    text={$t('Get in touch')}
                    className="block-feedback__button"
                    onClick={sendForm}
                    loading={formState.loading}
                  />
                </div>
              </div>
              <p class="block-feedback__legalText">
                {$t('By continuing you accept our')} <a href="{localeLink()}/terms-and-conditions">{$t('Terms & Conditions')}</a> {$t('and')} <a href="{localeLink()}/privacy-policy">{$t('Privacy policy')}</a>
              </p>
            </div>
          {/if}
          {#if formState.response?.status === 'ok'}
            <Message
              onClick={clickSendMore}
              text={$t('Thank you for your interest! Our team will contact you shortly to discuss the details.')}
            />
          {/if}
          {#if [500, 502, 429].includes(formState.status)}
            <Message
              error={true}
              onClick={clickSendMore}
              text={formState.response.error || formState.response.message || ''}
            />
          {/if}
        </div>
      </div>
    </div>
  </div>
</div>

<style lang="scss">
  @import 'src/scss/media';
  @import 'src/scss/mixins';
  @import 'src/scss/variables';

  .popupForm {
    position: fixed;
    z-index: 101;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(#1B1C1D, 0.7);
    overflow-y: auto;
    padding: 16px 0;
    overflow: hidden;

    .container {
      height: max-content;
      position: relative;
      top: 50%;
      right: 16px;
      transform: translateY(-50%);
      margin: 0;
      max-width: 100%;


      @include breakpoint-down('tabL') {
        top: 0;
        right: 0;
        transform: none;
        padding: 0 16px;
      }

      
      @include breakpoint-down('mobL') {
        padding: 0 12px;
      }

  
    }

    &::-webkit-scrollbar {
      width: 0;
      opacity: 0;
      display: none;
    }
  }

  .block-feedback {
    &__wrapper {
      display: flex;
      align-items: flex-start;
      justify-content: flex-end;
      max-height: 100%;               
      overflow-y: auto;
      gap: 40px;

      @include breakpoint-down('deskL') {
        gap: 32px;
      }

      @include breakpoint-down('deskS') {
        gap: 20px;
      }

      @include breakpoint-down('tabM') {
        flex-direction: column;
        gap: 34px;
        justify-content: flex-start;
        align-items: flex-end;
      }
    }

    &__content {
      padding-top: 30px;
      width: 800px;

      @include breakpoint-down('deskL') {
        padding-top: 0;
        width: 639px;
      }

      @include breakpoint-down('deskS') {
        width: 100%;
        max-width: 43%;
      }

      @include breakpoint-down('tabM') {
        max-width: none;
      }
    }

    &__contentBlock {
      @include breakpoint-down('deskS') {
        display: flex;
        gap: 16px;
      }

      @include breakpoint-down('tabM') {
        display: none;
      }
    }

    &__form {
      position: relative;
      width: 522px;
      max-height: min(992px, calc(100vh - 32px));
      height: min(992px, calc(100vh - 32px));
      overflow-y: auto;
      overflow-x: hidden;
      padding: 68px 40px 40px 40px;
      border-radius: 32px;
      background: #f2f5f7;
      display: flex;
      flex-direction: column;

      scrollbar-width: none;
      -ms-overflow-style: none;

      &::-webkit-scrollbar {
        width: 0;
        height: 0;
        background: transparent;
        display: none;
      }

      @include breakpoint-down('deskL') {
        width: 490px;
      }

      @include breakpoint-down('deskS') {
        width: 100%;
        max-width: 490px;
      }

      @media (max-width: 393px) {
        padding: 68px 20px;
      }
    }

    &__form :global(.popup-form-input .inputInput) {
      background: $techWhite !important;
      border: none !important;
      border-radius: 16px !important;
      height: 60px !important;
    }


    &__formItem:focus .inputPlaceholder {
      font-size: 12px;
    }

    &__form :global(.inputContainer .inputPlaceholder) {
      font-size: 16px;
      line-height: 24px;
      left: 16px !important;
    }

    &__form :global(.phone-input .inputPlaceholder) {
      left: 136px !important;

    }

    &__form :global(.phone-input input){
      width: calc(100% - 120px) !important;
    }

    &__form :global(.popup-form-input.phone-input .inputPlaceholder) {
      font-size: 16px;
      line-height: 24px;
    }
    &__form :global(.popup-form-textarea .textareaInput) {
      background: $techWhite !important;
      border: none !important;
      border-radius: 16px !important;
      height: 166px !important; 
      box-shadow: none;
    }

  &__form :global(.popup-form-textarea .textareaPlaceholder){
    font-size: 16px ;
    line-height: 24px ;
  }

    &__title {
      @include titleXL;

      max-width: 80%;
      margin-bottom: 64px;

      @include breakpoint-down('deskL') {
        margin-bottom: 40px;
      }

      @include breakpoint-down('deskS') {
        margin-bottom: 36px;
      }

      @include breakpoint-down('tabM') {
        display: none;
      }

      > span {
        color: $redPrimary;
      }
    }

    &__grid {
      display: flex;
      align-items: center;
      width: 100%;
      max-width: 680px;
      gap: 27px;
      margin-bottom: 24px;
      user-select: none;

      @include breakpoint-down('deskL') {
        margin-bottom: 16px;
      }

      @include breakpoint-down('deskS') {
        flex-direction: column;
        margin-bottom: 0;
        width: max-content;
        gap: 24px;
      }
    }

    &__gridItem {
      position: relative;
      z-index: 1;
      display: flex;
      align-items: center;
      justify-content: center;
      flex: 1;
      text-align: center;

      width: 83px;
      min-width: 83px;
      height: 83px;

      background-image: url("data:image/svg+xml,%3Csvg width='83' height='83' viewBox='0 0 83 83' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='41.5' cy='41.5' r='41.5' fill='white'/%3E%3C/svg%3E%0A");
      background-repeat: no-repeat;
      background-size: contain;
      background-position: center;

      font-family: $Inter;
      font-size: 32px;
      font-weight: 400;
      line-height: 35px;

      @include breakpoint-down('deskL') {
        width: 64px;
        min-width: 64px;
        height: 64px;
        font-size: 24px;
        line-height: 26px;
      }

      @include breakpoint-down('deskS') {
        flex: none;
        width: 48px;
        min-width: 48px;
        height: 48px;
        font-size: 21px;
        line-height: 23px;
      }

      &:after {
        content: '';
        position: absolute;
        top: 50%;
        transform: translateY(-50%);
        height: 1px;
        width: 80%;
        background-image: url("data:image/svg+xml,%3Csvg width='70' height='1' viewBox='0 0 70 1' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cline x1='0.5' y1='0.5' x2='69.5' y2='0.5' stroke='%23CFDAE1' stroke-linecap='round' stroke-dasharray='1 7'/%3E%3C/svg%3E%0A");
        background-size: contain;
        z-index: -1;
        left: 100%;

        @include breakpoint-down('deskL') {
          width: 80%;
          left: 85%;
          background-image: url("data:image/svg+xml,%3Csvg width='68' height='1' viewBox='0 0 68 1' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cline x1='0.5' y1='0.5' x2='67.5' y2='0.500006' stroke='%23CFDAE1' stroke-linecap='round' stroke-dasharray='1 7'/%3E%3C/svg%3E%0A");
        }
      }

      &:first-of-type {
        margin-right: 34px;
        width: 115px;
        min-width: 115px;
        height: 115px;

        background-image: url("data:image/svg+xml,%3Csvg width='116' height='115' viewBox='0 0 116 115' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='58' cy='57.5' r='57.5' fill='url(%23paint0_linear_10220_19321)'/%3E%3Cdefs%3E%3ClinearGradient id='paint0_linear_10220_19321' x1='58' y1='0' x2='58' y2='115' gradientUnits='userSpaceOnUse'%3E%3Cstop stop-color='%2340454E'/%3E%3Cstop offset='1' stop-color='%23313840'/%3E%3C/linearGradient%3E%3C/defs%3E%3C/svg%3E%0A");

        color: $techWhite;
        font-size: 48px;
        font-weight: 500;
        line-height: 53px;

        @include breakpoint-down('deskL') {
          width: 80px;
          min-width: 80px;
          height: 80px;
          font-size: 36px;
          line-height: 40px;
          margin-left: 10px;
          margin-right: -4px;
        }

        @include breakpoint-down('deskS') {
          margin-left: 0;
          margin-right: 0;
          width: 64px;
          min-width: 64px;
          height: 64px;
          font-size: 28px;
          line-height: 30px;
        }

        &:after {
          @include breakpoint-down('deskL') {
            left: 90%;
          }
        }
      }

      &:last-of-type {
        &:after {
          display: none;
        }
      }
    }

    &__text {
      display: flex;
      align-items: flex-start;
      width: 100%;
      max-width: 680px;
      gap: 27px;

      @include breakpoint-down('deskS') {
        flex-direction: column;
        width: calc((100% - 64px));
        gap: 24px;
      }
    }

    &__textItem {
      @include smallDefault;

      flex: 1;
      text-align: center;

      @include breakpoint-down('deskS') {
        display: flex;
        align-items: center;
        text-align: left;
        flex: none;
        min-height: 48px;
      }

      &:first-of-type {
        @include baseTitle;

        min-width: 115px;
        margin-right: 34px;

        @include breakpoint-down('deskL') {
          margin-left: 3px;
          margin-right: -8px;
        }

        @include breakpoint-down('deskS') {
          min-height: 64px;
          min-width: auto;
          margin-left: 0;
          margin-right: 0;
        }
      }
    }

    & :global(.block-feedback__back) {
      margin-bottom: 40px;

      @include breakpoint-down('tabM') {
        margin-bottom: 0;
      }
    }

    &__close {
      position: absolute;
      top: 16px;
      right: 16px;
      background: #eaecef;
      border: none;
      border-radius: 48px;
      cursor: pointer;
      padding: 12px 16px;
      display: flex;
      align-items: center;
      justify-content: center;
      z-index: 100;
      transition: opacity 0.2s ease;
      width: auto;
      height: auto;

      img {
        width: 12px;
        height: 12px;
        display: block;
        filter: brightness(0) saturate(100%) invert(11%) sepia(0%) saturate(0%) hue-rotate(0deg) brightness(95%) contrast(100%);
      }

      &:hover {
        opacity: 0.7;
      }

      @include breakpoint-down('deskS') {
        top: 16px;
        right: 16px;
      }
    }

    &__formTitle {
      font-size: 32px;
      line-height: 40px;
      margin-bottom: 12px;
      color: #1B1C1D;


      @media (max-width: 1024px) {
        font-size: 28px;
        line-height: 36px;
      }
      @media (max-width: 720px) {
        font-size: 24px;
        line-height: 28px;
      }

      @media (max-width: 393px) {
        font-size: 20px;
        line-height: 26px;
        margin-bottom: 8px;
      }
    }

    &__formSubtitle {
      font-size: 14px;
      line-height: 20px;
      margin-bottom: 40px;
      color: #7D8387;

      @media (max-width: 1024px) {
        margin-bottom: 32px;
      }

      @media (max-width: 393px) {
        margin-bottom: 24px;
      }
    }

    &__legalText {
      color: #7D8387;
      font-size: 14px;
      line-height: 20px;
      max-width: 390px;
      margin-top:auto;

      a {
        color: #1B1C1D;
        border-bottom: 1px solid #D4D8DB;
        text-decoration: none;
      }
    }

    &__formItems {
      display: flex;
      flex-direction: column;
      gap: 12px;

      @include breakpoint-down('deskS') {
        gap: 24px;
      }
    }

    &__formItem {
      width: 100%;

      & :global(.checkboxContainer) {
        @include breakpoint-down('deskS') {
          margin-top: -16px;
        }
      }

      &.recaptcha {
        display: flex;
        justify-content: center;
        margin-top: 24px;
        margin-bottom: 12px;
        transform: scale(1.35);

        @media (max-width: 720px) {
          transform: scale(1.6);
        }

        @media (max-width: 480px) {
          transform: scale(1.45);
        }

        @media (max-width: 393px) {
          transform: scale(1.3);
        }
      }

      &:has(.block-feedback__button) {
        margin-top: 12px;
        margin-bottom: 70px;
      }
    }

    & :global(.block-feedback__button) {
      font-size: 16px;
      line-height: 24px;
      width: 100%;
      padding: 14px 0;
      background-color: #FF282B;
      margin-top: 0;
      &:hover{
        background-color: #E60019;
      }

      &:active{
        background-color: #C70214;
      }
    }
  }

  .back {
    display: flex;
    align-items: center;
    width: max-content;
    gap: 10px;
    cursor: pointer;

    @include breakpoint-down('deskS') {
      gap: 8px;
    }

    &__icon {
      width: 34px;
      height: 19px;
    }

    &__text {
      @include baseTitle;
    }
  }
  :global(.block-feedback__title span) {
    color: $redPrimary;
  }

  :global(.block-feedback__form .iti) {
    width: 100% !important;
  }

  :global(.block-feedback__form .iti .iti__selected-flag) {
    border-radius: 16px;
    padding: 10px 16px;
    border: none;
    background: white !important;
  }

  .block-feedback__form {
  :global(.popup-form-input.focus .inputPlaceholder),
  :global(.popup-form-input.value .inputPlaceholder) {
    font-size: 12px !important;
    line-height: 16px !important;
  }
  
  :global(.popup-form-input.phone-input.focus .inputPlaceholder),
  :global(.popup-form-input.phone-input.value .inputPlaceholder) {
    font-size: 12px !important;
    line-height: 16px !important;
  }

  :global(.popup-form-textarea.focus .textareaPlaceholder),
  :global(.popup-form-textarea.value .textareaPlaceholder) {
    font-size: 12px !important;
    line-height: 16px !important;
  }

  :global(.iti__flag-container){
    width: 112px;
  }
}
</style>