templates/components/cards/card-product.html.twig line 1

Open in your IDE?
  1. {% import "macros/product.html.twig" as productMacros %}
  2. {% import 'components/avatar.html.twig' as avatar %}
  3. {% import 'components/button.html.twig' as button %}
  4. {% import _self as self %}
  5. <article class="product-card flex flex-col h-full">
  6.   <header class="product-card__image-container">
  7.     <a href="{{ path('app_product_show', {'slug': product.slug}) }}" class="relative flex h-full">
  8.       {% if (product.mainProductImage) %}
  9.       <img src="{{ path('app_media_display', {'id': product.mainProductImage.id}) }}" alt="{{ product.name }} image" loading="lazy" class="product-card__img">
  10.       {% endif %}
  11.     </a>
  12.     <div class="product-card__right">
  13.       {% if (product.brand and product.brand.logo) %}
  14.         <img src="{{ path('app_media_thumbnail_display', {'id': product.brand.logo.id}) }}" alt="Brand Logo" loading="lazy" class="product-card__brand" alt="{{ product.brand.logo.originalName }}" title="{{ product.brand.logo.originalName }}">
  15.       {% endif %}
  16.       {% if product.showCountdown %}
  17.         <div class="product-card__countdown {{ product.isFinished ? '' : 'countdownTimer' }}" data-end-offer-string="{{ product.endOfferDate|date("Y-m-d\\TH:i:sP") }}">
  18.           <svg viewBox="0 0 10 14" fill="none" xmlns="http://www.w3.org/2000/svg">
  19.             <path d="M7.64248 0.158447H0.09729V1.06574H1.20107V3.40935C1.19938 4.06804 1.37552 4.7148 1.71082 5.28172C2.04623 5.84852 2.52822 6.3144 3.10635 6.6301C2.52825 6.94577 2.04623 7.41164 1.71082 7.97848C1.37552 8.54539 1.19939 9.19215 1.20107 9.85084V12.1945H0.09729V13.1017H9.59303V12.1945H8.54968V9.85084C8.55137 9.19215 8.37523 8.54539 8.03993 7.97848C7.70463 7.41167 7.22253 6.94579 6.64452 6.6301C7.2225 6.31443 7.70463 5.84855 8.03993 5.28172C8.37523 4.7148 8.55136 4.06804 8.54968 3.40935V1.06574H9.59303V0.158447H7.64248ZM7.64248 9.85076V12.1944H7.4156L5.17778 9.66923C5.09446 9.5723 4.97295 9.51651 4.84513 9.51651C4.7173 9.51651 4.59579 9.5723 4.51247 9.66923L2.27465 12.1944H2.10832V9.85076C2.10832 8.86217 2.63568 7.94867 3.4918 7.45441C4.34792 6.96005 5.40275 6.96005 6.25887 7.45441C7.115 7.94867 7.64246 8.86217 7.64246 9.85076H7.64248ZM7.64248 2.78943H2.10833V1.06568H7.64248V2.78943Z" fill="currentColor"/>
  20.           </svg>
  21.           00h : 00m : 00s
  22.         </div>
  23. {#
  24.         <button data-modal="countdownProduct"  id="info-icon" class="cursor-pointer border-2 border-primary-500 text-primary-500 rounded-full w-6 h-6 flex items-center justify-center cursor-pointer">
  25.             ?
  26.         </button>
  27. #}
  28.       {% endif %}
  29.     </div>
  30.   </header>
  31.   <section class="product-card__info flex-grow flex flex-col">
  32.     <div class="flex justify-between items-center w-full">
  33.       <div class="w-full">
  34.         <h2 class="product-card__title  text-center w-full tablet:mb-0.5">
  35.           <a href="{{ path('app_product_show', {'slug': product.slug}) }}" title="{{ product.name }}" class="w-full whitespace-nowrap inline-block text-ellipsis">
  36.             {{ product.name }}
  37.           </a>
  38.         </h2>
  39.         {% if app.user or (app.user is null and product.isShowPrice) %}
  40.           <div class="grid grid-cols-12 tablet:grid-cols-12  mobile:grid-cols-12 mr-2">
  41.             <div class=" text-center sm:text-right col-span-12 sm:col-span-7 sm:empty:col-span-12 sm:flex sm:items-center sm:justify-end">
  42.                 {%if product.individualPrice != product.nextPrice%}
  43.                     <div class="sm:flex sm:items-center sm:justify-end">
  44.                         <span class="text-sm tablet:text-base line-through inline-flex leading-none">
  45.                         {#
  46.                         {{ productMacros.priceWithDecimals(product.originalPrice / product.unitsPerBox, '€', 'text-xs leading-none tablet:text-xs tablet:leading-5') }} 
  47.                         #}
  48.                         {{ productMacros.priceWithDecimals(product.individualPrice, '€', 'text-xs leading-none tablet:text-xs tablet:leading-5') }} 
  49.                         </span>
  50.                         <div class="text-sm tablet:text-base text-primary font-bold inline-block leading-none sm:ml-2">
  51.                             <span class="inline-flex">{{ productMacros.priceWithDecimals(product.nextPrice, '€', 'text-xs leading-none tablet:text-xs tablet:leading-5') }}</span>/ <span>{{"product.ud" | trans}}</span>
  52.                         </div>
  53.                     </div>
  54.                 {%else%}
  55.                     <div class="sm:flex sm:items-center sm:justify-end">
  56.                         {%if product.originalPrice > product.individualPrice%}
  57.                             <span class="text-sm tablet:text-base line-through inline-flex leading-none">
  58.                             {{ productMacros.priceWithDecimals(product.originalPrice, '€', 'text-xs leading-none tablet:text-xs tablet:leading-5') }} 
  59.                             </span>
  60.                             <div class="text-sm tablet:text-base text-primary font-bold inline-block leading-none sm:ml-2">
  61.                                 <span class="inline-flex">{{ productMacros.priceWithDecimals(product.nextPrice, '€', 'text-xs leading-none tablet:text-xs tablet:leading-5') }}</span>/ <span>{{"product.ud" | trans}}</span>
  62.                             </div>
  63.                         {%else%}   
  64.                             <span class="text-sm tablet:text-base inline-flex leading-none">
  65.                             {{ productMacros.priceWithDecimals(product.originalPrice , '€', 'text-xs leading-none tablet:text-xs tablet:leading-5') }}
  66.                             </span><span> / {{"product.ud" | trans}}</span>
  67.                         {%endif%}
  68.                     </div>
  69.                 {%endif%}
  70.             </div>
  71.             <div class="text-right col-span-12 sm:col-span-5">
  72.             {% if app.user %}
  73.                 {% if groupsProducts is defined and groupsProducts[product.id] is defined %}
  74.                     <div class="relative bottom-0 left-0 flex items-center justify-end product-card__avatars">
  75.                         <div class="flex items-center ml-auto product-card__avatars__people popupGroups hover:cursor-pointer" data-entity-id="{{product.id}}" >
  76.                             {% for group in groupsProducts[product.id].groups | slice(0, 5) %}
  77.                                 {% if group.buyingGroup is not null %}
  78.                                     {% if group.buyingGroup.image %}
  79.                                         <span title="{{group.buyingGroup.name}}" alt="{{group.buyingGroup.name}}">{{ avatar.create( path('app_media_thumbnail_display', {'id': group.buyingGroup.image.id}), group.buyingGroup.name, 'md') }}</span>
  80.                                     {% else %}
  81.                                         {{ avatar.create(asset('build/images/group_placeholder.webp'), product.name, 'lg') }}
  82.                                     {% endif %}
  83.                                 {% endif %}
  84.                             {% endfor %}
  85.                         </div>
  86.                         <input type="hidden" class="group-data" data-product-id="{{ product.id }}" value="
  87.                             {% for group in groupsProducts[product.id].groups %}
  88.                                 {% if group.buyingGroup is not null %}
  89.                                     {{ group.buyingGroup.name }}|{{ group.buyingGroup.image ? path('app_media_thumbnail_display', {'id': group.buyingGroup.image.id}) : asset('build/images/group_placeholder.webp') }},
  90.                                 {% endif %}
  91.                             {% endfor %}
  92.                         ">
  93.                     </div>
  94.                 {%else%}
  95.                     <div class="relative bottom-0 left-0 flex items-center justify-end product-card__avatars">
  96.                         <div class="flex items-center ml-auto product-card__avatars__people" >
  97.                             <span title="" alt="" class="avatar-placeholder flex items-center justify-center rounded-full bg-transparent  w-10 h-10">
  98.                                 
  99.                             </span>
  100.                         </div>
  101.                     </div>
  102.                 {% endif %}
  103.             {%else%}
  104.                 <div class="relative bottom-0 left-0 flex items-center justify-end product-card__avatars">
  105.                     <div class="flex items-center ml-auto product-card__avatars__people" >
  106.                         <span title="" alt="" class="avatar-placeholder flex items-center justify-center rounded-full bg-transparent  w-10 h-10">
  107.                             
  108.                         </span>
  109.                     </div>
  110.                 </div>
  111.             {% endif %}
  112.             </div>
  113.            </div>
  114.         {%else%}
  115.             <div class="relative bottom-0 left-0 flex items-center justify-end product-card__avatars">
  116.                 <div class="flex items-center ml-auto product-card__avatars__people" >
  117.                     <span title="" alt="" class="avatar-placeholder flex items-center justify-center rounded-full bg-transparent  w-10 h-10">
  118.                         
  119.                     </span>
  120.                 </div>
  121.             </div>
  122.         {% endif %}
  123.       </div>
  124.         
  125.       <input type="hidden" class="currentPrice_value" value="{{ product.isSellIsEnought}}" />
  126.       <input type="hidden" class="currentPrice_hidden" name="currentPrice" value="{{product.nextPrice|number_format(2, ',', '.')}}" />
  127.     </div>
  128.     <div class="mt-auto">
  129.     {% if app.user %}
  130.       <button data-id="{{ product.id }}" data-modal="confirmProduct" aria-hidden="true" class="hidden"></button>
  131.       <button data-id="{{ product.id }}" data-producer="{{ product.producer.id }}" class="AddToCartAjax disabled:bg-gray-400 group text-white bg-primary-500 hover:bg-primary-400 md:text-base text-xs rounded p-2 sm:p-1 shadow-md transition-colors flex justify-center items-center w-full">
  132.         {{ "shopping_cart.add-to-cart"|trans }}
  133.         <svg class="block group-disabled:hidden ml-2 w-4 h-4 sm:w-5 sm:h-5" viewBox="0 0 32 33" fill="none" xmlns="http://www.w3.org/2000/svg">
  134.           <path d="M4 4.66504H6.66667L7.2 7.33171L4 4.66504ZM9.33333 17.9984H22.6667L28 7.33171H7.2L9.33333 17.9984ZM9.33333 17.9984L7.2 7.33171L9.33333 17.9984ZM9.33333 17.9984L6.27615 21.0556C5.43619 21.8956 6.03108 23.3317 7.21895 23.3317H22.6667L9.33333 17.9984ZM22.6667 23.3317C21.1939 23.3317 20 24.5256 20 25.9984C20 27.4712 21.1939 28.665 22.6667 28.665C24.1395 28.665 25.3333 27.4712 25.3333 25.9984C25.3333 24.5256 24.1395 23.3317 22.6667 23.3317ZM12 25.9984C12 27.4712 10.8061 28.665 9.33333 28.665C7.86057 28.665 6.66667 27.4712 6.66667 25.9984C6.66667 24.5256 7.86057 23.3317 9.33333 23.3317C10.8061 23.3317 12 24.5256 12 25.9984Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
  135.         </svg>
  136.         
  137.         <div role="status" class="ml-2 hidden group-disabled:block">
  138.             <svg aria-hidden="true" class="animate-spin w-4 h-4 sm:w-5 sm:h-5 fill-white text-transparent" viewBox="0 0 100 101" fill="none" xmlns="http://www.w3.org/2000/svg">
  139.                 <path d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z" fill="currentColor"/>
  140.                 <path d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z" fill="currentFill"/>
  141.             </svg>
  142.         </div>
  143.       </button>
  144.       {# <a
  145.         href="{{ path('app_product_add_to_shopping_cart', {'id': product.id, 'isIndividual': false}) }}"
  146.         class="group text-white bg-primary-500 hover:bg-primary-400 text-sm sm:text-lg rounded p-2 shadow-md transition-colors flex justify-center items-center"
  147.       >
  148.         {{ "shopping_cart.add-to-cart"|trans }}
  149.         <svg class="ml-2 w-4 h-4 sm:w-5 sm:h-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="m15 11-1 9"/><path d="m19 11-4-7"/><path d="M2 11h20"/><path d="m3.5 11 1.6 7.4a2 2 0 0 0 2 1.6h9.8a2 2 0 0 0 2-1.6l1.7-7.4"/><path d="M4.5 15.5h15"/><path d="m5 11 4-7"/><path d="m9 11 1 9"/></svg>
  150.       </a> #}
  151.       {#
  152.       <button class="group hover:bg-primary-500 rounded p-2 shadow-md transition-colors" data-bs-toggle="modal" data-bs-target="#authOnlyModal">
  153.         <svg class="group-hover:text-white transition-colors" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="m15 11-1 9"/><path d="m19 11-4-7"/><path d="M2 11h20"/><path d="m3.5 11 1.6 7.4a2 2 0 0 0 2 1.6h9.8a2 2 0 0 0 2-1.6l1.7-7.4"/><path d="M4.5 15.5h15"/><path d="m5 11 4-7"/><path d="m9 11 1 9"/></svg>
  154.       </button>
  155.       #}
  156.     {% endif %}
  157. </div>
  158.   </section>
  159. </article>
  160. {# Product Macros #}
  161. {% macro shareButton(product,price) %}
  162.     {% set influencerShared = getInfluencerShared(product) %}
  163.     {% if influencerShared %}
  164.         {{ _self.shareButtonInfluencer(influencerShared) }}
  165.     {% else %}
  166.         {{ _self.shareButtonNormal(product,price) }}
  167.     {% endif %}
  168. {% endmacro %}
  169. {% macro shareButtonInfluencer(influencerShared) %}
  170.     {% set sbTitle = 'general.offer_shared_by_influencer_title'|trans %}
  171.     <button type="button" name="share-popover" class="btn btn--sm btn--white-border" data-bs-toggle="popover"
  172.         data-bs-placement="top" data-bs-container="body" data-bs-html="true" data-bs-sanitize="false" data-bs-content='
  173.     <div class="share-buttons share-buttons-init" data-sb-url="{{ influencerShared|influencer_share_url  }}"
  174.       data-sb-title="{{ sbTitle }}">
  175.       <a class="email"></a>
  176.       <a class="twitter"></a>
  177.       <a class="facebook"></a>
  178.       <a class="whatsapp"></a>
  179.       <a class="telegram"></a>
  180.     </div>
  181.   '>
  182.         <img src="{{ asset('build/images/share.svg') }}" height="15rem" width="15rem" alt="Share">
  183.         <small>{{ "general.share" | trans }}</small>
  184.         <span class="badge rounded-pill bg-primary">{{ influencerShared.totalReferredPoints|format_currency('EUR') }}</span>
  185.     </button>
  186. {% endmacro %}
  187. {% macro shareButtonNormal(product, price) %}
  188.     {% set alreadyBought = get_already_bought(product) %}
  189.     {% if alreadyBought %}
  190.         {% set sbTitle = 'general.offerpurchasedbyuser'|trans %}
  191.     {% else %}
  192.         {% set sbTitle = 'general.offer_found_by_user'|trans %}
  193.     {% endif %}
  194.     <button type="button" name="share-popover" class="product-card__share-btn btn btn--md btn--white-border" data-bs-toggle="popover"
  195.         data-bs-placement="top" data-bs-container="body" data-bs-html="true" data-bs-sanitize="false" data-bs-content='
  196.                         <div class="share-buttons share-buttons-init" data-sb-url="{{ product|product_share_url  }}"
  197.                             data-sb-title="{{ sbTitle }}">
  198.                             <a class="email"></a>
  199.                             <a class="twitter"></a>
  200.                             <a class="facebook"></a>
  201.                             <a class="whatsapp"></a>
  202.                             <a class="telegram"></a>
  203.                         </div>
  204.                     '>
  205.         <svg width="21" height="21" viewBox="0 0 21 21" fill="none" xmlns="http://www.w3.org/2000/svg">
  206.       <path d="M12.7241 13.6842L13.0769 13.8468L13.3216 13.5451C13.5853 13.2201 13.9177 12.9575 14.2949 12.7763C14.6716 12.5952 15.0838 12.4998 15.5017 12.4968C16.0615 12.4971 16.6087 12.6633 17.0741 12.9743C17.5401 13.2856 17.9032 13.7281 18.1177 14.2459C18.3321 14.7636 18.3882 15.3333 18.2789 15.8829C18.1696 16.4325 17.8997 16.9374 17.5035 17.3336C17.1072 17.7299 16.6024 17.9997 16.0528 18.109C15.5031 18.2183 14.9335 18.1622 14.4157 17.9478C13.898 17.7333 13.4555 17.3702 13.1442 16.9042C12.8334 16.4392 12.6673 15.8926 12.6667 15.3333C12.669 15.1644 12.6857 14.996 12.7166 14.8299L12.7878 14.4471L12.434 14.2843L8.03404 12.2593L7.72147 12.1154L7.47544 12.356C7.07671 12.7458 6.57178 13.0094 6.02393 13.1136C5.47608 13.2178 4.90966 13.158 4.39564 12.9417C3.88163 12.7254 3.44287 12.3622 3.13435 11.8976C2.82583 11.4331 2.66125 10.8878 2.66125 10.3301C2.66125 9.77246 2.82583 9.22719 3.13435 8.76263C3.44287 8.29808 3.88163 7.9349 4.39564 7.7186C4.90966 7.5023 5.47608 7.4425 6.02393 7.54669C6.57178 7.65087 7.07671 7.91442 7.47544 8.3043L7.72147 8.54486L8.03404 8.40101L12.434 6.37601L12.7878 6.2132L12.7166 5.83036C12.6856 5.66364 12.6689 5.49458 12.6666 5.32502C12.6615 4.65757 12.8922 4.00971 13.318 3.49568L12.933 3.17671L13.318 3.49568C13.744 2.98138 14.3381 2.63411 14.9953 2.51516C15.6524 2.39621 16.3305 2.51322 16.9098 2.84556C17.4891 3.17789 17.9324 3.70417 18.1614 4.33152C18.3904 4.95888 18.3905 5.64697 18.1616 6.27437C17.9327 6.90176 17.4895 7.42813 16.9102 7.76056C16.331 8.093 15.653 8.21014 14.9958 8.09131C14.3386 7.97248 13.7445 7.62532 13.3183 7.11109L13.0731 6.8152L12.7241 6.97602L8.47409 8.93436L8.06987 9.12061L8.20804 9.54369C8.37493 10.0547 8.37493 10.6056 8.20804 11.1166L8.06987 11.5397L8.47409 11.7259L12.7241 13.6842ZM16.7037 3.52862C16.3474 3.29054 15.9285 3.16347 15.5 3.16347C14.9254 3.16347 14.3743 3.39174 13.9679 3.79807C13.5616 4.2044 13.3333 4.7555 13.3333 5.33013C13.3333 5.75866 13.4604 6.17756 13.6985 6.53387C13.9366 6.89017 14.2749 7.16788 14.6709 7.33187C15.0668 7.49586 15.5024 7.53877 15.9227 7.45517C16.343 7.37157 16.7291 7.16521 17.0321 6.8622C17.3351 6.55918 17.5414 6.17312 17.625 5.75283C17.7086 5.33254 17.6657 4.89689 17.5017 4.50098C17.3378 4.10508 17.06 3.76669 16.7037 3.52862ZM4.29627 12.1316C4.65257 12.3697 5.07148 12.4968 5.5 12.4968C6.07464 12.4968 6.62574 12.2685 7.03207 11.8622C7.4384 11.4559 7.66667 10.9048 7.66667 10.3301C7.66667 9.90161 7.5396 9.4827 7.30152 9.1264C7.06344 8.77009 6.72506 8.49238 6.32915 8.32839C5.93324 8.1644 5.4976 8.1215 5.07731 8.2051C4.65701 8.2887 4.27095 8.49506 3.96794 8.79807C3.66492 9.10108 3.45857 9.48714 3.37497 9.90744C3.29137 10.3277 3.33427 10.7634 3.49826 11.1593C3.66225 11.5552 3.93996 11.8936 4.29627 12.1316ZM14.2963 17.1316C14.6526 17.3697 15.0715 17.4968 15.5 17.4968C16.0746 17.4968 16.6257 17.2685 17.0321 16.8622C17.4384 16.4559 17.6667 15.9048 17.6667 15.3301C17.6667 14.9016 17.5396 14.4827 17.3015 14.1264C17.0634 13.7701 16.7251 13.4924 16.3292 13.3284C15.9332 13.1644 15.4976 13.1215 15.0773 13.2051C14.657 13.2887 14.271 13.4951 13.9679 13.7981C13.6649 14.1011 13.4586 14.4871 13.375 14.9074C13.2914 15.3277 13.3343 15.7634 13.4983 16.1593C13.6623 16.5552 13.94 16.8936 14.2963 17.1316Z" fill="currentColor" stroke="currentColor"/>
  207.     </svg>
  208.         <strong class="font-bold text-primary">{{ price }}</strong>
  209.         {% set coinsIfItIsShared = getCoinsIfItIsShared(product) %}
  210.         {% if coinsIfItIsShared != null and alreadyBought == true %}
  211.             <span class="badge rounded-pill bg-primary">{{ coinsIfItIsShared|format_currency('EUR') }}</span>
  212.         {% endif %}
  213.     </button>
  214. {% endmacro %}