templates/product/show.html.twig line 1

Open in your IDE?
  1. {% extends 'layout/app.html.twig' %}
  2. {% block PAGE_CSS %}
  3. {% endblock %}
  4. {% block CONTENT_MID %}
  5.     <div class="bg-white">
  6.         <div class="pt-4 max-w-7xl mx-auto lg:flex items-center justify-between space-y-2 lg:space-y-0 lg:space-x-2 px-4 sm:px-6 lg:px-8">
  7.             <ol role="list" class="max-w-3xl flex items-center space-x-2">
  8.                 <li>
  9.                     <div class="flex items-center">
  10.                         <a href="{{ navStartNode }}/" class="mr-2 text-sm font-medium text-gray-900">Home</a>
  11.                         <svg width="16" height="20" viewBox="0 0 16 20" fill="currentColor" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" class="h-5 w-4 text-gray-300">
  12.                             <path d="M5.697 4.34L8.98 16.532h1.327L7.025 4.341H5.697z" />
  13.                         </svg>
  14.                     </div>
  15.                 </li>
  16.                 <li>
  17.                     <div class="flex items-center">
  18.                         <a href="{{ navStartNode }}/" class="mr-2 text-sm font-medium text-gray-900">{{ 'Produkte' | trans }}</a>
  19.                         <svg width="16" height="20" viewBox="0 0 16 20" fill="currentColor" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" class="h-5 w-4 text-gray-300">
  20.                             <path d="M5.697 4.34L8.98 16.532h1.327L7.025 4.341H5.697z" />
  21.                         </svg>
  22.                     </div>
  23.                 </li>
  24.                 <li class="text-sm">
  25.                     <a href="{{ product.slug is defined ? product.slug : '#' }}" aria-current="page" class="font-medium text-brand-600 hover:text-gray-600">{{ product.name is defined ? product.name : '' }}</a>
  26.                 </li>
  27.             </ol>
  28.         </div>
  29.         <div class="mx-auto max-w-2xl pb-16 px-4 sm:pb-24 sm:px-6 lg:max-w-7xl lg:px-8 pt-4 space-y-8">
  30.             <div class="lg:grid lg:grid-cols-2 lg:items-start lg:gap-x-8">
  31.                 <!-- Image gallery -->
  32.                 <div class="flex flex-1 flex-col" x-data="{ showTab: 1 }">
  33.                     <!-- Image selector -->
  34.                     <div class="aspect-w-1 aspect-h-1 w-full bg-gray-100 rounded-lg">
  35.                         <!-- Tab panel, show/hide based on tab state. -->
  36.                         <div x-cloak x-show="showTab === 1" class="flex justify-center items-center" id="tabs-1-panel-1" aria-labelledby="tabs-1-tab-1" role="tabpanel" tabindex="0">
  37.                             {{ (product.mainImage is not empty ? product.mainImage.thumbnail('productThumbnail').html : pimcore_asset_by_path('/System/missing.png').thumbnail('productThumbnail').html ) | raw }}
  38.                             {% if product.discontinued %}
  39.                                 <span class="absolute top-2 right-2 bg-brand-600 text-center text-white text-xs rounded-full px-2 py-1">Auslaufartikel</span>
  40.                             {% endif %}
  41.                         </div>
  42.                         {% for key, otherImage in product.otherImages %}
  43.                             <div x-cloak x-show="showTab === {{ key+2 }}" class="flex justify-center items-center" id="tabs-1-panel-{{ key+2 }}" aria-labelledby="tabs-1-tab-{{ key+2 }}" role="tabpanel" tabindex="0">
  44.                                 {{ otherImage.thumbnail('productThumbnail').html | raw }}
  45.                                 {% if product.discontinued %}
  46.                                     <span class="absolute top-2 right-2 bg-brand-600 text-center text-white text-xs rounded-full px-2 py-1">Auslaufartikel</span>
  47.                                 {% endif %}
  48.                             </div>
  49.                         {% endfor %}
  50.                         {% for key, detailImage in product.detailView %}
  51.                             <div x-cloak x-show="showTab === {{ key+50 }}" class="flex justify-center items-center" id="tabs-1-panel-{{ key+50 }}" aria-labelledby="tabs-1-tab-{{ key+50 }}" role="tabpanel" tabindex="0">
  52.                                 {{ detailImage.thumbnail('productThumbnail').html | raw }}
  53.                                 {% if product.discontinued %}
  54.                                     <span class="absolute top-2 right-2 bg-brand-600 text-center text-white text-xs rounded-full px-2 py-1">Auslaufartikel</span>
  55.                                 {% endif %}
  56.                             </div>
  57.                         {% endfor %}
  58.                     </div>
  59.                     <div class="mx-auto mt-6 w-full max-w-2xl lg:max-w-none relative"
  60.                          x-data="{start: true, end: false}">
  61.                         <div class="grid auto-cols-[25%] grid-flow-col gap-6 overflow-x-auto py-2"
  62.                              x-ref="slider" x-on:scroll.debounce="$refs.slider.scrollLeft == 0 ? start = true : start = false; Math.abs(($refs.slider.scrollWidth - $refs.slider.offsetWidth) - $refs.slider.scrollLeft) < 5 ? end = true : end = false;"
  63.                              aria-orientation="horizontal" role="tablist">
  64.                             <button x-on:click="showTab = 1" class="relative flex items-center justify-center h-32 bg-gray-100 hover:bg-gray-50 border-2 focus:outline-none rounded-md cursor-pointer select-none transition ease duration-300" :class="{'border-brand-500': showTab === 1, 'border-transparent': showTab !== 1}" aria-controls="tabs-1-panel-1" role="tab" type="button">
  65.                                 <span class="sr-only">Main Product Image</span>
  66.                                 <span class="absolute flex inset-0 overflow-hidden rounded-md">
  67.                                         {{ (product.mainImage is not empty ? product.mainImage.thumbnail('productThumbnail').html : pimcore_asset_by_path('/System/missing.png').thumbnail('productThumbnail').html ) | raw }}
  68.                                     </span>
  69.                             </button>
  70.                             {% for key, otherImage in product.otherImages %}
  71.                                 <button x-on:click="showTab = {{ key+2 }}" class="relative flex items-center justify-center h-32 bg-gray-100 hover:bg-gray-50 border-2 focus:outline-none rounded-md cursor-pointer select-none transition ease duration-300" :class="{'border-brand-500': showTab === {{ key+2 }}, 'border-transparent': showTab !== {{ key+2 }}}" aria-controls="tabs-1-panel-{{ key+2 }}" role="tab" type="button">
  72.                                     <span class="sr-only">Additional Product Image</span>
  73.                                     <span class="absolute flex inset-0 overflow-hidden rounded-md">
  74.                                         {{ otherImage.thumbnail('productThumbnail').html | raw }}
  75.                                     </span>
  76.                                 </button>
  77.                             {% endfor %}
  78.                             {% for key, detailImage in product.detailView %}
  79.                                 <button x-on:click="showTab = {{ key+50 }}" class="relative flex items-center justify-center h-32 bg-gray-100 hover:bg-gray-50 border-2 focus:outline-none rounded-md cursor-pointer select-none transition ease duration-300" :class="{'border-brand-500': showTab === {{ key+50 }}, 'border-transparent': showTab !== {{ key+50 }}}" aria-controls="tabs-1-panel-{{ key+50 }}" role="tab" type="button">
  80.                                     <span class="sr-only">Additional Product Image</span>
  81.                                     <span class="absolute flex inset-0 overflow-hidden rounded-md">
  82.                                         {{ detailImage.thumbnail('productThumbnail').html | raw }}
  83.                                     </span>
  84.                                 </button>
  85.                             {% endfor %}
  86.                         </div>
  87.                         {% if(1 + (product.otherImages|length) + (product.detailView|length) >= 4) %}
  88.                         <button class="absolute top-14 left-[-20px]" x-on:click="$refs.slider.scrollBy({left: $refs.slider.offsetWidth * -1, behavior: 'smooth'});" x-bind:class="start ? '' : 'slider__nav__button--active'">
  89.                             <span class="hidden sm:inline-flex justify-center items-center rounded-full w-10 h-10 bg-gray-100 group-hover:bg-brand/50 group-focus:ring-4 group-focus:ring-white group-focus:outline-none">
  90.                                 <svg class="w-5 h-5 text-brand sm:w-6 sm:h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path></svg>
  91.                                 <span class="hidden">Previous</span>
  92.                             </span>
  93.                         </button>
  94.                         <button class="absolute top-14 right-[-20px]" x-on:click="$refs.slider.scrollBy({left: $refs.slider.offsetWidth, behavior: 'smooth'});" x-bind:class="end ? '' : 'slider__nav__button--active'">
  95.                             <span class="hidden sm:inline-flex justify-center items-center rounded-full w-10 h-10 bg-gray-100 group-hover:bg-brand/50 group-focus:ring-4 group-focus:ring-white group-focus:outline-none">
  96.                                 <svg class="w-5 h-5 sm:w-6 sm:h-6 text-brand" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path></svg>
  97.                                 <span class="hidden">Next</span>
  98.                             </span>
  99.                         </button>
  100.                         {% endif %}
  101.                     </div>
  102.                 </div>
  103.                 <!-- Product info -->
  104.                 <div class="mt-10 px-4 sm:mt-16 sm:px-0 lg:mt-0 space-y-6">
  105.                     <h1 class="text-3xl font-bold text-gray-900 tracking-tight">{{ product.name is defined ? product.name : '' }}</h1>
  106.                     {% if product.brandImage is not empty %}
  107.                         <img class="float-right max-h-16" src="{{ product.brandImage.thumbnail({'width': 128}).path }}">
  108.                     {% endif %}
  109.                     <div class="space-y-3">
  110.                         {% if product.manufacturer is not empty %}
  111.                         <div>
  112.                             <div class="flex items-center space-x-1.5 text-sm">
  113.                                 <p>{{ 'manufacturer'|trans }}:</p>
  114.                                 <p class="font-semibold">{{ product.manufacturer }}</p>
  115.                             </div>
  116.                         </div>
  117.                         {% endif %}
  118.                         <div class="grid grid-cols-1 md:grid-cols-2 gap-y-2 md:gap-x-6 text-sm">
  119.                             {% if product.group is not empty %}
  120.                             <div class="flex items-center space-x-1.5">
  121.                                 <p>{{ 'product group' | trans }}:</p>
  122.                                 <div class="flex" style="max-width: 9rem">
  123.                                     <span class="text-white text-sm rounded-r-full pl-4 pr-8 py-1 w-fit" style="background-color: {{ product.group.color | slice(0,7) }};">{{ product.group.name }}</span>
  124.                                 </div>
  125.                             </div>
  126.                             {% endif %}
  127.                             {% if product.code is not empty %}
  128.                             <div class="flex items-center space-x-1.5">
  129.                                 <p>{{ 'general.filter.code' | trans }}:</p>
  130.                                 <p class="font-semibold">{{ product.code }}</p>
  131.                             </div>
  132.                             {% endif %}
  133.                             {% if product.availableColors is not empty %}
  134.                             <div class="flex items-center space-x-1.5">
  135.                                 <p>{{ 'color' | trans }}:</p>
  136.                                 <p class="font-semibold">{{ product.availableColors|map(feature => feature)|join(', ') | raw }}</p>
  137.                             </div>
  138.                             {% endif %}
  139.                         </div>
  140.                     </div>
  141.                     {% if product.normPictograms|length > 0 %}
  142.                         <div>
  143.                             <div class="grid lg:grid-cols-4 grid-cols-2 gap-4">
  144.                                 {% for pictogram in product.normPictograms %}
  145.                                     <div class="flex flex-col items-center">
  146.                                         <img width="48" src="{{ pictogram.pictogram.thumbnail('icon-64x64').path }}">
  147.                                         <span class="text-xs text-gray-500 text-center font-bold">{{ pictogram.normName|raw }}</span>
  148.                                         <span class="text-xs text-gray-500 text-center">{{ pictogram.additionalInfo }}</span>
  149.                                     </div>
  150.                                 {% endfor %}
  151.                             </div>
  152.                             <p class="text-gray-500 text-sm mt-1">Weitere Informationen finden Sie <a class="text-brand" href="https://hugo-josten.de/service/wissenswertes/359-normenuebersicht">hier</a></p>
  153.                         </div>
  154.                     {% endif %}
  155.                     <div class="space-y-1">
  156.                         <h2 class="text-lg font-semibold text-gray-900">{{ 'description' | trans }}</h2>
  157.                         <div class="prose prose-base text-gray-500">
  158.                             <p class="leading-6">
  159.                                 {{ product.shortDescription | raw }}
  160.                             </p>
  161.                         </div>
  162.                     </div>
  163.                 </div>
  164.             </div>
  165.             <div class="grid grid-cols-1 lg:grid-cols-2 gap-12">
  166.                 <div class="space-y-6">
  167.                     <dl class="p-6 bg-gray-50 rounded-lg space-y-4">
  168.                         <h2 class="text-lg font-semibold text-gray-900">{{ 'description' | trans }}</h2>
  169.                         <div class="space-y-2 text-sm">
  170.                             {% for property in [
  171.                                 "manufacturer",
  172.                                 "group",
  173.                                 "code",
  174.                                 "availableColorsWithCode",
  175.                                 "clothingType",
  176.                                 "sizeRange",
  177.                                 "specialities",
  178.                                 "ceMark",
  179.                                 "norms",
  180.                                 "procedureEN_ISO",
  181.                                 "codeEN_ISO",
  182.                                 "typeEN_ISO",
  183.                                 "safetyClassEN_ISO",
  184.                                 "discontinued",
  185.                             ] %}
  186.                                 {% if product[property]|length > 0 %}
  187.                                     <div class="grid grid-cols-2 gap-4">
  188.                                         <dt class="font-semibold">{{ ('general.filter.' ~ property) | trans }}</dt>
  189.                                         {% if property == "group" %}
  190.                                             <dd class="mt-1 sm:mt-0">{{ product.group.name }}</dd>
  191.                                         {% elseif product[property] is iterable %}
  192.                                             <dd class="mt-1 sm:mt-0">{{ product[property]|map(feature => feature)|join('<br>') | raw }}</dd>
  193.                                         {% else %}
  194.                                             <dd class="mt-1 sm:mt-0">{{ product[property] }}</dd>
  195.                                         {% endif %}
  196.                                     </div>
  197.                                 {% endif %}
  198.                             {% endfor %}
  199.                         </div>
  200.                     </dl>
  201.                     {% if product.productMaterial %}
  202.                     <dl class="p-6 bg-gray-50 rounded-lg space-y-4">
  203.                         <h2 class="text-lg font-semibold text-gray-900">{{ 'Material' | trans }}</h2>
  204.                         <div class="space-y-2 text-sm">
  205.                             {% for property in [
  206.                                 "strength",
  207.                                 "fabricQuality",
  208.                                 "cotton",
  209.                                 "polyester",
  210.                                 "polyamid",
  211.                                 "polyacryl",
  212.                                 "elasthan",
  213.                                 "guidelines",
  214.                                 "protex",
  215.                                 "bio_cotton",
  216.                                 "cotton_carbon",
  217.                                 "pan",
  218.                                 "recycled_polyester",
  219.                                 "carbon",
  220.                             ] %}
  221.                                 {% if product.productMaterial[property]|length > 0 and product.productMaterial[property] > 0 %}
  222.                                     <div class="grid grid-cols-2 gap-4">
  223.                                         <dt class="font-semibold">{{ ('general.filter.' ~ property) | trans }}</dt>
  224.                                         {% if product.productMaterial[property] is iterable %}
  225.                                             <dd class="mt-1 sm:mt-0">{{ product.productMaterial[property]|map(feature => feature)|join('<br>') | raw }}</dd>
  226.                                         {% else %}
  227.                                             <dd class="mt-1 sm:mt-0">{{ product.productMaterial[property] }}</dd>
  228.                                         {% endif %}
  229.                                     </div>
  230.                                 {% endif %}
  231.                             {% endfor %}
  232.                         </div>
  233.                     </dl>
  234.                     {% endif %}
  235.                 </div>
  236.                 <div class="space-y-6">
  237.                     {% if product.productDatasheet|length > 0 or
  238.                         product.mainImage|length > 0 or
  239.                         product.otherImages|length > 0 or
  240.                         product.detailView|length > 0 %}
  241.                     <div class="p-6 bg-gray-50 rounded-lg space-y-4">
  242.                         <h2 class="text-lg font-semibold text-gray-900">{{ 'download media' | lower | trans }}</h2>
  243.                         {% if product.productDatasheet|length > 0 %}
  244.                             <div class="space-y-1">
  245.                                 <p class="text-sm font-semibold">{{ 'productdatasheet' | lower | trans }}:</p>
  246.                                 <ul role="list" class="divide-y divide-gray-200 rounded-md border border-gray-200">
  247.                                     <li class="flex items-center justify-between py-3 pl-3 pr-4 text-sm">
  248.                                         <div class="flex w-0 flex-1 items-center">
  249.                                             <!-- Heroicon name: mini/paper-clip -->
  250.                                             <svg class="h-5 w-5 flex-shrink-0 text-gray-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
  251.                                                 <path fill-rule="evenodd" d="M15.621 4.379a3 3 0 00-4.242 0l-7 7a3 3 0 004.241 4.243h.001l.497-.5a.75.75 0 011.064 1.057l-.498.501-.002.002a4.5 4.5 0 01-6.364-6.364l7-7a4.5 4.5 0 016.368 6.36l-3.455 3.553A2.625 2.625 0 119.52 9.52l3.45-3.451a.75.75 0 111.061 1.06l-3.45 3.451a1.125 1.125 0 001.587 1.595l3.454-3.553a3 3 0 000-4.242z" clip-rule="evenodd" />
  252.                                             </svg>
  253.                                             <span class="ml-2 w-0 flex-1 truncate">{{ product.productDatasheet.filename }}</span>
  254.                                         </div>
  255.                                         <div class="ml-4 flex-shrink-0">
  256.                                             <a href="{{ product.productDatasheet.fullpath }}" target="_blank" class="font-medium text-brand-600 hover:text-brand-500">Download</a>
  257.                                         </div>
  258.                                     </li>
  259.                                 </ul>
  260.                             </div>
  261.                         {% endif %}
  262.                         {% if product.sizeTable|length > 0 %}
  263.                             <div class="space-y-1">
  264.                                 <p class="text-sm font-semibold">{{ 'Größentabelle' | trans }}:</p>
  265.                                 <ul role="list" class="divide-y divide-gray-200 rounded-md border border-gray-200">
  266.                                     <li class="flex items-center justify-between py-3 pl-3 pr-4 text-sm">
  267.                                         <div class="flex w-0 flex-1 items-center">
  268.                                             <!-- Heroicon name: mini/paper-clip -->
  269.                                             <svg class="h-5 w-5 flex-shrink-0 text-gray-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
  270.                                                 <path fill-rule="evenodd" d="M15.621 4.379a3 3 0 00-4.242 0l-7 7a3 3 0 004.241 4.243h.001l.497-.5a.75.75 0 011.064 1.057l-.498.501-.002.002a4.5 4.5 0 01-6.364-6.364l7-7a4.5 4.5 0 016.368 6.36l-3.455 3.553A2.625 2.625 0 119.52 9.52l3.45-3.451a.75.75 0 111.061 1.06l-3.45 3.451a1.125 1.125 0 001.587 1.595l3.454-3.553a3 3 0 000-4.242z" clip-rule="evenodd" />
  271.                                             </svg>
  272.                                             <span class="ml-2 w-0 flex-1 truncate">{{ product.sizeTable.filename }}</span>
  273.                                         </div>
  274.                                         <div class="ml-4 flex-shrink-0">
  275.                                             <a href="{{ product.sizeTable.fullpath }}" target="_blank" class="font-medium text-brand-600 hover:text-brand-500">Download</a>
  276.                                         </div>
  277.                                     </li>
  278.                                 </ul>
  279.                             </div>
  280.                         {% endif %}
  281.                         {% if product.mainImage|length > 0 or
  282.                             product.otherImages|length > 0 or
  283.                             product.detailView|length > 0
  284.                         %}
  285.                             <div class="space-y-1">
  286.                                 <p class="text-sm font-semibold">{{ 'productImages' | lower | trans }}:</p>
  287.                                 <ul role="list" class="divide-y divide-gray-200 rounded-md border border-gray-200">
  288.                                     <li class="flex items-center justify-between py-3 pl-3 pr-4 text-sm relative group">
  289.                                         <div class="flex w-0 flex-1 items-center">
  290.                                             <!-- Heroicon name: mini/paper-clip -->
  291.                                             <svg class="h-5 w-5 flex-shrink-0 text-gray-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
  292.                                                 <path fill-rule="evenodd" d="M15.621 4.379a3 3 0 00-4.242 0l-7 7a3 3 0 004.241 4.243h.001l.497-.5a.75.75 0 011.064 1.057l-.498.501-.002.002a4.5 4.5 0 01-6.364-6.364l7-7a4.5 4.5 0 016.368 6.36l-3.455 3.553A2.625 2.625 0 119.52 9.52l3.45-3.451a.75.75 0 111.061 1.06l-3.45 3.451a1.125 1.125 0 001.587 1.595l3.454-3.553a3 3 0 000-4.242z" clip-rule="evenodd" />
  293.                                             </svg>
  294.                                             <span class="ml-2 w-0 flex-1 truncate">{{ basename(product.mainImage.thumbnail('high-1920px').path)|replace({'%20': '_', ' ': '_'}) }}</span>
  295.                                         </div>
  296.                                         <div class="absolute w-64 h-64 bg-gray-100 p-6 shadow-lg left-[calc(-16rem-20px)] rounded-md hidden group-hover:block">
  297.                                             {{ product.mainImage.thumbnail('productThumbnail').html|raw }}
  298.                                             <svg class="absolute text-gray-100 h-8 right-0 mr-[-33px] top-[calc(50%-19px)]" x="0px" y="0px" viewBox="0 0 255 255" xml:space="preserve">
  299.                                                 <polygon style="fill: currentColor;" points="0,0 127.5,127.5 0,255"/>
  300.                                             </svg>
  301.                                         </div>
  302.                                         <div class="ml-4 flex-shrink-0">
  303.                                             <a href="{{ product.mainImage.thumbnail('high-1920px').path }}" download="{{ basename(product.mainImage.thumbnail('high-1920px').path)|replace({'%20': '_', ' ': '_'}) }}" target="_blank" class="font-medium text-brand-600 hover:text-brand-500">Download</a>
  304.                                         </div>
  305.                                     </li>
  306.                                     {% for otherImage in product.otherImages %}
  307.                                         <li class="flex items-center justify-between py-3 pl-3 pr-4 text-sm relative group">
  308.                                             <div class="flex w-0 flex-1 items-center">
  309.                                                 <!-- Heroicon name: mini/paper-clip -->
  310.                                                 <svg class="h-5 w-5 flex-shrink-0 text-gray-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
  311.                                                     <path fill-rule="evenodd" d="M15.621 4.379a3 3 0 00-4.242 0l-7 7a3 3 0 004.241 4.243h.001l.497-.5a.75.75 0 011.064 1.057l-.498.501-.002.002a4.5 4.5 0 01-6.364-6.364l7-7a4.5 4.5 0 016.368 6.36l-3.455 3.553A2.625 2.625 0 119.52 9.52l3.45-3.451a.75.75 0 111.061 1.06l-3.45 3.451a1.125 1.125 0 001.587 1.595l3.454-3.553a3 3 0 000-4.242z" clip-rule="evenodd" />
  312.                                                 </svg>
  313.                                                 <span class="ml-2 w-0 flex-1 truncate">{{ basename(otherImage.thumbnail('high-1920px').path)|replace({'%20': '_', ' ': '_'}) }}</span>
  314.                                             </div>
  315.                                             <div class="absolute w-64 h-64 bg-gray-100 p-6 shadow-lg left-[calc(-16rem-20px)] rounded-md hidden group-hover:block">
  316.                                                 {{ otherImage.thumbnail('productThumbnail').html|raw }}
  317.                                                     <svg class="absolute text-gray-100 h-8 right-0 mr-[-33px] top-[calc(50%-19px)]" x="0px" y="0px" viewBox="0 0 255 255" xml:space="preserve">
  318.                                                     <polygon style="fill: currentColor;" points="0,0 127.5,127.5 0,255"/>
  319.                                                 </svg>
  320.                                             </div>
  321.                                             <div class="ml-4 flex-shrink-0">
  322.                                                 <a href="{{ otherImage.thumbnail('high-1920px').path }}" download="{{ basename(otherImage.thumbnail('high-1920px').path)|replace({'%20': '_', ' ': '_'}) }}" target="_blank" class="font-medium text-brand-600 hover:text-brand-500">Download</a>
  323.                                             </div>
  324.                                         </li>
  325.                                     {% endfor %}
  326.                                     {% for detailImage in product.detailView %}
  327.                                         <li class="flex items-center justify-between py-3 pl-3 pr-4 text-sm relative group">
  328.                                             <div class="flex w-0 flex-1 items-center">
  329.                                                 <!-- Heroicon name: mini/paper-clip -->
  330.                                                 <svg class="h-5 w-5 flex-shrink-0 text-gray-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
  331.                                                     <path fill-rule="evenodd" d="M15.621 4.379a3 3 0 00-4.242 0l-7 7a3 3 0 004.241 4.243h.001l.497-.5a.75.75 0 011.064 1.057l-.498.501-.002.002a4.5 4.5 0 01-6.364-6.364l7-7a4.5 4.5 0 016.368 6.36l-3.455 3.553A2.625 2.625 0 119.52 9.52l3.45-3.451a.75.75 0 111.061 1.06l-3.45 3.451a1.125 1.125 0 001.587 1.595l3.454-3.553a3 3 0 000-4.242z" clip-rule="evenodd" />
  332.                                                 </svg>
  333.                                                 <span class="ml-2 w-0 flex-1 truncate">{{ basename(detailImage.thumbnail('high-1920px').path)|replace({'%20': '_', ' ': '_'}) }}</span>
  334.                                             </div>
  335.                                             <div class="absolute w-64 h-64 bg-gray-100 p-6 shadow-lg left-[calc(-16rem-20px)] rounded-md hidden group-hover:block">
  336.                                                 {{ detailImage.thumbnail('productThumbnail').html|raw }}
  337.                                                 <svg class="absolute text-gray-100 h-8 right-0 mr-[-33px] top-[calc(50%-19px)]" x="0px" y="0px" viewBox="0 0 255 255" xml:space="preserve">
  338.                                                     <polygon style="fill: currentColor;" points="0,0 127.5,127.5 0,255"/>
  339.                                                 </svg>
  340.                                             </div>
  341.                                             <div class="ml-4 flex-shrink-0">
  342.                                                 <a href="{{ detailImage.thumbnail('high-1920px').path }}" download="{{ basename(detailImage.thumbnail('high-1920px').path)|replace({'%20': '_', ' ': '_'}) }}" target="_blank" class="font-medium text-brand-600 hover:text-brand-500">Download</a>
  343.                                             </div>
  344.                                         </li>
  345.                                     {% endfor %}
  346.                                 </ul>
  347.                             </div>
  348.                         {% endif %}
  349.                         {% if product.applicationImages|length > 0 %}
  350.                             <div class="space-y-1">
  351.                                 <p class="text-sm font-semibold">{{ 'applicationImages' | lower | trans }}:</p>
  352.                                 <ul role="list" class="divide-y divide-gray-200 rounded-md border border-gray-200">
  353.                                     {% for applicationImage in product.applicationImages %}
  354.                                         <li class="flex items-center justify-between py-3 pl-3 pr-4 text-sm relative group">
  355.                                             <div class="flex w-0 flex-1 items-center">
  356.                                                 <!-- Heroicon name: mini/paper-clip -->
  357.                                                 <svg class="h-5 w-5 flex-shrink-0 text-gray-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
  358.                                                     <path fill-rule="evenodd" d="M15.621 4.379a3 3 0 00-4.242 0l-7 7a3 3 0 004.241 4.243h.001l.497-.5a.75.75 0 011.064 1.057l-.498.501-.002.002a4.5 4.5 0 01-6.364-6.364l7-7a4.5 4.5 0 016.368 6.36l-3.455 3.553A2.625 2.625 0 119.52 9.52l3.45-3.451a.75.75 0 111.061 1.06l-3.45 3.451a1.125 1.125 0 001.587 1.595l3.454-3.553a3 3 0 000-4.242z" clip-rule="evenodd" />
  359.                                                 </svg>
  360.                                                 <span class="ml-2 w-0 flex-1 truncate">{{ basename(applicationImage.thumbnail('high-1920px').path) }}</span>
  361.                                             </div>
  362.                                             <div class="absolute w-64 h-64 bg-gray-100 p-6 shadow-lg left-[calc(-16rem-20px)] rounded-md hidden group-hover:block">
  363.                                                 {{ applicationImage.thumbnail('productThumbnail').html|raw }}
  364.                                                 <svg class="absolute text-gray-100 h-8 right-0 mr-[-33px] top-[calc(50%-19px)]" x="0px" y="0px" viewBox="0 0 255 255" xml:space="preserve">
  365.                                                     <polygon style="fill: currentColor;" points="0,0 127.5,127.5 0,255"/>
  366.                                                 </svg>
  367.                                             </div>
  368.                                             <div class="ml-4 flex-shrink-0">
  369.                                                 <a href="{{ applicationImage.thumbnail('high-1920px').path }}" download="{{ basename(applicationImage.thumbnail('high-1920px').path) }}" target="_blank" class="font-medium text-brand-600 hover:text-brand-500">Download</a>
  370.                                             </div>
  371.                                         </li>
  372.                                     {% endfor %}
  373.                                 </ul>
  374.                             </div>
  375.                         {% endif %}
  376.                     </div>
  377.                     {% endif %}
  378.                     {% if product.relatedProducts|length > 0 %}
  379.                     <div class="p-6 bg-gray-50 rounded-lg space-y-4">
  380.                         <h2 class="text-lg font-semibold text-gray-900">{{ 'Zugehörige Produkte' | trans }}</h2>
  381.                         <div class="space-y-1">
  382.                             <div class="divide-y divide-gray-200 rounded-md border border-gray-200 text-sm">
  383.                                 {% for relatedProduct in product.relatedProducts %}
  384.                                 <a href="{{ app_product_detaillink(relatedProduct) }}" class="grid grid-cols-2 items-center hover:bg-gray-100 cursor-pointer">
  385.                                     <div>
  386.                                         {{ (relatedProduct.mainImage is not empty ? relatedProduct.mainImage.thumbnail('productThumbnail').html : pimcore_asset_by_path('/System/missing.png').thumbnail('productThumbnail').html ) | raw }}
  387.                                     </div>
  388.                                     <div>
  389.                                         <div class="font-semibold">{{ relatedProduct.name }}</div>
  390.                                         <div class="">{{ relatedProduct.code }}</div>
  391.                                     </div>
  392.                                 </a>
  393.                                 {% endfor %}
  394.                             </div>
  395.                         </div>
  396.                     </div>
  397.                     {% endif %}
  398.                 </div>
  399.             </div>
  400.         </div>
  401.     </div>
  402. {% endblock %}
  403. {% block PAGE_JS %}
  404.     <div id="promo-box" class="bg-brand-600 px-8 py-12 rounded shadow-md fixed top-1/3 right-0 hidden">
  405.         <button id="close-button" class="absolute top-0 right-0 p-2 text-white opacity-100" type="button" aria-label="Close">
  406.             <span aria-hidden="true">&times;</span>
  407.         </button>
  408.         <div class="text-white">
  409.             <span class=" text-xl ">Wir veredeln mit</span><br>
  410.             <span class="text-2xl font-bold">Ihrem Logo!</span><br>
  411.         </div>
  412.         <br>
  413.         <div>
  414.             <a href="https://hugo-josten.de/service/beratung" class="text-white font-bold">
  415.                 Erfahren Sie mehr
  416.             </a>
  417.         </div>
  418.         <div class="h-4"></div>
  419.     </div>
  420.     <div id="promo-icon" class="fixed top-1/3 right-0 p-2 bg-brand-600 text-white rounded-l cursor-pointer hidden">
  421.         <svg class="h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
  422.             <path stroke-linecap="round" stroke-linejoin="round" d="M9.53 16.122a3 3 0 0 0-5.78 1.128 2.25 2.25 0 0 1-2.4 2.245 4.5 4.5 0 0 0 8.4-2.245c0-.399-.078-.78-.22-1.128Zm0 0a15.998 15.998 0 0 0 3.388-1.62m-5.043-.025a15.994 15.994 0 0 1 1.622-3.395m3.42 3.42a15.995 15.995 0 0 0 4.764-4.648l3.876-5.814a1.151 1.151 0 0 0-1.597-1.597L14.146 6.32a15.996 15.996 0 0 0-4.649 4.763m3.42 3.42a6.776 6.776 0 0 0-3.42-3.42" />
  423.         </svg>
  424.     </div>
  425.     <script>
  426.         document.addEventListener('DOMContentLoaded', function() {
  427.             const promoBox = document.getElementById('promo-box');
  428.             const promoIcon = document.getElementById('promo-icon');
  429.             const closeButton = document.getElementById('close-button');
  430.             // Check if the promo box should be hidden
  431.             if (localStorage.getItem('promoBoxClosed') !== 'true') {
  432.                 promoBox.classList.remove('hidden');
  433.             }else{
  434.                 promoIcon.classList.remove('hidden');
  435.             }
  436.             // Add click event to the close button
  437.             closeButton.addEventListener('click', function() {
  438.                 promoBox.classList.add('hidden');
  439.                 promoIcon.classList.remove('hidden');
  440.                 localStorage.setItem('promoBoxClosed', 'true');
  441.             });
  442.             promoIcon.addEventListener('click', function() {
  443.                 promoIcon.classList.add('hidden');
  444.                 promoBox.classList.remove('hidden');
  445.                 localStorage.setItem('promoBoxClosed', 'false');
  446.             });
  447.         });
  448.     </script>
  449. {% endblock %}