Refactor code structure for improved readability and maintainability
This commit is contained in:
486
product.php
486
product.php
@@ -5,10 +5,17 @@ defined(security_key) or exit;
|
||||
// Check to make sure the id parameter is specified in the URL
|
||||
if (isset($_GET['id'])) {
|
||||
|
||||
//GET CATALOG DATA
|
||||
$product = ioAPIv2('/v2/catalog/product_id='.$_GET['id'],'',$clientsecret);
|
||||
$product = json_decode($product,true);
|
||||
$product = $product[0] ?? '';
|
||||
//GET CATALOG DATA FROM CACHE
|
||||
$all_products = $GLOBALS['cached_catalog'];
|
||||
|
||||
// Find the specific product by ID or slug
|
||||
$product = null;
|
||||
foreach ($all_products as $prod) {
|
||||
if ($prod['rowID'] == $_GET['id'] || (isset($prod['url_slug']) && $prod['url_slug'] == $_GET['id'])) {
|
||||
$product = $prod;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the product exists (array is not empty)
|
||||
if (!$product) {
|
||||
@@ -89,42 +96,76 @@ $view .='<p class="content-wrapper error">'.$error.'</p>';
|
||||
}
|
||||
else {
|
||||
$view .='
|
||||
<div class="product content-wrapper">
|
||||
<div class="product-imgs">';
|
||||
if (isset($_GET['option_id']) && !empty($_GET['option_id']) && $_GET['option_id'] !=''){
|
||||
|
||||
$fullPath = null;
|
||||
<div class="product content-wrapper">
|
||||
<div class="product-mobile-header">
|
||||
<div class="breadcrum">
|
||||
<a href="'.$products_link.'">'.$breadcrum_products.'</a> <p>/ '.(${$product['productname']} ?? $product['productname']).'</p>
|
||||
</div>
|
||||
<h1 class="name">'.(${$product['productname']} ?? $product['productname']).'</h1>
|
||||
</div>
|
||||
<div class="product-imgs carousel-container">';
|
||||
// Determine the main image source
|
||||
$mainImageSrc = '';
|
||||
$mainImageAlt = '';
|
||||
|
||||
if (isset($_GET['option_id']) && !empty($_GET['option_id']) && $_GET['option_id'] !=''){
|
||||
foreach ($product['configurations'] as $configuration) {
|
||||
if (isset($configuration['attributes'])) {
|
||||
foreach ($configuration['attributes'] as $attribute) {
|
||||
if ($attribute['attribute_id'] == $_GET['option_id']) {
|
||||
$fullPath = $attribute['alternative_media_full_path'] ?? $attribute['full_path'];
|
||||
$altTitle = $attribute['alternative_media_title'] ?? $attribute['title'];
|
||||
$view .='
|
||||
<div class="product-img-large">
|
||||
<img src="'.img_url.$fullPath.'" id="'.$product['rowID'].'" alt="'.$altTitle.'">
|
||||
</div>';
|
||||
break 2; // Exit all loops once found
|
||||
$mainImageSrc = img_url . ($attribute['alternative_media_full_path'] ?? $attribute['full_path']);
|
||||
$mainImageAlt = $attribute['alternative_media_title'] ?? $attribute['title'];
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} elseif (isset($product['full_path']) && $product['full_path'] != ''){
|
||||
}
|
||||
|
||||
// Fallback to product main image if no option_id or not found
|
||||
if (empty($mainImageSrc) && isset($product['full_path']) && $product['full_path'] != '') {
|
||||
$mainImageSrc = img_url . $product['full_path'];
|
||||
$mainImageAlt = ${$product['productname']} ?? $product['productname'];
|
||||
}
|
||||
|
||||
// Render carousel with arrows if we have an image
|
||||
if (!empty($mainImageSrc)) {
|
||||
$view .='
|
||||
<div class="product-img-large">
|
||||
<img src="'.img_url.$product['full_path'].'" id="'.$product['rowID'].'" alt="'.(${$product['productname']} ?? $product['productname']).'">
|
||||
<div class="product-img-large carousel-main">
|
||||
<button class="carousel-arrow left" aria-label="Previous image">←</button>
|
||||
<img src="'.$mainImageSrc.'" id="'.$product['rowID'].'" alt="'.$mainImageAlt.'">
|
||||
<button class="carousel-arrow right" aria-label="Next image">→</button>
|
||||
</div>';
|
||||
}
|
||||
$view .='
|
||||
<div class="product-small-imgs">';
|
||||
//Show small images
|
||||
foreach ($product_media as $media){
|
||||
|
||||
$view .=' <div class="product-img-small '.($media['position']==1?' selected':'').'">
|
||||
<img src="'.img_url.$media['full_path'].'" width="150" height="150" alt="">
|
||||
</div>';
|
||||
<div class="product-small-imgs carousel-thumbnails">';
|
||||
// Add the main product image as the first thumbnail
|
||||
$thumbs = [];
|
||||
if (isset($_GET['option_id']) && !empty($_GET['option_id']) && $_GET['option_id'] !=''){
|
||||
foreach ($product['configurations'] as $configuration) {
|
||||
if (isset($configuration['attributes'])) {
|
||||
foreach ($configuration['attributes'] as $attribute) {
|
||||
if ($attribute['attribute_id'] == $_GET['option_id']) {
|
||||
$mainPath = $attribute['alternative_media_full_path'] ?? $attribute['full_path'];
|
||||
$mainAltTitle = $attribute['alternative_media_title'] ?? $attribute['title'];
|
||||
$thumbs[] = ['src' => img_url.$mainPath, 'alt' => $mainAltTitle, 'selected' => true];
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} elseif (isset($product['full_path']) && $product['full_path'] != ''){
|
||||
$thumbs[] = ['src' => img_url.$product['full_path'], 'alt' => (${$product['productname']} ?? $product['productname']), 'selected' => true];
|
||||
}
|
||||
foreach ($product_media as $media){
|
||||
$thumbs[] = ['src' => img_url.$media['full_path'], 'alt' => '', 'selected' => false];
|
||||
}
|
||||
foreach ($thumbs as $i => $thumb) {
|
||||
$sel = $thumb['selected'] ? ' selected' : '';
|
||||
$view .= ' <div class="product-img-small'.$sel.'" data-index="'.$i.'">
|
||||
<img src="'.$thumb['src'].'" width="80" height="80" alt="'.$thumb['alt'].'">
|
||||
</div>';
|
||||
}
|
||||
$view .='
|
||||
</div>
|
||||
</div>
|
||||
@@ -178,33 +219,35 @@ $view .='<form id="product-form" action="" method="post">';
|
||||
$output ='';
|
||||
|
||||
foreach ($configuration['attributes'] as $attribute){
|
||||
// Check if this option should be pre-selected
|
||||
$isChecked = (isset($_GET['option_id']) && $_GET['option_id'] == $attribute['attribute_id']) ? ' checked' : '';
|
||||
|
||||
if(isset($attribute['full_path']) && $attribute['full_path'] !=''){
|
||||
|
||||
|
||||
$onclick ='';
|
||||
//ADD updateOption to change pictures when GROUP is IN configuration
|
||||
if(isset($product['config_setting']) && $product['config_setting'] == $configuration['assignment']){
|
||||
|
||||
|
||||
$IMG_large_id = img_url.$attribute['alternative_media_full_path']; //URL TO LARGE IMAGE
|
||||
$onclick = 'onclick="updateOption(\''.$product['rowID'].'\',\''.$IMG_large_id.'\')"';
|
||||
}
|
||||
|
||||
$IMG_small_id = img_url.$attribute['full_path']; //URL TO SMALL IMAGE
|
||||
|
||||
|
||||
$output .= '
|
||||
<label class="picture_select_label">
|
||||
<input id="'.$attribute['attribute_id'].'" class="option radio" value="'.$attribute['attribute_id'].'" name="product[option]['.$configuration['assignment'].'][]" type="radio" data-price="'.($attribute['price'] ?? 0).'" data-rrp="'.($attribute['rrp'] ?? 0).'" data-modifier="'.($attribute['price_modifier'] ?? 1).'" '.(($configuration['group_mandatory'] == 1 ) ? ' required' : '').'>
|
||||
<input id="'.$attribute['attribute_id'].'" class="option radio" value="'.$attribute['attribute_id'].'" name="product[option]['.$configuration['assignment'].'][]" type="radio" data-price="'.($attribute['price'] ?? 0).'" data-rrp="'.($attribute['rrp'] ?? 0).'" data-modifier="'.($attribute['price_modifier'] ?? 1).'" '.(($configuration['group_mandatory'] == 1 ) ? ' required' : '').$isChecked.'>
|
||||
<span class="picture_select"><img '.$onclick.' src="'.$IMG_small_id.'"></span>
|
||||
</label>';
|
||||
</label>';
|
||||
|
||||
} else {
|
||||
$output .= '
|
||||
<label>
|
||||
<input id="'.$attribute['attribute_id'].'>" class="option radio" value="'.$attribute['attribute_id'].'" name="product[option]['.$configuration['assignment'].'][]" type="radio" data-price="'.($attribute['price'] ?? 0).'" data-rrp="'.($attribute['rrp'] ?? 0).'" data-modifier="'.($attribute['price_modifier'] ?? 1).'" '.(($configuration['group_mandatory'] == 1 ) ? ' required' : '').'>'.(${$attribute['item_name']} ?? $attribute['item_name']).'
|
||||
</label>';
|
||||
<input id="'.$attribute['attribute_id'].'>" class="option radio" value="'.$attribute['attribute_id'].'" name="product[option]['.$configuration['assignment'].'][]" type="radio" data-price="'.($attribute['price'] ?? 0).'" data-rrp="'.($attribute['rrp'] ?? 0).'" data-modifier="'.($attribute['price_modifier'] ?? 1).'" '.(($configuration['group_mandatory'] == 1 ) ? ' required' : '').$isChecked.'>'.(${$attribute['item_name']} ?? $attribute['item_name']).'
|
||||
</label>';
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
$view .= '<div class="radio-checkbox">'.$output.'</div>';
|
||||
|
||||
@@ -213,68 +256,75 @@ $view .='<form id="product-form" action="" method="post">';
|
||||
$output ='';
|
||||
|
||||
foreach ($configuration['attributes'] as $attribute){
|
||||
// Check if this option should be pre-selected
|
||||
$isChecked = (isset($_GET['option_id']) && $_GET['option_id'] == $attribute['attribute_id']) ? ' checked' : '';
|
||||
|
||||
if(isset($attribute['full_path']) && $attribute['full_path'] !=''){
|
||||
|
||||
|
||||
$onclick ='';
|
||||
//ADD updateOption to change pictures when GROUP is IN configuration
|
||||
if(isset($product['config_setting']) && $product['config_setting'] == $configuration['assignment']){
|
||||
|
||||
|
||||
$IMG_large_id = img_url.$attribute['alternative_media_full_path']; //URL TO LARGE IMAGE
|
||||
$onclick = 'onclick="updateOption(\''.$product['rowID'].'\',\''.$IMG_large_id.'\')"';
|
||||
}
|
||||
|
||||
$IMG_small_id = img_url.$attribute['full_path']; //URL TO SMALL IMAGE
|
||||
|
||||
|
||||
$output .= '
|
||||
<label class="picture_select_label">
|
||||
<input id="'.$attribute['attribute_id'].'>" class="option checkbox" value="'.$attribute['attribute_id'].'" name="product[option]['.$configuration['assignment'].'][]" type="checkbox" data-price="'.($attribute['price'] ?? 0).'" data-rrp="'.($attribute['rrp'] ?? 0).'" data-modifier="'.($attribute['price_modifier'] ?? 1).'" '.(($configuration['group_mandatory'] == 1 ) ? ' required' : '').'>
|
||||
<input id="'.$attribute['attribute_id'].'>" class="option checkbox" value="'.$attribute['attribute_id'].'" name="product[option]['.$configuration['assignment'].'][]" type="checkbox" data-price="'.($attribute['price'] ?? 0).'" data-rrp="'.($attribute['rrp'] ?? 0).'" data-modifier="'.($attribute['price_modifier'] ?? 1).'" '.(($configuration['group_mandatory'] == 1 ) ? ' required' : '').$isChecked.'>
|
||||
<span class="picture_select"><img '.$onclick.' src="'.$IMG_small_id.'"></span>
|
||||
</label>';
|
||||
</label>';
|
||||
|
||||
} else {
|
||||
$output .= '
|
||||
<label>
|
||||
<input id="'.$attribute['attribute_id'].'>" class="option checkbox" value="'.$attribute['attribute_id'].'" name="product[option]['.$configuration['assignment'].'][]" type="checkbox" data-price="'.($attribute['price'] ?? 0).'" data-rrp="'.($attribute['rrp'] ?? 0).'" data-modifier="'.($attribute['price_modifier'] ?? 1).'" '.(($configuration['group_mandatory'] == 1 ) ? ' required' : '').'>'.(${$attribute['item_name']} ?? $attribute['item_name']).'
|
||||
</label>';
|
||||
<input id="'.$attribute['attribute_id'].'>" class="option checkbox" value="'.$attribute['attribute_id'].'" name="product[option]['.$configuration['assignment'].'][]" type="checkbox" data-price="'.($attribute['price'] ?? 0).'" data-rrp="'.($attribute['rrp'] ?? 0).'" data-modifier="'.($attribute['price_modifier'] ?? 1).'" '.(($configuration['group_mandatory'] == 1 ) ? ' required' : '').$isChecked.'>'.(${$attribute['item_name']} ?? $attribute['item_name']).'
|
||||
</label>';
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
$view .= '<div class="radio-checkbox">'.$output.'</div>';
|
||||
|
||||
break;
|
||||
|
||||
case 2: //Dropdown
|
||||
// Check if any option is pre-selected via URL
|
||||
$hasPreselection = isset($_GET['option_id']) && !empty($_GET['option_id']);
|
||||
|
||||
$output ='
|
||||
<select id="'.$configuration['assignment'].'" class="option select" name="product[option]['.$configuration['assignment'].']" '.(($configuration['group_mandatory'] == 1 ) ? ' required' : '').'>
|
||||
<option value="" selected disabled style="display:none">'.$configuration['assignment_name'].'</option>
|
||||
<option value=""'.($hasPreselection ? '' : ' selected').' disabled style="display:none">'.$configuration['assignment_name'].'</option>
|
||||
';
|
||||
|
||||
foreach ($configuration['attributes'] as $attribute){
|
||||
// Check if this option should be pre-selected
|
||||
$isSelected = (isset($_GET['option_id']) && $_GET['option_id'] == $attribute['attribute_id']) ? ' selected' : '';
|
||||
|
||||
if(isset($attribute['full_path']) && $attribute['full_path'] !=''){
|
||||
|
||||
|
||||
$onclick ='';
|
||||
//ADD updateOption to change pictures when GROUP is IN configuration
|
||||
if(isset($product['config_setting']) && $product['config_setting'] == $configuration['assignment']){
|
||||
|
||||
|
||||
$IMG_large_id = img_url.$attribute['alternative_media_full_path']; //URL TO LARGE IMAGE
|
||||
$onclick = 'onclick="updateOption(\''.$product['rowID'].'\',\''.$IMG_large_id.'\')"';
|
||||
}
|
||||
|
||||
$IMG_small_id = img_url.$attribute['full_path']; //URL TO SMALL IMAGE
|
||||
|
||||
|
||||
$output .= '
|
||||
<option id="'.$attribute['attribute_id'].'" value="'.$attribute['attribute_id'].'" data-price="'.($attribute['price'] ?? 0).'" data-rrp="'.($attribute['rrp'] ?? 0).'" data-modifier="'.($attribute['price_modifier'] ?? 1).'">'.(${$attribute['item_name']} ?? $attribute['item_name']).'</option>';
|
||||
<option id="'.$attribute['attribute_id'].'" value="'.$attribute['attribute_id'].'" data-price="'.($attribute['price'] ?? 0).'" data-rrp="'.($attribute['rrp'] ?? 0).'" data-modifier="'.($attribute['price_modifier'] ?? 1).'"'.$isSelected.'>'.(${$attribute['item_name']} ?? $attribute['item_name']).'</option>';
|
||||
|
||||
|
||||
} else {
|
||||
$output .= '
|
||||
<option id="'.$attribute['attribute_id'].'" value="'.$attribute['attribute_id'].'" data-price="'.($attribute['price'] ?? 0).'" data-rrp="'.($attribute['rrp'] ?? 0).'" data-modifier="'.($attribute['price_modifier'] ?? 1).'">'.(${$attribute['item_name']} ?? $attribute['item_name']).'</option>';
|
||||
<option id="'.$attribute['attribute_id'].'" value="'.$attribute['attribute_id'].'" data-price="'.($attribute['price'] ?? 0).'" data-rrp="'.($attribute['rrp'] ?? 0).'" data-modifier="'.($attribute['price_modifier'] ?? 1).'"'.$isSelected.'>'.(${$attribute['item_name']} ?? $attribute['item_name']).'</option>';
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
$view .= $output.'</select></div>';
|
||||
|
||||
@@ -290,16 +340,325 @@ $view .='
|
||||
<input id="product" type="hidden" name="product[product]" value="'.$product['rowID'].'">
|
||||
<input id="product" type="hidden" name="product[version]" value="'.($product['version_id'] ?? '').'">
|
||||
|
||||
<input type="submit" value="'.$add_to_basket.'" class="btn">
|
||||
<input type="submit" value="'.$add_to_basket.'" class="btn add-to-basket-sticky">
|
||||
</form>
|
||||
<div class="description">
|
||||
'.(${$product['productdescription']} ?? $product['productdescription']).'
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>';
|
||||
|
||||
$view .= '<style>
|
||||
/* Mobile Header - Hidden on desktop */
|
||||
.product-mobile-header {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Carousel Container */
|
||||
.carousel-container {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* Main Image Area */
|
||||
.carousel-main {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
background-color: #f8f8f8;
|
||||
border-radius: 8px;
|
||||
padding: 1rem;
|
||||
overflow: hidden;
|
||||
min-height: 300px;
|
||||
}
|
||||
|
||||
.carousel-main img {
|
||||
max-width: 100%;
|
||||
max-height: 450px;
|
||||
object-fit: contain;
|
||||
border-radius: 8px;
|
||||
transition: opacity 0.3s ease;
|
||||
user-select: none;
|
||||
-webkit-user-drag: none;
|
||||
}
|
||||
|
||||
/* Carousel Arrows */
|
||||
.carousel-arrow {
|
||||
background: rgba(255, 255, 255, 0);
|
||||
border: none;
|
||||
font-size: 1.5rem;
|
||||
padding: 0.75rem 1rem;
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
z-index: 10;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
||||
transition: all 0.2s ease;
|
||||
color: #1a3a5f;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.carousel-arrow:hover {
|
||||
background: #fff;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
|
||||
transform: translateY(-50%) scale(1.1);
|
||||
}
|
||||
|
||||
.carousel-arrow.left { left: 10px; }
|
||||
.carousel-arrow.right { right: 10px; }
|
||||
|
||||
/* Thumbnails Container */
|
||||
.carousel-thumbnails {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 10px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-top: 15px;
|
||||
padding: 10px 0;
|
||||
overflow-x: auto;
|
||||
scroll-behavior: smooth;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: #ccc transparent;
|
||||
}
|
||||
|
||||
.carousel-thumbnails::-webkit-scrollbar {
|
||||
height: 6px;
|
||||
}
|
||||
|
||||
.carousel-thumbnails::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.carousel-thumbnails::-webkit-scrollbar-thumb {
|
||||
background-color: #ccc;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
/* Thumbnail Items */
|
||||
.product-img-small {
|
||||
flex-shrink: 0;
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
border: 2px solid transparent;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
overflow: hidden;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.product-img-small:hover {
|
||||
border-color: #1a3a5f;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.product-img-small.selected {
|
||||
border-color: #1a3a5f;
|
||||
opacity: 1;
|
||||
box-shadow: 0 2px 8px rgba(26, 58, 95, 0.3);
|
||||
}
|
||||
|
||||
.product-img-small img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Sticky Add to Basket Button */
|
||||
.add-to-basket-sticky {
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.add-to-basket-sticky.is-sticky {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
z-index: 1000;
|
||||
border-radius: 0;
|
||||
margin: 0;
|
||||
padding: 1rem 2rem;
|
||||
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
/* Tablet/Mobile Responsive Styles (< 993px) */
|
||||
@media (max-width: 992px) {
|
||||
/* Hide info bar on tablet/mobile */
|
||||
.top-info-bar,
|
||||
.info-bar {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* Show mobile header on tablet/mobile */
|
||||
.product-mobile-header {
|
||||
display: block;
|
||||
order: 0;
|
||||
padding: 1rem;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.product-mobile-header .breadcrum {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.product-mobile-header .name {
|
||||
font-size: 1.5rem;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
/* Hide original breadcrumb and name on tablet/mobile */
|
||||
.product-wrapper > .breadcrum,
|
||||
.product-wrapper > .name {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Reorder product page layout */
|
||||
.product.content-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
gap: 0;
|
||||
max-width: 100%;
|
||||
border-radius: 0;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
/* Full width carousel */
|
||||
.carousel-container,
|
||||
.product-imgs {
|
||||
order: 1;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.carousel-main {
|
||||
border-radius: 0;
|
||||
padding: 0;
|
||||
min-height: auto;
|
||||
max-height: 60vh;
|
||||
}
|
||||
|
||||
.carousel-main img {
|
||||
max-width: 100%;
|
||||
max-height: 60vh;
|
||||
width: 100%;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.carousel-arrow {
|
||||
padding: 0.5rem 0.75rem;
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.carousel-arrow.left { left: 5px; }
|
||||
.carousel-arrow.right { right: 5px; }
|
||||
|
||||
/* Thumbnails */
|
||||
.carousel-thumbnails {
|
||||
margin-top: 10px;
|
||||
padding: 10px;
|
||||
justify-content: flex-start;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.product-img-small {
|
||||
width: 55px;
|
||||
height: 55px;
|
||||
}
|
||||
|
||||
/* Product wrapper */
|
||||
.product-wrapper {
|
||||
order: 2;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
/* Breadcrumb - smaller on tablet/mobile */
|
||||
.breadcrum {
|
||||
font-size: 0.8rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
/* Always sticky add to basket on tablet/mobile */
|
||||
.add-to-basket-sticky {
|
||||
position: fixed !important;
|
||||
left: 0 !important;
|
||||
right: 0 !important;
|
||||
bottom: 0 !important;
|
||||
width: 100% !important;
|
||||
z-index: 1000 !important;
|
||||
border-radius: 0 !important;
|
||||
margin: 0 !important;
|
||||
padding: 1rem !important;
|
||||
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.15) !important;
|
||||
}
|
||||
|
||||
/* Add padding at bottom for sticky button */
|
||||
.product.content-wrapper {
|
||||
padding-bottom: 70px;
|
||||
}
|
||||
|
||||
/* Prices/stock spacing */
|
||||
.product-wrapper .prices,
|
||||
.product-wrapper .stock {
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* Extra small screens */
|
||||
@media (max-width: 480px) {
|
||||
.carousel-main img {
|
||||
max-height: 50vh;
|
||||
}
|
||||
|
||||
.product-img-small {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.carousel-arrow {
|
||||
padding: 0.4rem 0.6rem;
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
</style>';
|
||||
}
|
||||
|
||||
$view .= '
|
||||
<script>
|
||||
<script>
|
||||
// Push viewContent event to dataLayer
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
window.dataLayer.push({
|
||||
"event": "viewContent",
|
||||
"ecommerce": {
|
||||
"detail": {
|
||||
"products": [{
|
||||
"id": "' . $product['rowID'] . '",
|
||||
"name": "' . addslashes(${$product['productname']} ?? $product['productname']) . '",
|
||||
"price": "' . $product['price'] . '",
|
||||
"category": "' . ($product['category_name'] ?? '') . '"
|
||||
}]
|
||||
}
|
||||
},
|
||||
"content_type": "product",
|
||||
"content_ids": ["' . $product['rowID'] . '"],
|
||||
"content_name": "' . addslashes(${$product['productname']} ?? $product['productname']) . '",
|
||||
"value": "' . $product['price'] . '",
|
||||
"currency": "EUR"
|
||||
});
|
||||
|
||||
// Pre-select option from URL
|
||||
(function() {
|
||||
//Read urlstring
|
||||
const queryString = window.location.href;
|
||||
const option_id = queryString.substring(queryString.lastIndexOf(\'/\') + 1);
|
||||
@@ -308,20 +667,21 @@ $view .= '
|
||||
|
||||
//Check for option_id
|
||||
if (option_id != url_slug){
|
||||
document.getElementById(option_id).checked = true;
|
||||
const optionElement = document.getElementById(option_id);
|
||||
if (optionElement) {
|
||||
optionElement.checked = true;
|
||||
}
|
||||
} else {
|
||||
// Get all radio buttons
|
||||
const radioButtons = document.querySelectorAll(\'.picture_select_label input[type="radio"]\');
|
||||
|
||||
|
||||
// Select the first radio button if any exist
|
||||
if (radioButtons.length > 0) {
|
||||
radioButtons[0].checked = true;
|
||||
radioButtons[0].checked = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
</script>';
|
||||
}
|
||||
})();
|
||||
</script>';
|
||||
|
||||
$view .= template_footer();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user