templates/application/hubs/index.html.twig line 1

Open in your IDE?
  1. {% extends 'application/layout.html.twig' %}
  2. {% block content %}
  3.         <h1>Распределительные центры</h1>
  4.         <form class="rc-search" id="searchForm">
  5.             <div class="form__group">
  6.                 <input id="chainSearchInput" name="text" type="text" class="form__control" placeholder="Поиск по наименованию, адресу, сети">
  7.             </div>
  8.             <div class="form__btn">
  9.                 <button type="submit" class="btn" disabled="disabled">
  10.                         <span class="btn__icon">
  11.                             <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M9.063 3.438a5.625 5.625 0 1 0 0 11.25 5.625 5.625 0 0 0 0-11.25zm-7.5 5.624a7.5 7.5 0 1 1 15 0 7.5 7.5 0 0 1-15 0z" fill="#405464"/><path fill-rule="evenodd" clip-rule="evenodd" d="M13.04 13.04a.937.937 0 0 1 1.326 0l3.797 3.797a.937.937 0 0 1-1.326 1.326l-3.797-3.797a.937.937 0 0 1 0-1.326z"/></svg>
  12.                         </span>
  13.                     <span class="btn__text">Найти</span>
  14.                 </button>
  15.             </div>
  16.             <div class="rc-search__dropdown dropdown scroll" id="searchResult">
  17.             </div>
  18.         </form>
  19.         <div class="main__content box rc-list">
  20.             <div class="rc-list__header">
  21.                 <div class="btn-group rc-list__toggle a-toggle-list">
  22.                     <button class="btn btn--light active show-list">
  23.                             <span class="btn__icon">
  24.                                 <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M3.125 12.73a.806.806 0 0 1-.593-.24.806.806 0 0 1-.24-.594c0-.236.08-.43.24-.584a.826.826 0 0 1 .593-.229h13.75c.236 0 .434.08.594.24.16.16.24.35.24.573 0 .236-.08.434-.24.594a.807.807 0 0 1-.594.24H3.125zm0 3.728a.806.806 0 0 1-.593-.24.806.806 0 0 1-.24-.593c0-.236.08-.43.24-.583a.826.826 0 0 1 .593-.23h13.75c.236 0 .434.08.594.24.16.16.24.35.24.573 0 .25-.08.451-.24.604a.826.826 0 0 1-.594.23H3.125zm0-7.479a.806.806 0 0 1-.593-.24.782.782 0 0 1-.24-.572c0-.236.08-.434.24-.594.16-.16.357-.24.593-.24h13.75c.236 0 .434.08.594.24.16.16.24.358.24.594s-.08.43-.24.583a.826.826 0 0 1-.594.23H3.125zm0-3.75a.806.806 0 0 1-.593-.24.806.806 0 0 1-.24-.593c0-.236.08-.43.24-.583a.826.826 0 0 1 .593-.23h13.75c.236 0 .434.08.594.24.16.16.24.35.24.573 0 .25-.08.451-.24.604a.826.826 0 0 1-.594.23H3.125z"/></svg>
  25.                             </span>
  26.                         <span class="btn__text">Список</span>
  27.                     </button>
  28.                     <button class="btn btn--light show-map">
  29.                             <span class="btn__icon">
  30.                                 <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M10 16.417c1.778-1.625 3.09-3.101 3.938-4.427.847-1.327 1.27-2.49 1.27-3.49 0-1.583-.503-2.875-1.51-3.875-1.007-1-2.24-1.5-3.698-1.5-1.458 0-2.691.5-3.698 1.5-1.007 1-1.51 2.292-1.51 3.875 0 1 .434 2.16 1.302 3.48.868 1.319 2.17 2.798 3.906 4.437zm0 1.812c-.125 0-.247-.017-.365-.052A.867.867 0 0 1 9.313 18c-2.07-1.847-3.619-3.552-4.646-5.114C3.639 11.322 3.125 9.86 3.125 8.5c0-2.139.691-3.847 2.073-5.125C6.58 2.097 8.18 1.458 10 1.458c1.82 0 3.42.64 4.802 1.917 1.382 1.278 2.073 2.986 2.073 5.125 0 1.361-.514 2.823-1.542 4.386-1.027 1.562-2.576 3.267-4.646 5.114a.882.882 0 0 1-.312.177 1.256 1.256 0 0 1-.375.052z"/></svg>
  31.                             </span>
  32.                         <span class="btn__text">На карте</span>
  33.                     </button>
  34.                 </div>
  35.                 <div class="rc-list__tags">
  36.                     <div id="chainList" class="rc-tag">
  37.                         <div class="rc-tag__item active">
  38.                             <a href="#" class="rc rc-tag__link chainItem" data-id="">
  39.                                 <span class="rc__name">Все РЦ</span>
  40.                             </a>
  41.                         </div>
  42.                         {% for chain in topChains %}
  43.                             <div class="rc-tag__item">
  44.                                 <a href="#" class="rc rc-tag__link chainItem" data-id="{{ chain.id }}">
  45.                                         <span class="rc__logo">
  46.                                             <img width="30" height="30" src="{{ resizeImage(chain.image) }}" />
  47.                                         </span>
  48.                                     <span class="rc__name">{{ chain.name }}</span>
  49.                                 </a>
  50.                             </div>
  51.                         {% endfor %}
  52.                     </div>
  53.                     {% if showMoreChains %}
  54.                         <button class="btn btn--light rc-tag__all">
  55.                             <span class="btn__text">Еще</span>
  56.                             <span class="btn__icon">
  57.                                     <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M6.375 8.675c.217-.183.458-.28.725-.287.267-.009.5.087.7.287l4.225 4.225 4.25-4.25c.183-.183.42-.27.713-.262.291.008.529.104.712.287.217.217.32.454.313.713a.994.994 0 0 1-.313.687l-4.975 4.975c-.1.1-.208.175-.325.225a.942.942 0 0 1-.375.075.941.941 0 0 1-.375-.075 1.038 1.038 0 0 1-.325-.225l-4.95-4.95a.916.916 0 0 1-.288-.7c.009-.267.105-.508.288-.725z"/></svg>
  58.                                 </span>
  59.                         </button>
  60.                     {% endif %}
  61.                 </div>
  62.             </div>
  63.             <div class="rc-list__body">
  64.                 <div class="tbl">
  65.                     <div class="tbl__body scroll" id="hubTable">
  66.                         {% include 'application/hubs/hub-table.html.twig' %}
  67.                     </div>
  68.                 </div>
  69.                 <div class="map" id="map" style="height: 100%; width: 100%">
  70.                 </div>
  71.             </div>
  72.         </div>
  73. {% endblock %}
  74. {% block popups %}
  75.     <div class="panel panel--rc scroll">
  76.         <button class="panel__close">
  77.             <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M3.636 3.636a1 1 0 0 1 1.414 0L16.364 14.95a1 1 0 0 1-1.415 1.414L3.636 5.05a1 1 0 0 1 0-1.414z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M3.636 16.364a1 1 0 0 1 0-1.414L14.95 3.636a1 1 0 1 1 1.414 1.414L5.05 16.364a1 1 0 0 1-1.414 0z"/></svg>
  78.         </button>
  79.         <div id="hubPanel"></div>
  80.     </div>
  81.     <div class="panel panel--review scroll">
  82.         <button class="panel__close">
  83.             <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M3.636 3.636a1 1 0 0 1 1.414 0L16.364 14.95a1 1 0 0 1-1.415 1.414L3.636 5.05a1 1 0 0 1 0-1.414z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M3.636 16.364a1 1 0 0 1 0-1.414L14.95 3.636a1 1 0 1 1 1.414 1.414L5.05 16.364a1 1 0 0 1-1.414 0z"/></svg>
  84.         </button>
  85.         <div class="panel__header">
  86.             <h3 class="panel__title text--primary">Оставьте отзыв</h3>
  87.         </div>
  88.         <div class="panel__body">
  89.             <form class="form" id="reviewForm">
  90.                 <input type="hidden" name="hubId" id="reviewIdInput">
  91.                 <div class="form__group form__group--md">
  92.                     <div class="form__label">Номер заказа</div>
  93.                     <input name="orderNumber" type="text" class="form__control w-sm" placeholder="Введите номер" required>
  94.                 </div>
  95.                 {% for key, rating in ratings %}
  96.                     <div class="add-review__item ">
  97.                         <div class="add-review__num">{{ loop.index }}</div>
  98.                         <div class="add-review__title">{{ rating }}</div>
  99.                         <div class="add-review__rating">
  100.                             <input type="hidden" name="ratings[{{ key }}]">
  101.                             <div class="rating a-rating">
  102.                                 <div class="rating__item"><svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M27.911 12.668a1.746 1.746 0 0 0-.593-.848 1.763 1.763 0 0 0-.97-.366l-6.363-.437-2.357-5.91A1.764 1.764 0 0 0 16 4a1.764 1.764 0 0 0-1.628 1.107l-2.4 5.942-6.32.405c-.352.023-.69.151-.969.368a1.779 1.779 0 0 0-.037 2.773l4.863 4.089-1.446 5.654a1.959 1.959 0 0 0 .75 2.087 1.936 1.936 0 0 0 2.152.064l5.024-3.163h.022l5.41 3.397c.277.18.6.276.931.277a1.776 1.776 0 0 0 1.393-.694 1.751 1.751 0 0 0 .3-1.52l-1.532-6.187 4.841-4.004a1.788 1.788 0 0 0 .557-1.927z"></path></svg></div>
  103.                                 <div class="rating__item"><svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M27.911 12.668a1.746 1.746 0 0 0-.593-.848 1.763 1.763 0 0 0-.97-.366l-6.363-.437-2.357-5.91A1.764 1.764 0 0 0 16 4a1.764 1.764 0 0 0-1.628 1.107l-2.4 5.942-6.32.405c-.352.023-.69.151-.969.368a1.779 1.779 0 0 0-.037 2.773l4.863 4.089-1.446 5.654a1.959 1.959 0 0 0 .75 2.087 1.936 1.936 0 0 0 2.152.064l5.024-3.163h.022l5.41 3.397c.277.18.6.276.931.277a1.776 1.776 0 0 0 1.393-.694 1.751 1.751 0 0 0 .3-1.52l-1.532-6.187 4.841-4.004a1.788 1.788 0 0 0 .557-1.927z"></path></svg></div>
  104.                                 <div class="rating__item"><svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M27.911 12.668a1.746 1.746 0 0 0-.593-.848 1.763 1.763 0 0 0-.97-.366l-6.363-.437-2.357-5.91A1.764 1.764 0 0 0 16 4a1.764 1.764 0 0 0-1.628 1.107l-2.4 5.942-6.32.405c-.352.023-.69.151-.969.368a1.779 1.779 0 0 0-.037 2.773l4.863 4.089-1.446 5.654a1.959 1.959 0 0 0 .75 2.087 1.936 1.936 0 0 0 2.152.064l5.024-3.163h.022l5.41 3.397c.277.18.6.276.931.277a1.776 1.776 0 0 0 1.393-.694 1.751 1.751 0 0 0 .3-1.52l-1.532-6.187 4.841-4.004a1.788 1.788 0 0 0 .557-1.927z"></path></svg></div>
  105.                                 <div class="rating__item"><svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M27.911 12.668a1.746 1.746 0 0 0-.593-.848 1.763 1.763 0 0 0-.97-.366l-6.363-.437-2.357-5.91A1.764 1.764 0 0 0 16 4a1.764 1.764 0 0 0-1.628 1.107l-2.4 5.942-6.32.405c-.352.023-.69.151-.969.368a1.779 1.779 0 0 0-.037 2.773l4.863 4.089-1.446 5.654a1.959 1.959 0 0 0 .75 2.087 1.936 1.936 0 0 0 2.152.064l5.024-3.163h.022l5.41 3.397c.277.18.6.276.931.277a1.776 1.776 0 0 0 1.393-.694 1.751 1.751 0 0 0 .3-1.52l-1.532-6.187 4.841-4.004a1.788 1.788 0 0 0 .557-1.927z"></path></svg></div>
  106.                                 <div class="rating__item"><svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M27.911 12.668a1.746 1.746 0 0 0-.593-.848 1.763 1.763 0 0 0-.97-.366l-6.363-.437-2.357-5.91A1.764 1.764 0 0 0 16 4a1.764 1.764 0 0 0-1.628 1.107l-2.4 5.942-6.32.405c-.352.023-.69.151-.969.368a1.779 1.779 0 0 0-.037 2.773l4.863 4.089-1.446 5.654a1.959 1.959 0 0 0 .75 2.087 1.936 1.936 0 0 0 2.152.064l5.024-3.163h.022l5.41 3.397c.277.18.6.276.931.277a1.776 1.776 0 0 0 1.393-.694 1.751 1.751 0 0 0 .3-1.52l-1.532-6.187 4.841-4.004a1.788 1.788 0 0 0 .557-1.927z"></path></svg></div>
  107.                             </div>
  108.                         </div>
  109.                     </div>
  110.                 {% endfor %}
  111.                 <div class="form__group">
  112.                     <textarea id="reviewMessage" name="message" class="form__control" cols="30" rows="3" placeholder="Оставить текстовый отзыв"></textarea>
  113.                 </div>
  114.                 <div class="form__group file a-file">
  115.                     <div class="file__path">
  116.                         <input name="image" type="file" accept="image/*">
  117.                         <span class="file__icon"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M13.473 3.348a3.75 3.75 0 1 1 5.288 5.319L9.78 17.31a1.125 1.125 0 0 1-1.56-1.622l8.972-8.635a1.5 1.5 0 0 0-2.128-2.115l-9.197 9.178a3.37 3.37 0 0 0 4.766 4.766l7.697-7.68a1.125 1.125 0 1 1 1.59 1.594l-7.697 7.677a5.62 5.62 0 1 1-7.947-7.948l9.197-9.178z"/></svg></span>
  118.                         <span id="reviewFileName" class="file__text">Приложить фото</span>
  119.                     </div>
  120.                 </div>
  121.                 <div class="form__btn form__btn--sm">
  122.                     <button class="btn btn--block" type="submit">Отправить</button>
  123.                 </div>
  124.             </form>
  125.         </div>
  126.     </div>
  127. {% endblock %}
  128. {% block scripts %}
  129.     <script>
  130.         $(document).ready(function () {
  131.             function chainFilterClick(item) {
  132.                 let id = item.attr('data-id');
  133.                 $.ajax({
  134.                     type: "GET",
  135.                     url: '{{ path('select-chain') }}',
  136.                     data: {
  137.                         id: id,
  138.                     },
  139.                     dataType: "json",
  140.                     success: function (data) {
  141.                         $('#hubTable').html(data.html);
  142.                         $('#chainList > div').removeClass('active');
  143.                         $('#chainList a[data-id="' + id + '"]').parent().addClass('active');
  144.                         updateMap(data.hubPoints);
  145.                         initHubTable();
  146.                     }
  147.                 }).fail(function() {
  148.                     popupAlert('Ошибка');
  149.                 });
  150.                 return false;
  151.             }
  152.             $('.chainItem').click(function () {
  153.                 chainFilterClick($(this));
  154.             });
  155.             initHubTable();
  156.             $('.rc-search .form__control').keyup(function() {
  157.                 if($(this).val()) {
  158.                     $.ajax({
  159.                         type: "GET",
  160.                         url: '{{ path('hub-search-chain') }}',
  161.                         data: {
  162.                             text: $(this).val(),
  163.                         },
  164.                         success: function (html) {
  165.                             $('#searchResult').html(html);
  166.                             $('#searchResult .chainItem').click(function () {
  167.                                 $('.rc-search .dropdown').hide();
  168.                                 if ($(this).attr('data-id')) {
  169.                                     $('.rc-search .btn').attr('disabled','disabled');
  170.                                     $('#chainSearchInput').val('');
  171.                                     chainFilterClick($(this));
  172.                                 } else {
  173.                                     $('#chainSearchInput').val($(this).attr('data-name'));
  174.                                 }
  175.                             });
  176.                         }
  177.                     });
  178.                 }
  179.             });
  180.             $('#searchForm').submit(function () {
  181.                 $.ajax({
  182.                     type: "POST",
  183.                     url: '{{ path('hub-search') }}',
  184.                     data: $('#searchForm').serialize(),
  185.                     dataType: "json",
  186.                     success: function (data) {
  187.                         $('#hubTable').html(data.html);
  188.                         $('#chainList > div').removeClass('active');
  189.                         $('#chainList a[data-id=""]').parent().addClass('active');
  190.                         $('.rc-search .dropdown').hide();
  191.                         updateMap(data.hubPoints);
  192.                         initHubTable();
  193.                     }
  194.                 }).fail(function() {
  195.                     popupAlert('Ошибка');
  196.                 });
  197.                 return false;
  198.             });
  199.             function initHubTable() {
  200.                 $('.hubLink').click(function () {
  201.                     openHubPanel($(this).attr('data-id'));
  202.                     return false;
  203.                 });
  204.             }
  205.             $('#reviewForm').submit(function () {
  206.                 let messageRequired = false;
  207.                 let rating = null;
  208.                 {% for key, rating in ratings %}
  209.                     rating = $(this).find('input[name="ratings[{{ key }}]"').val();
  210.                     if (!rating) {
  211.                         popupAlert('Не выбран рейтинг "{{ rating }}"');
  212.                         return false;
  213.                     }
  214.                     if (rating == 1 || rating == 2) {
  215.                         messageRequired = true;
  216.                     }
  217.                 {% endfor %}
  218.                 if (messageRequired && !$('#reviewMessage').val()) {
  219.                     popupAlert('Не заполнен отзыв');
  220.                     return false;
  221.                 }
  222.                 $.ajax({
  223.                     type: "POST",
  224.                     url: '{{ path('review-message') }}',
  225.                     data: new FormData($(this)[0]),
  226.                     dataType: "json",
  227.                     contentType: false,
  228.                     processData: false,
  229.                     success: function () {
  230.                         popupAlert('Ваш отзыв отправлен');
  231.                         closePopup();
  232.                         $('.a-rating div.checked').removeClass('checked');
  233.                         $('#reviewForm input').val('');
  234.                         $('#reviewForm textarea').val('');
  235.                         $('#reviewFileName').html('Приложить фото');
  236.                     }
  237.                 }).fail(function() {
  238.                     popupAlert('Ошибка');
  239.                 });
  240.                 return false;
  241.             });
  242.             $('.a-rating div').click(function () {
  243.                 let parent = $(this).parent();
  244.                 parent.parent().find('input').val(parent.find('div.checked').length);
  245.             });
  246.         });
  247.         function openHubPanel(id) {
  248.             history.pushState({}, '', '/hubs/' + id);
  249.             $.ajax({
  250.                 type: "GET",
  251.                 url: '{{ path('hub-panel') }}',
  252.                 data: {
  253.                     id: id,
  254.                 },
  255.                 success: function (html) {
  256.                     $('#hubPanel').html(html);
  257.                     $('.panel--rc').addClass('showen');
  258.                     $('.panel__backdrop').addClass('showen');
  259.                     $('.tabs__link').on('click', function() {
  260.                         var tabName = $(this).attr('data-tab');
  261.                         $(this).closest('.tabs').find('.tabs__item.active').removeClass('active');
  262.                         $(this).closest('.tabs__item').addClass('active');
  263.                         $(this).closest('.tabs').find('.tabs__pane.show').removeClass('show');
  264.                         $('#' + tabName + '').addClass('show');
  265.                     });
  266.                     $('.dropdown__toggle').on('click', function(){
  267.                         if ( ! $(this).closest('.dropdown').hasClass('opened')) {
  268.                             $('.dropdown').removeClass('opened');
  269.                             $(this).closest('.dropdown').toggleClass('opened');
  270.                         } else {
  271.                             $('.dropdown').removeClass('opened');
  272.                         }
  273.                         return false;
  274.                     });
  275.                     $('.dropdown__menu').click(function(e){
  276.                         e.stopPropagation();
  277.                     });
  278.                     new Carousel(document.querySelector('.carousel'), {
  279.                             'infinite' : false,
  280.                             'center': false,
  281.                             'fill' : true,
  282.                             'dragFree' : false
  283.                     });
  284.                 }
  285.             }).fail(function() {
  286.                 popupAlert('Ошибка');
  287.             });
  288.         }
  289.         function openReview(id) {
  290.             closePopup();
  291.             $('#reviewIdInput').val(id);
  292.             $('.panel__backdrop').addClass('showen');
  293.             $('.panel--review').addClass('showen');
  294.         }
  295.         {% if openHubId %}
  296.         openHubPanel('{{ openHubId }}');
  297.         {% endif %}
  298.     </script>
  299.     <script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU" type="text/javascript"></script>
  300.     <script>
  301.         {% set id = random() %}
  302.         let map{{ id }} = null;
  303.         function updateMap(hubPoints) {
  304.             let map = map{{ id }};
  305.             let objects = [];
  306.             map.geoObjects.each(function (geoObject) {
  307.                 objects.push(geoObject);
  308.                 return true;
  309.             });
  310.             for (let i = 0; i < objects.length; i++) {
  311.                 map.geoObjects.remove(objects[i]);
  312.             }
  313.             for (let i = 0; i < hubPoints.length; i++) {
  314.                 let point = hubPoints[i];
  315.                 if (point.icon) {
  316.                     let myPlacemark = new ymaps.Placemark(point.coordinates, {
  317.                         hintContent: point.name,
  318.                     }, {
  319.                         iconLayout: 'default#image',
  320.                         iconImageHref: point.icon,
  321.                         iconImageSize: [30, 30],
  322.                         iconImageOffset: [0, 0],
  323.                     });
  324.                     myPlacemark.events.add([
  325.                         'click',
  326.                     ], function (e) {
  327.                         openHubPanel(point.id);
  328.                     });
  329.                     map.geoObjects.add(myPlacemark);
  330.                 }
  331.             }
  332.         }
  333.         ymaps.ready(function () {
  334.             map{{ id }} = new ymaps.Map('map',
  335.                 {
  336.                     center: [55.751574, 37.573856],
  337.                     zoom: 6
  338.                 },
  339.                 {
  340.                     searchControlProvider: 'yandex#search'
  341.                 }
  342.             );
  343.             updateMap({{ hubPoints|json_encode|raw }});
  344.         });
  345.     </script>
  346. {% endblock %}