From 85035f27686e3a868f69f54f84822b035f5eeadc Mon Sep 17 00:00:00 2001 From: apurvabangali <107414864+apurvabangali@users.noreply.github.com> Date: Mon, 29 Apr 2024 16:05:20 +0530 Subject: [PATCH] WIP --- .../js/front-set-product-measurements.js | 285 ++++++++++++++++++ .../front/customer_account_section.tpl | 86 ++++++ .../views/templates/hook/customer_account.tpl | 7 + .../display_measurements_section_cart.tpl | 22 ++ .../hook/set-measurements-button.tpl | 76 +++++ .../_partials/cart-detailed-product-line.tpl | 2 +- .../_partials/order-final-summary-table.tpl | 0 .../_partials/order-final-summary.tpl | 0 8 files changed, 477 insertions(+), 1 deletion(-) create mode 100644 modules/thobbodymeasurements/views/js/front-set-product-measurements.js create mode 100644 modules/thobbodymeasurements/views/templates/front/customer_account_section.tpl create mode 100644 modules/thobbodymeasurements/views/templates/hook/customer_account.tpl create mode 100644 modules/thobbodymeasurements/views/templates/hook/display_measurements_section_cart.tpl create mode 100644 modules/thobbodymeasurements/views/templates/hook/set-measurements-button.tpl mode change 100755 => 100644 templates/checkout/_partials/order-final-summary-table.tpl mode change 100755 => 100644 templates/checkout/_partials/order-final-summary.tpl diff --git a/modules/thobbodymeasurements/views/js/front-set-product-measurements.js b/modules/thobbodymeasurements/views/js/front-set-product-measurements.js new file mode 100644 index 0000000..0ce9d9d --- /dev/null +++ b/modules/thobbodymeasurements/views/js/front-set-product-measurements.js @@ -0,0 +1,285 @@ +$(document).ready(function() { + + $('#photos-completed-button').click(function(event){ + event.preventDefault(); + + var accessCode = $('#product-additional-info-access-code').val(); + + $.ajax({ + url: 'index.php?fc=module&module=thobbodymeasurements&controller=SetProductMeasurements&ajax=true&action=getCustomerMeasurementsForMirrorSize', + method: 'POST', + dataType: 'json', + headers: { + Accepts: "application/json", + }, + data: { + ajax: true, + action: 'getCustomerMeasurementsForMirrorSize', + accessCode: accessCode, + }, + success: function(response) { + console.log(response); + // window.location.reload(); + }, + error: function(xhr, status, error) { + console.error(xhr.responseText); + } + }); + }); + + $('#set-measurements-button').click(function(event) { + // Prevent the default behavior of the anchor tag + event.preventDefault(); + + // Toggle the visibility of the modal + $('#measurements-modal').toggle(); + }); + $(document).click(function(event) { + // Check if the click target is not within the modal + if (!$(event.target).closest('#measurements-modal').length && !$(event.target).is('#set-measurements-button')) { + // Hide the modal + $('#measurements-modal').hide(); + } + }); + }); + + + // Add click event handler to the "Custom Measurements" tab + $('#custom-measurements-tab').click(function(event) { + // Prevent the default behavior of the anchor tag + event.preventDefault(); + + // Hide the "Mirror Size Measurements" tab if it's currently active + $('#mirror-size-measurements').removeClass('opacity-100 block active'); + + // Show the "Custom Measurements" tab + $('#custom-measurements').addClass('opacity-100 block active'); +}); + +// Add click event handler to the "Mirror Size Measurements" tab +$('#mirror-size-measurements-tab').click(function(event) { + // Prevent the default behavior of the anchor tag + event.preventDefault(); + + + // Show the "Mirror Size Measurements" tab + $('#mirror-size-measurements').addClass('opacity-100 block active'); +}); + + + + // Add click event handler to the "Photos Completed" button + $('#photos-completed-button').click(function(event) { + // Perform some action here + alert('Photos Completed button clicked!'); + }); + + + $('#submit-measurements-button').click(function(event) { + event.preventDefault(); + var measurements = []; + + $('.modal-set-measurements .form-group').each(function() { + var attributeId = $(this).find('input').attr('id'); + var value = $(this).find('input').val(); + console.log("Attribute id: ",attributeId) + console.log("value: ",value) + + + measurements.push({ + "attributeId": attributeId, + "value": value + }); + }); + console.log("measurements: ",measurements) + + var formId = $('#current_form_id').val(); + var formLabel = $('#current_form_label').val(); + + var productId = $('#product-additional-info-product-id').val(); + var categoryId = $('#product-additional-info-category-id').val(); + var productAttributeId = $('#product-additional-info-product-attribute-id').val(); + + $.ajax({ + url: 'index.php?fc=module&module=thobbodymeasurements&controller=SetProductMeasurements&ajax=true&action=saveProductMeasurements', + method: 'POST', + dataType: 'json', + headers: { + Accepts: "application/json", + }, + data: { + ajax: true, + action: 'saveProductMeasurements', + formId: formId, + formLabel: formLabel, + measurements: JSON.stringify(measurements), + productId: productId, + categoryId: categoryId, + productAttributeId: productAttributeId, + }, + success: function(response) { + console.log(response); + window.location.reload(); + }, + error: function(xhr, status, error) { + console.error(xhr.responseText); + } + }); + }); + + $('.add-to-cart').click( (event) => { + console.log("inside add to cart click..."); + + var productId = $('#product-additional-info-product-id').val(); + var categoryId = $('#product-additional-info-category-id').val(); + var productAttributeId = $('#product-additional-info-product-attribute-id').val(); + + if(!productId && !categoryId){ + return; + } + + event.preventDefault(); + event.stopImmediatePropagation(); + + var formId = $('#current_form_id').val(); + var formLabel = $('#current_form_label').val(); + var measurements = []; + + $('.modal-set-measurements .form-group').each(function() { + var attributeId = $(this).find('input').attr('id'); + var value = $(this).find('input').val(); + + measurements.push({ + "attributeId": attributeId, + "value": value + }); + }); + + //first check if the measurements are set by the customer + $.ajax({ + url: 'index.php?fc=module&module=thobbodymeasurements&controller=SetProductMeasurements&ajax=true&action=customerHasMeasurements', + method: 'POST', + dataType: 'json', + headers: { + Accepts: "application/json", + }, + data: { + ajax: true, + action: 'customerHasMeasurements', + productId: productId, + categoryId: categoryId, + } + }).done(function (response){ + console.log('has measurements response....'); + if(!response.hasMeasurements){ + console.log("Set measurements first..."); + $('#measurements-modal').modal('show'); + }else{ + $.ajax({ + url: 'index.php?fc=module&module=thobbodymeasurements&controller=SetProductMeasurements&ajax=true&action=saveProductMeasurements', + method: 'POST', + dataType: 'json', + headers: { + Accepts: "application/json", + }, + data: { + ajax: true, + action: 'saveProductMeasurements', + formId: formId, + formLabel: formLabel, + measurements: JSON.stringify(measurements), + productId: productId, + categoryId: categoryId, + productAttributeId: productAttributeId, + }, + success: function(response) { + console.log(response); + console.log("Proceed to add to cart...."); + + const $form = $(event.currentTarget.form); + const query = `${$form.serialize()}&add=1&action=update`; + console.log("Query: ", query); + + const actionURL = $form.attr('action'); + const addToCartButton = $(event.currentTarget); + + addToCartButton.prop('disabled', true); + + const isQuantityInputValid = ($input) => { + let validInput = true; + + $input.each((index, input) => { + const $currentInput = $(input); + const minimalValue = parseInt($currentInput.attr('min'), 10); + + if (minimalValue && $currentInput.val() < minimalValue) { + onInvalidQuantity($currentInput); + validInput = false; + } + }); + + return validInput; + }; + + let onInvalidQuantity = ($input) => { + $input + .parents(prestashop.selectors.product.addToCart) + .first() + .find(prestashop.selectors.product.minimalQuantity) + .addClass('error'); + $input + .parent() + .find('label') + .addClass('error'); + }; + + const $quantityInput = $form.find('input[min]'); + + if (!isQuantityInputValid($quantityInput)) { + onInvalidQuantity($quantityInput); + return; + } + + $.post(actionURL, query, null, 'json') + .then((resp) => { + console.log('Resp: ', resp); + if (!resp.hasError) { + prestashop.emit('updateCart', { + reason: { + idProduct: resp.id_product, + idProductAttribute: resp.id_product_attribute, + idCustomization: resp.id_customization, + linkAction: 'add-to-cart', + cart: resp.cart, + }, + resp, + }); + } else { + prestashop.emit('handleError', { + eventType: 'addProductToCart', + resp, + }); + } + }) + .fail((resp) => { + prestashop.emit('handleError', { + eventType: 'addProductToCart', + resp, + }); + }) + .always(() => { + setTimeout(() => { + addToCartButton.prop('disabled', false); + }, 1000); + }); + }, + error: function(xhr, status, error) { + console.error(xhr.responseText); + } + }); + } + }); + }); + + + diff --git a/modules/thobbodymeasurements/views/templates/front/customer_account_section.tpl b/modules/thobbodymeasurements/views/templates/front/customer_account_section.tpl new file mode 100644 index 0000000..a0177f4 --- /dev/null +++ b/modules/thobbodymeasurements/views/templates/front/customer_account_section.tpl @@ -0,0 +1,86 @@ +{** + * Copyright since 2007 PrestaShop SA and Contributors + * PrestaShop is an International Registered Trademark & Property of PrestaShop SA + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License 3.0 (AFL-3.0) + * that is bundled with this package in the file LICENSE.md. + * It is also available through the world-wide-web at this URL: + * https://opensource.org/licenses/AFL-3.0 + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@prestashop.com so we can send you a copy immediately. + * + * @author PrestaShop SA <contact@prestashop.com> + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) + *} +{extends file='customer/page.tpl'} + +{block name='page_title'} + {l s='thob - Manual Body Measurements' mod='thobbodymeasurements'} +{/block} + +{block name='page_content'} +<div class="bg-white-400 shadow-md"> + <section class=" h-34 p-10 flex flex-col"> + {if isset($selectedForm)} + <h2 class="text-lg font-bold">{l s='Form:' mod='thobbodymeasurements'} {$selectedForm.label_form}</h2> + <form action="#" method="post" class="flex flex-col "> + {foreach from=$selectedForm.attributes item=attribute} + <section class="flex flex-row mx-auto p-4"> + <div class=" flex flex-row gap-4"> + <label for="{$attribute.id}" class="text-base font-semibold mt-1 ">{$attribute.name}:</label> + <div class="w-[500px]"> + <input + type="text" + id="{$attribute.id}" + name="{$attribute.id}" + class=" w-full" + pattern="[0-9]+" + title="Please enter a positive number" + required + {if isset($customerMeasurements) && isset($customerMeasurements[$attribute.id])} + value="{$customerMeasurements[$attribute.id]}" + {else} + placeholder="Enter measurement" + {/if} + /> + </div> + <div class="mt-1"> + {$attribute.unit} + </div> + </div> + <input type="hidden" name="selected_form_id" id="selected_form_id" class="form-control" value="{$selectedForm.id_form}"> + <input type="hidden" name="selected_form_label" id="selected_form_label" class="form-control" value="{$selectedForm.label_form}"> + </section> + {/foreach} + + <div class=""> + <button name="measurements_submit_form" type="submit" class=" hover:text-white hover:no-underline px-6 py-2 bg-blue-950 disabled:bg-gray-700 text-white text-base font-light">{l s='Save Measurements' mod='thobbodymeasurements'}</button> + </div> + </form> + {else} + <form action="#" method="post" class="form-horizontal"> + <div class="flex lg:flex-row flex-col gap-4 justify-center"> + <label for="form_select" class="form-control-label col-md-3 font-medium text-lg mt-1 ">{l s='Select a Form:' mod='thobbodymeasurements'}</label> + <div class=""> + <select name="form_select" id="form_select" class="form-control form-control-select w-[220px] h-[40px] rounded"> + {foreach from=$currentForms item=form} + <option value="{$form.id_form}">{$form.label_form}</option> + {/foreach} + </select> + </div> + </div> + + <div class=""> + <div class=" hover:text-white hover:no-underline px-6 py-2 bg-blue-950 disabled:bg-gray-700 text-white text-base font-light w-32"> + <button type="submit" class="">{l s='Select Form' mod='thobbodymeasurements'}</button> + </div> + </div> + </form> + {/if} + </section> +</div> +{/block} diff --git a/modules/thobbodymeasurements/views/templates/hook/customer_account.tpl b/modules/thobbodymeasurements/views/templates/hook/customer_account.tpl new file mode 100644 index 0000000..f5c5e5a --- /dev/null +++ b/modules/thobbodymeasurements/views/templates/hook/customer_account.tpl @@ -0,0 +1,7 @@ + +<a class="w-full md:w-1/3 lg:w-1/5 flex flex-col p-4 border-gray-500" id="tbm-link" href="{$front_controller}"> + <span class="flex flex-col items-center font-semibolds text-lg"> + <svg xmlns="http://www.w3.org/2000/svg" width=32 height=32 viewBox="0 0 32 32" id="measurements" stroke="currentColor"><path d="M29.5,1h-5A2.5,2.5,0,0,0,22,3.5V22H3.5A2.5,2.5,0,0,0,1,24.5v5A2.5,2.5,0,0,0,3.5,32h26A2.5,2.5,0,0,0,32,29.5V3.5A2.5,2.5,0,0,0,29.5,1ZM31,29.5A1.5,1.5,0,0,1,29.5,31H3.5A1.5,1.5,0,0,1,2,29.5v-5A1.5,1.5,0,0,1,3.5,23H4v3.5a.5.5,0,0,0,1,0V23H7v1.5a.5.5,0,0,0,1,0V23h2v1.5a.5.5,0,0,0,1,0V23h2v3.5a.5.5,0,0,0,1,0V23h2v1.5a.5.5,0,0,0,1,0V23h2v1.5a.5.5,0,0,0,1,0V23h2v3.5a.5.5,0,0,0,1,0V23h3.5a.5.5,0,0,0,0-1H23V20h1.5a.5.5,0,0,0,0-1H23V17h1.5a.5.5,0,0,0,0-1H23V14h3.5a.5.5,0,0,0,0-1H23V11h1.5a.5.5,0,0,0,0-1H23V8h1.5a.5.5,0,0,0,0-1H23V5h3.5a.5.5,0,0,0,0-1H23V3.5A1.5,1.5,0,0,1,24.5,2h5A1.5,1.5,0,0,1,31,3.5Z"></path></svg> + {l s='thob Body Measurements' mod='thobbodymeasurements'} + </span> +</a> \ No newline at end of file diff --git a/modules/thobbodymeasurements/views/templates/hook/display_measurements_section_cart.tpl b/modules/thobbodymeasurements/views/templates/hook/display_measurements_section_cart.tpl new file mode 100644 index 0000000..5e25114 --- /dev/null +++ b/modules/thobbodymeasurements/views/templates/hook/display_measurements_section_cart.tpl @@ -0,0 +1,22 @@ +{if $measurements} + <div class="block w-full overflow-auto scrolling-touch table-striped p-1"> + <table class="w-full max-w-full mb-4 bg-transparent"> + <thead> + <tr> + <th>Attribute</th> + <th>Value</th> + <th>Unit</th> + </tr> + </thead> + <tbody> + {foreach from=$measurements item="measurement"} + <tr> + <td style="text-align:left;">{$measurement.label}</td> + <td style="text-align:left;">{$measurement.value}</td> + <td style="text-align:left;">{$measurement.unit}</td> + </tr> + {/foreach} + </tbody> + </table> + </div> +{/if} diff --git a/modules/thobbodymeasurements/views/templates/hook/set-measurements-button.tpl b/modules/thobbodymeasurements/views/templates/hook/set-measurements-button.tpl new file mode 100644 index 0000000..c192473 --- /dev/null +++ b/modules/thobbodymeasurements/views/templates/hook/set-measurements-button.tpl @@ -0,0 +1,76 @@ + +<input type="hidden" id="product-additional-info-product-id" value="{$productId}"> +<input type="hidden" id="product-additional-info-category-id" value="{$categoryId}"> +<input type="hidden" id="product-additional-info-product-attribute-id" value="{$productAttributeId}"> +<input type="hidden" id="product-additional-info-access-code" value="{$accessCode}"> + +<a href="#" class="product-set-measurements-btn" id="set-measurements-button" data-toggle="modal" data-target="#measurements-modal"> + Set Measurements +</a> + +<!-- Modal --> +<div class="modal modal-set-measurements" id="measurements-modal" tabindex="-1" role="dialog" style="display: none;;overflow-x:auto ;position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 600px; height: 80%; background-color: white; border: 1px solid black; padding: 20px; z-index: 9999;"> + <div class="modal-dialog" role="document"> + <div class="modal-content"> + <div class="modal-header"> + <ul class="flex flex-wrap list-none pl-0 mb-0 border border-t-0 border-r-0 border-l-0 border-b-1 border-gray-200" id="measurementTabs" role="tablist"> + <li class="-mb-px"> + <a class="inline-block py-2 px-4 no-underline border border-b-0 mx-1 rounded rounded-t active" id="custom-measurements-tab" data-toggle="tab" href="#custom-measurements" role="tab" aria-controls="custom-measurements" aria-selected="true">Custom Measurements</a> + </li> + <li class="-mb-px"> + <a class="inline-block py-2 px-4 no-underline border border-b-0 mx-1 rounded rounded-t" id="mirror-size-measurements-tab" data-toggle="tab" href="#mirror-size-measurements" role="tab" aria-controls="mirror-size-measurements" aria-selected="false">Mirror Size Measurements</a> + </li> + </ul> + <div class="modal-body"> + <div class="tab-content" id="measurementTabsContent"> + <div class="tab-pane opacity-100 block active" id="custom-measurements" role="tabpanel" aria-labelledby="custom-measurements-tab"> + {if isset($currentForm)} + <h2>{$currentForm.label_form}</h2> + <form id="measurements-form" name="measurements-form" class="form-horizontal" action="#" method="POST"> + <section class="form-fields"> + {foreach from=json_decode($currentForm.attributes, true) item=$attribute} + <div class="mb-4 flex flex-wrap form-group "> + <label for="{$attribute.id}" class="form-control-label md:w-1/4 pr-4 pl-4 required">{$attribute.name}</label> + <div class="md:w-1/2 pr-4 pl-4 js-input-column"> + <input + type="text" + id="{$attribute.id}" + name="{$attribute.id}" + class=" block appearance-none w-full py-1 px-2 mb-1 text-base leading-normal bg-white text-gray-800 border border-gray-200 rounded" + pattern="[0-9]+" + title="Please enter a positive number" + required + {if isset($customerMeasurements) && isset($customerMeasurements[$attribute.id])} + value="{$customerMeasurements[$attribute.id]}" + {/if}> + </div> + <div class="md:w-1/4 pr-4 pl-4 form-control-comment"> + <small class="block mt-1 text-gray-700">{$attribute.unit}</small> + </div> + </div> + {/foreach} + <input type="hidden" name="current_form_id" id="current_form_id" class="block appearance-none w-full py-1 px-2 mb-1 text-base leading-normal bg-white text-gray-800 border border-gray-200 rounded" value="{$currentForm.id_form}"> + <input type="hidden" name="current_form_label" id="current_form_label" class="block appearance-none w-full py-1 px-2 mb-1 text-base leading-normal bg-white text-gray-800 border border-gray-200 rounded" value="{$currentForm.label_form}"> + </section> + </form> + {else} + <p>No form data available.</p> + {/if} + </div> + <div class="tab-pane opacity-0" id="mirror-size-measurements" role="tabpanel" aria-labelledby="mirror-size-measurements-tab"> + {if $qrCode} + <img src="{$qrCode}" alt="Mirror Size QR Code" class="max-w-full h-auto"> + <p> Scan the above QR code to begin our easy 2 photo custom measurement collection.</p> + <p> Click on 'Photos Completed' button once your above process is finished. </p> + <button type="button" class="inline-block align-middle text-center select-none border font-normal whitespace-no-wrap rounded py-1 px-3 leading-normal no-underline bg-green-500 text-white hover:green-600" id="photos-completed-button" name="photos-completed-button">Photos Completed</button> + {/if} + </div> + </div> + </div> + <div class="modal-footer"> + <button type="submit" class="inline-block align-middle text-center select-none border font-normal whitespace-no-wrap rounded py-1 px-3 leading-normal no-underline bg-blue-600 text-white hover:bg-blue-600" id="submit-measurements-button">{l s='Submit' mod='thobbodymeasurements'}</button> + <button type="button" class="inline-block align-middle text-center select-none border font-normal whitespace-no-wrap rounded py-1 px-3 leading-normal no-underline bg-gray-600 text-white hover:bg-gray-700" data-dismiss="modal">Close</button> + </div> + </div> + </div> +</div> diff --git a/templates/checkout/_partials/cart-detailed-product-line.tpl b/templates/checkout/_partials/cart-detailed-product-line.tpl index a3d050e..8b02604 100644 --- a/templates/checkout/_partials/cart-detailed-product-line.tpl +++ b/templates/checkout/_partials/cart-detailed-product-line.tpl @@ -41,7 +41,7 @@ <div class="modal-body flex flex-col gap-2"> {foreach from=$customization.fields item="field"} <div class="product-customization-line row"> - <div class="col-sm-12 col-xs-8 value"> + <div class="value"> {if $field.type == 'text'} {if (int)$field.id_module} {$field.text nofilter} diff --git a/templates/checkout/_partials/order-final-summary-table.tpl b/templates/checkout/_partials/order-final-summary-table.tpl old mode 100755 new mode 100644 diff --git a/templates/checkout/_partials/order-final-summary.tpl b/templates/checkout/_partials/order-final-summary.tpl old mode 100755 new mode 100644