templates/pages/tariff/tariff_web.html.twig line 1

Open in your IDE?
  1. <figure class="mt-[10px] lg:mt-[40px] mx-auto max-w-max lg:max-w-[1328px] px-[24px]">
  2.     {% include '@App/shared/ui/header/header.html.twig' %}
  3.     <div class="stepper-wrapper mt-[80px] mb-[24px]">
  4.         <div class="stepper-item active">
  5.             <div class="step-counter">01</div>
  6.             <div class="step-name">{% trans from 'tarif_choice' %}Тарифні плани{% endtrans %}</div>
  7.         </div>
  8.         <div class="stepper-item ">
  9.             <div class="step-counter">02</div>
  10.             <div class="step-name">{% trans from 'tarif_choice' %}Реєстрація E-mail{% endtrans %}</div>
  11.         </div>
  12.         <div class="stepper-item ">
  13.             <div class="step-counter">03</div>
  14.             <div class="step-name">{% trans from 'tarif_choice' %}Отримання номеру{% endtrans %}</div>
  15.         </div>
  16.         <div class="stepper-item">
  17.             <div class="step-counter">04</div>
  18.             <div class="step-name">{% trans from 'tarif_choice' %}Підтвердження та оплата{% endtrans %}</div>
  19.         </div>
  20.         <div class="stepper-item">
  21.             <div class="step-counter">05</div>
  22.             <div class="step-name">{% trans from 'tarif_choice' %}Отримання eSIM{% endtrans %}</div>
  23.         </div>
  24.     </div>
  25.     <div class="rounded-[16px] p-[16px] md:p-[32px] border border-[#E2E2E9] bg-[#F7F7FA]">
  26.         <div class="mt-[14px] p-0 md:p-[18px] max-w-full mx-auto rounded-[24px] ">
  27.             <div class="flex justify-between items-center relative">
  28.                 <div class="absolute left-[-10px] top-[-10px] md:left-0 md:top-0">
  29.                     {% include '@App/shared/ui/backButton/backButtonWeb.html.twig' %}
  30.                 </div>
  31.                 <div class="flex flex-col gap-[16px] text-center mt-[32px] md:mt-0 mx-auto max-w-[485px]">
  32.                     <div class="text-[24px] font-semibold text-[#1B2028]"
  33.                          style="{{ inlineStyles(app.request.get('companyInner'), constant('App\\Constants\\SettingConstants::BLOCK_TITLE_STYLES')) }}"
  34.                     >{% trans from 'tarif_choice' %}Перегляд тарифу{% endtrans %}</div>
  35.                 </div>
  36.                 {% if faqs is defined and faqs is not empty %}
  37.                     {#                <a href="{{ path('how_it_works') }}" class="font-medium text-[#E64829] text-[16px] text-center block hover:underline mt-[30px]">{% trans from 'main' %}Як працює eSIM?{% endtrans %}</a> #}
  38.                     <div class="absolute right-[-10px] top-[-10px] md:right-0 md:top-0">
  39.                         <div class="relative group">
  40.                             <button data-modal="#modal_faq"
  41.                                     class="js--modal hover:underline transition ease-in-out duration-150 block text-center w-[34px] h-[34px] p-[7px] md:w-[48px] md:h-[48px] md:p-[14px] bg-transparent border rounded-[50%] border-none font-semibold text-[16px] focus:outline-none"
  42.                                     style="color: {{ companyStyles.linkTextColor }}; --custom-color: {{ companyStyles.buttonColor }}; background-color: rgba(from var(--custom-color) r g b / 0.2)">
  43.                                 <svg class="w-[20px] h-[20px]"
  44.                                      style="fill: {{ companyStyles.buttonColor }}; border-color: {{ companyStyles.buttonColor }}">
  45.                                     <use href="{{ asset('build/sprite.svg#question') }}"></use>
  46.                                 </svg>
  47.                             </button>
  48.                             <!-- Тултип -->
  49.                             <div class="w-[160px] text-right text-[14px] absolute hidden group-hover:block bg-[#1A1A1A] text-white rounded py-[4px] px-[8px] right-full top-1/2 -translate-y-1/2 mr-2 transition-opacity duration-200 opacity-0 group-hover:opacity-100">
  50.                                 {% trans from 'tarif_choice' %}Поширені питання та відповіді{% endtrans %}
  51.                                 <!-- Стрелка -->
  52.                                 <div class="absolute w-0 h-0 border-4 border-transparent border-l-[#1A1A1A] -right-2 top-1/2 -translate-y-1/2"></div>
  53.                             </div>
  54.                         </div>
  55.                     </div>
  56.                 {% endif %}
  57.             </div>
  58.             {#            <div class="text-[16px] font-medium text-[#A0A4AE] mb-[20px] text-{{ companyStyles.descriptionTextAlign }}"> #}
  59.             {#                {% if is_granted('ROLE_FRONT_USER') %}{% trans from 'register' %}Крок 1/3{% endtrans %}{% else %}{% trans from 'register' %}Крок 1/5{% endtrans %}{% endif %} #}
  60.             {#            </div> #}
  61.             <div class="gap-[10px] mt-[32px] pr-[8px]">
  62.                 {% if esimPresence is defined and esimPresence is not null and esimPresence == false %}
  63.                     <div class="rounded-[16px] p-[18px] border border-[#E2E2E9] bg-[#ffffff] mt-[40px]">
  64.                         <div class="text-[24px] font-semibold text-[#1B2028] mx-auto text-{{ companyStyles.descriptionTextAlign }} {% if companyStyles.descriptionTextAlign == 'center' %}max-w-[360px]{% endif %}"
  65.                         >{% trans from 'tarif_choice' %}На жаль, наразі немає доступних номерів. Спробуйте пізніше{% endtrans %}</div>
  66.                     </div>
  67.                 {% else %}
  68.                     {# ===== MOBILE LAYOUT (< 767px) ===== #}
  69.                     <div class="block md:hidden">
  70.                         <div class="rounded-[16px] p-[18px] w-full border border-[#E2E2E9] bg-[#ffffff]">
  71.                             {% if tariff.mainImage is not empty %}
  72.                                 <div class="w-full h-auto mb-[16px]">
  73.                                     {{ sonata_media(tariff.mainImage, 'reference') }}
  74.                                 </div>
  75.                             {% elseif tariff.imageLink %}
  76.                                 <div class="w-full h-auto mb-[16px]">
  77.                                     <img src="{{ tariff.imageLink }}" alt="{{ tariff.name }}"/>
  78.                                 </div>
  79.                             {% endif %}
  80.                             <div class="text-[20px] text-[#1B2028] font-medium">{{ tariff.name }}</div>
  81.                             {% if tariff.reference is not empty %}
  82.                                 <div class="text-[12px] text-[#5B5B5B] font-medium">{% trans from 'tarif_choice' %}Артикул:{% endtrans %} {{ tariff.reference }}</div>
  83.                             {% endif %}
  84.                             {% if tariff.shortInfo is not empty %}
  85.                                 {# Accordion: Короткий опис #}
  86.                                 <div class="tariff-accordion mt-[16px] border border-[#E2E2E9] rounded-[16px] overflow-hidden">
  87.                                     <button class="tariff-accordion__toggle w-full flex justify-between items-center p-[14px] bg-[#F7F7FA] text-[16px] font-medium text-[#1B2028]" aria-expanded="true">
  88.                                         <span>Короткий опис</span>
  89.                                         <svg class="tariff-accordion__icon w-[20px] h-[20px] transition-transform duration-300" style="stroke: #5B5B5B; fill: none;" viewBox="0 0 24 24" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  90.                                             <polyline points="6 9 12 15 18 9"/>
  91.                                         </svg>
  92.                                     </button>
  93.                                     <div class="tariff-accordion__body px-[14px] pb-[14px] text-[14px] text-[#5B5B5B] prose break-words">
  94.                                         {{ tariff.shortInfo|raw }}
  95.                                     </div>
  96.                                 </div>
  97.                             {% endif %}
  98.                             {# Accordion: Детальна інформація #}
  99.                             {% if tariff.detailedInfo is not empty %}
  100.                                 <div class="tariff-accordion mt-[12px] border border-[#E2E2E9] rounded-[16px] overflow-hidden">
  101.                                     <button class="tariff-accordion__toggle w-full flex justify-between items-center p-[14px] bg-[#F7F7FA] text-[16px] font-medium text-[#1B2028]" aria-expanded="false">
  102.                                         <span>{% trans from 'tarif_choice' %}Детальна інформація{% endtrans %}</span>
  103.                                         <svg class="tariff-accordion__icon w-[20px] h-[20px] transition-transform duration-300" style="stroke: #5B5B5B; fill: none;" viewBox="0 0 24 24" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  104.                                             <polyline points="6 9 12 15 18 9"/>
  105.                                         </svg>
  106.                                     </button>
  107.                                     <div class="tariff-accordion__body hidden px-[14px] pb-[14px] text-[14px] text-[#5B5B5B] prose break-words">
  108.                                         {{ tariff.detailedInfo|raw }}
  109.                                     </div>
  110.                                 </div>
  111.                             {% endif %}
  112.                         </div>
  113.                         {# Sticky buttons bar #}
  114.                         <div id="tariff-sticky-bar" class="fixed bottom-0 left-0 right-0 z-50 bg-white border-t border-[#E2E2E9] px-[16px] py-[12px] flex flex-col gap-[8px] transition-all duration-300">
  115.                             {% if tariff.active %}
  116.                                 <a href="{{ path('tariff_selected_page',{tariff:tariff.id}) }}" class="w-full">
  117.                                     <button class="hover:underline transition ease-in-out duration-150 w-full flex flex-row gap-[8px] justify-center text-center p-[12px] min-h-[48px] bg-transparent border rounded-[10px] font-semibold text-[14px] focus:outline-none"
  118.                                             style="color: {{ companyStyles.notFilledButtonTextColor }}; border-color: {{ companyStyles.notFilledButtonTextColor }}">
  119.                                         {% trans with {'%price%': tariff.price} from 'tarif_choice' %}Купити за %price%₴{% endtrans %}
  120.                                     </button>
  121.                                 </a>
  122.                             {% else %}
  123.                                 <button type="button" disabled class="w-full opacity-50 cursor-not-allowed pointer-events-none transition ease-in-out duration-150 flex flex-row gap-[8px] justify-center text-center p-[12px] min-h-[48px] bg-transparent border border-[#E2E2E9] text-[#5B5B5B] rounded-[10px] font-semibold text-[14px] focus:outline-none">
  124.                                     {% trans from 'tarif_choice' %}Немає в наявності{% endtrans %}
  125.                                 </button>
  126.                             {% endif %}
  127.                             <a href="{{ path('operator_tariff_page',{slug:tariff.operator.slug}) }}" class="w-full">
  128.                                 <button class="hover:underline transition ease-in-out duration-150 w-full flex flex-row gap-[8px] justify-center text-center p-[12px] min-h-[48px] bg-transparent border rounded-[10px] font-semibold text-[14px] focus:outline-none"
  129.                                         style="color: {{ companyStyles.notFilledButtonTextColor }}; border-color: {{ companyStyles.notFilledButtonTextColor }}">
  130.                                     {% trans from 'tarif_choice' %}Обрати інший тариф{% endtrans %}
  131.                                 </button>
  132.                             </a>
  133.                         </div>
  134.                         {# Sentinel: when buttons scroll into natural position, hide sticky bar #}
  135.                         <div id="tariff-buttons-sentinel" class="rounded-[16px] p-[18px] w-full border border-[#E2E2E9] bg-[#ffffff] mt-[12px]">
  136.                             <div class="flex flex-wrap justify-center flex-col gap-[8px] w-full">
  137.                                 {% if tariff.active %}
  138.                                     <a href="{{ path('tariff_selected_page',{tariff:tariff.id}) }}" class="w-full">
  139.                                         <button class="hover:underline transition ease-in-out duration-150 w-full flex flex-row gap-[8px] justify-center text-center p-[12px] min-h-[48px] bg-transparent border rounded-[10px] font-semibold text-[14px] focus:outline-none"
  140.                                                 style="color: {{ companyStyles.notFilledButtonTextColor }}; border-color: {{ companyStyles.notFilledButtonTextColor }}">
  141.                                             {% trans with {'%price%': tariff.price} from 'tarif_choice' %}Купити за %price%₴{% endtrans %}
  142.                                         </button>
  143.                                     </a>
  144.                                 {% else %}
  145.                                     <button type="button" disabled class="w-full opacity-50 cursor-not-allowed pointer-events-none transition ease-in-out duration-150 flex flex-row gap-[8px] justify-center text-center p-[12px] min-h-[48px] bg-transparent border border-[#E2E2E9] text-[#5B5B5B] rounded-[10px] font-semibold text-[14px] focus:outline-none">
  146.                                         {% trans from 'tarif_choice' %}Немає в наявності{% endtrans %}
  147.                                     </button>
  148.                                 {% endif %}
  149.                                 <a href="{{ path('operator_tariff_page',{slug:tariff.operator.slug}) }}" class="w-full">
  150.                                     <button class="hover:underline transition ease-in-out duration-150 w-full flex flex-row gap-[8px] justify-center text-center p-[12px] min-h-[48px] bg-transparent border rounded-[10px] font-semibold text-[14px] focus:outline-none"
  151.                                             style="color: {{ companyStyles.notFilledButtonTextColor }}; border-color: {{ companyStyles.notFilledButtonTextColor }}">
  152.                                         {% trans from 'tarif_choice' %}Обрати інший тариф{% endtrans %}
  153.                                     </button>
  154.                                 </a>
  155.                             </div>
  156.                         </div>
  157.                     </div>
  158.                     {# ===== DESKTOP LAYOUT (>= 767px) ===== #}
  159.                     <div class="hidden md:block">
  160.                         <div class="rounded-[16px] p-[18px] w-full border border-[#E2E2E9] bg-[#ffffff]">
  161.                             <div class="flex flex-col md:flex-row content-start gap-[32px]">
  162.                                 {% if tariff.mainImage is not empty %}
  163.                                     <div class="w-full h-auto ">
  164.                                         {{ sonata_media(tariff.mainImage, 'reference') }}
  165.                                     </div>
  166.                                 {% elseif tariff.imageLink %}
  167.                                     <div class="w-full h-auto ">
  168.                                         <img src="{{ tariff.imageLink }}" alt="{{ tariff.name }}"/>
  169.                                     </div>
  170.                                 {% endif %}
  171.                                 <div class="w-full h-auto flex flex-col content-start">
  172.                                     <div class="text-[20px] text-[#1B2028] font-medium">{{ tariff.name }}</div>
  173.                                     {% if tariff.reference is not empty %}
  174.                                         <div class="text-[12px] text-[#5B5B5B] font-medium">{% trans from 'tarif_choice' %}Артикул:{% endtrans %} {{ tariff.reference }}</div>
  175.                                     {% endif %}
  176.                                     {% if tariff.shortInfo is not empty %}
  177.                                         <div class="mt-[32px] text-[14px] text-[#5B5B5B] prose break-words">{{ tariff.shortInfo|raw }}</div>
  178.                                     {% endif %}
  179.                                     <div class="flex flex-wrap justify-center flex-row gap-[10px] mt-[32px] w-full">
  180.                                         {% if tariff.active %}
  181.                                             <a href="{{ path('tariff_selected_page',{tariff:tariff.id}) }}"
  182.                                                class="mt-auto w-full max-w-[250px]"
  183.                                             >
  184.                                                 <button class=" hover:underline transition ease-in-out duration-150 w-full flex flex-row gap-[8px] justify-center text-center p-[12px] min-h-[48px] bg-transparent border rounded-[10px] font-semibold text-[14px] mt-[16px] focus:outline-none"
  185.                                                         style="color: {{ companyStyles.notFilledButtonTextColor }}; border-color: {{ companyStyles.notFilledButtonTextColor }}">
  186.                                                     {% trans with {'%price%': tariff.price} from 'tarif_choice' %}Купити за %price%₴{% endtrans %}
  187.                                                 </button>
  188.                                             </a>
  189.                                         {% else %}
  190.                                             <button type="button" disabled class="mt-auto w-full max-w-[250px] opacity-50 cursor-not-allowed pointer-events-none hover:underline transition ease-in-out duration-150 flex flex-row gap-[8px] justify-center text-center p-[12px] min-h-[48px] bg-transparent border border-[#E2E2E9] text-[#5B5B5B] rounded-[10px] font-semibold text-[14px] mt-[16px] focus:outline-none">
  191.                                                 {% trans from 'tarif_choice' %}Немає в наявності{% endtrans %}
  192.                                             </button>
  193.                                         {% endif %}
  194.                                         <a href="{{ path('operator_tariff_page',{slug:tariff.operator.slug}) }}"
  195.                                            class="mt-auto w-full max-w-[250px]"
  196.                                         >
  197.                                             <button class=" hover:underline transition ease-in-out duration-150 w-full flex flex-row gap-[8px] justify-center text-center p-[12px] min-h-[48px] bg-transparent border rounded-[10px] font-semibold text-[14px] mt-[16px] focus:outline-none"
  198.                                                     style="color: {{ companyStyles.notFilledButtonTextColor }}; border-color: {{ companyStyles.notFilledButtonTextColor }}">
  199.                                                 {% trans from 'tarif_choice' %}Обрати інший тариф{% endtrans %}
  200.                                             </button>
  201.                                         </a>
  202.                                     </div>
  203.                                 </div>
  204.                             </div>
  205.                             <div class="rounded-[16px] p-[18px] mt-[32px] w-full border border-[#E2E2E9] bg-[#ffffff]">
  206.                                 <div class="text-[18px] text-[#1B2028] font-medium">{% trans from 'tarif_choice' %}Детальна інформація{% endtrans %}</div>
  207.                                 <article class="mb-[10px]">
  208.                                     {% if tariff.detailedInfo is not empty %}
  209.                                         <div class="mt-[32px] text-[14px] text-[#5B5B5B] prose break-words">{{ tariff.detailedInfo|raw }}</div>
  210.                                     {% endif %}
  211.                                 </article>
  212.                             </div>
  213.                         </div>
  214.                     </div>
  215.                 {% endif %}
  216.             </div>
  217.         </div>
  218.     </div>
  219. </figure>
  220. <!-- modal-window fixed hidden top-0 left-0 right-0 z-50 show:opacity-100 w-full p-4 overflow-x-hidden overflow-y-auto mx-auto md:inset-0 max-h-full -->
  221. {% for modal in tariff.operator.tariffs %}
  222.     {% if modal.description is not empty %}
  223.         {% include '@App/shared/ui/modal/modal_web.html.twig' with {
  224.             id: modal.id,
  225.             name: modal.name,
  226.             image: modal.mainImage,
  227.             imageLink: modal.imageLink,
  228.             description: modal.description | raw,
  229.             showButton: true,
  230.         } %}
  231.     {% endif %}
  232. {% endfor %}
  233. <script>
  234. (function () {
  235.     // Only run on mobile (< 767px)
  236.     if (window.innerWidth >= 767) return;
  237.     // ── Accordion ──────────────────────────────────────────────
  238.     document.querySelectorAll('.tariff-accordion__toggle').forEach(function (btn) {
  239.         var body = btn.nextElementSibling;
  240.         var icon = btn.querySelector('.tariff-accordion__icon');
  241.         var isOpen = btn.getAttribute('aria-expanded') === 'true';
  242.         // Apply initial state
  243.         if (!isOpen) {
  244.             body.classList.add('hidden');
  245.             icon.style.transform = 'rotate(-90deg)';
  246.         } else {
  247.             body.classList.remove('hidden');
  248.             icon.style.transform = 'rotate(0deg)';
  249.         }
  250.         btn.addEventListener('click', function () {
  251.             var expanded = btn.getAttribute('aria-expanded') === 'true';
  252.             if (expanded) {
  253.                 btn.setAttribute('aria-expanded', 'false');
  254.                 body.classList.add('hidden');
  255.                 icon.style.transform = 'rotate(-90deg)';
  256.             } else {
  257.                 btn.setAttribute('aria-expanded', 'true');
  258.                 body.classList.remove('hidden');
  259.                 icon.style.transform = 'rotate(0deg)';
  260.             }
  261.         });
  262.     });
  263.     // ── Sticky bar ─────────────────────────────────────────────
  264.     var stickyBar = document.getElementById('tariff-sticky-bar');
  265.     var sentinel = document.getElementById('tariff-buttons-sentinel');
  266.     if (stickyBar && sentinel) {
  267.         var observer = new IntersectionObserver(function (entries) {
  268.             entries.forEach(function (entry) {
  269.                 if (entry.isIntersecting) {
  270.                     // Sentinel is visible — hide sticky bar
  271.                     stickyBar.style.transform = 'translateY(100%)';
  272.                     stickyBar.style.opacity = '0';
  273.                     stickyBar.style.pointerEvents = 'none';
  274.                 } else {
  275.                     // Sentinel not visible — show sticky bar
  276.                     stickyBar.style.transform = 'translateY(0)';
  277.                     stickyBar.style.opacity = '1';
  278.                     stickyBar.style.pointerEvents = '';
  279.                 }
  280.             });
  281.         }, { threshold: 0.1 });
  282.         observer.observe(sentinel);
  283.     }
  284. })();
  285. </script>