UNITED STATES ARMY M-60 PATTON Challenge Coin
people are viewing this right now
Freeshipping for all & more discount
${function() {
const variantData = data.variant || {"id":"05684680-f222-4159-b767-ba7e0c1cd8a1","product_id":"11a89611-a4b9-4d1a-a5db-48a5b96eaf1f","title":"","weight_unit":"lb","inventory_quantity":0,"sku":"","barcode":"","position":1,"option1":"","option2":"","option3":"","note":"","image":null,"wholesale_price":[{"price":15.95,"min_quantity":1}],"weight":"0","compare_at_price":"0","price":"15.95","retail_price":"0","available":true,"url":"\/products\/united-states-army-m-60-patton-challenge-coin?variant=05684680-f222-4159-b767-ba7e0c1cd8a1","available_quantity":999999999,"options":[],"off_ratio":"0","flashsale_info":{"variant_id":"05684680-f222-4159-b767-ba7e0c1cd8a1","product_id":"","quantity":0,"discount_id":"","limit_time":0,"limit_buy":0,"user_limit_buy":0,"discount_sales":0,"discount_sales_rate":"","discount_stock":0,"ends_at":0,"starts_at":0,"allow_oversold":"","allocation_method":"","price":"15.95","compare_at_price":"","discount_price":"15.95","customary_saved_price":"","customary_off_ratio":"","discount_saved_price":"","discount_off_ratio":"0","use_before_price":false,"before_price":"","title":"","properties":"","color_setting_promotional_copy":"","discount_quantity":0,"is_need_split":false},"sales":0};
const saveType = "percentage";
const productLabelDiscountOn = true;
return `
-
${saveType == 'percentage'
? `-${variantData.off_ratio}%`
: `-`
}
`;
}()}
${(function () {
const automatic_discount_list = originData.automatic_discount_list;
// 显示类型
const DISPLAY_TYPE = {
DTE_FOLD: 'DTE_FOLD', // 折叠
DTE_TILE: 'DTE_TILE' // 平铺
}
const DEFAULT_CONFIG = {
BG: 'rgba(235, 57, 27, 0.04)',
TEXT_COLOR: '#EB391B',
BORDER_COLOR: 'rgb(235, 57, 27)'
};
const isExist = automatic_discount_list?.length > 0 && automatic_discount_list.some(item => item.discount[0].product_enabled);
// 如果没有任何自动折扣,则隐藏,防止gap占位
if (!isExist) {
return `
`;
} else {
return `
${(function () {
return automatic_discount_list.map((item) => {
// 模版类型
const template_type = item.discount[0].template_type;
// 是否显示自动折扣
const is_show_automatic_discount = item.discount[0].product_enabled;
// 是否跳转落地页
const is_redirection = item.discount[0].is_redirection;
// 折扣图标
const discount_icon = item.discount_icon;
// 第一个自动折扣
const first_automatic_discount = item.discount[0];
// 显示折叠展示
const isFold = (item.discount[0].display_type || DISPLAY_TYPE.DTE_FOLD) === DISPLAY_TYPE.DTE_FOLD;
// 文本数组
const text_arr = item.discount[0].config.texts;
// 落地页链接
const first_landing_url = `/promotions/discount-default/${first_automatic_discount.discount_id}`;
// 自动折扣总数
const automatic_discount_total = item.discount.length;
// 是否显示折扣图标
const isHasDiscountIcon = discount_icon ? true : false;
// 是否显示折扣图标且模版类型不为tag
const isHasDiscountIconWithNoTag = (template_type != 'tag' && isHasDiscountIcon)? true : false;
// 文本颜色
let text_color = DEFAULT_CONFIG.TEXT_COLOR;
// 背景颜色
const bgFn = (curBg) => template_type === "text" ? "transparent" : curBg;
let bg_color = bgFn(DEFAULT_CONFIG.BG);
// 边框颜色
const borderFn = (curBorder) => template_type == "tag" ? curBorder : "initial";
let border_color = borderFn(DEFAULT_CONFIG.BORDER_COLOR);
// 模版配置
let template_config = first_automatic_discount.template_config;
// 兜底方案
try {
if(template_config.length !== 0){
template_config = JSON.parse(template_config);
text_color= isHasDiscountIconWithNoTag ? template_config.color[template_type].icon_text_color : template_config.color[template_type].text_color;
bg_color = bgFn(template_config.color[template_type].background_color);
const arrayRgba = bg_color.split(",");
arrayRgba.splice(3, 1, " 1)");
border_color = borderFn(`${arrayRgba.join(",")}`);
}
} catch (error) {
console.error('template_config_error', error);
template_config = {
color: {
[template_type]: {
icon_text_color: DEFAULT_CONFIG.TEXT_COLOR,
text_color: DEFAULT_CONFIG.TEXT_COLOR,
background_color: DEFAULT_CONFIG.BG
}
}
};
}
// 标签
const isTag = template_type == 'tag';
// 文字和横幅
const isTextAndBanner = template_type == 'text' || template_type == 'banner';
// 文字样式
const textStyle = `color: ${text_color}; background-color: transparent; border: none;`;
// 标签样式
const labelStyle = `color: ${text_color};border: 1px solid ${border_color};background-color:${bg_color};padding: 4px;`;
// 横幅样式
const bannerStyle = `color: ${text_color};border: none; background-color:${bg_color}`;
// 外层样式在标签样式下不展示颜色配置,除开标签类型,颜色都可以在外层覆盖
let outerStyle = '';
if (template_type == 'text') {
outerStyle = textStyle;
} else if (template_type == 'tag') {
outerStyle = "border: none;";
} else if (template_type == 'banner') {
outerStyle = bannerStyle;
}
/**
* 1. 标签一定是单独样式展示的
* 2. 折叠:横向布局,文字和横幅,合并成一行文本; 标签:单独样式处理
* 3. 平铺:纵向布局,文字、横幅和标签; 标签:单独样式处理
*/
let txtHtml = ``;
if (isFold) {
if(isTag) {
// 标签
const spanText = text_arr.map((text) => {
return `
${text}`;
}).join('');
txtHtml = `
${spanText}
`;
} else {
// 文字和横幅
txtHtml = `
${first_automatic_discount.config.text}
`;
}
} else {
// 文字和横幅, 但标签有自己的样式
const spanText = text_arr.map((text) => {
return `
${text}`;
}).join('');
// 都是纵向布局,标签有间距, 多活动多层级横向布局
txtHtml = `
${spanText}
`;
}
/**
* 显示图标的判断
*/
const discount_type = item.discount_type;
const isShowRebateIcon = ["DT_REBATE_CTQ_OTP", "DT_REBATE_CTQ_OTR", "DT_REBATE_CTA_OTP", "DT_REBATE_CTA_OTR", "DT_M_N_DISCOUNT"].includes(discount_type) && isTextAndBanner
const isShowBxgyIcon = ["DT_BUY_ONE_GET_ONE", "DT_BUY_X_GET_Y"].includes(discount_type)
const isShowBundleIcon = ["DT_CLASSIC_BUNDLE","DT_MIX_MATCH_BUNDLE"].includes(discount_type);
/**
* 渲染下拉框或抽屉的折扣列表
*/
const discount_list_html = (curItem) => {
return `
${function() {
return curItem.discount.map(childItem => {
return `
`}).join('');
}()}
`;
}
return `
${discount_list_html(item)}
${function() {
return text_arr.map((text) => {
return `
${text}
`;
}).join('');
}()}
`;
}).join('');
})()}
`
}
})()}
const TAG = "spz-custom-product-automatic";
class SpzCustomProductAutomatic extends SPZ.BaseElement {
constructor(element) {
super(element);
this.variant_id = '05684680-f222-4159-b767-ba7e0c1cd8a1';
this.isRTL = SPZ.win.document.dir === 'rtl';
}
static deferredMount() {
return false;
}
buildCallback() {
this.action_ = SPZServices.actionServiceForDoc(this.element);
this.templates_ = SPZServices.templatesForDoc(this.element);
this.xhr_ = SPZServices.xhrFor(this.win);
this.setupAction_();
this.viewport_ = this.getViewport();
}
mountCallback() {
this.init();
// 监听事件
this.bindEvent_();
}
async init() {
this.handleFitTheme();
const data = await this.getDiscountList();
this.renderApiData_(data);
}
async getDiscountList() {
const productId = '11a89611-a4b9-4d1a-a5db-48a5b96eaf1f';
const variantId = this.variant_id;
const productType = 'default';
const reqBody = {
product_id: productId,
variant_id: variantId,
discount_method: "DM_AUTOMATIC",
customer: {
customer_id: window.C_SETTINGS.customer.customer_id,
email: window.C_SETTINGS.customer.customer_email
},
product_type: productType
}
const url = `/api/storefront/promotion/display_setting/text/list`;
const data = await this.xhr_.fetchJson(url, {
method: "post",
body: reqBody
}).then(res => {
return res;
}).catch(err => {
this.setContainerDisabled(false);
})
return data;
}
async renderDiscountList() {
this.setContainerDisabled(true);
const data = await this.getDiscountList();
this.setContainerDisabled(false);
// 重新渲染 抖动问题处理
this.renderApiData_(data);
}
clearDom() {
const children = this.element.querySelector('*:not(template)');
children && SPZCore.Dom.removeElement(children);
}
async renderApiData_(data) {
const parentDiv = document.querySelector('.automatic_discount_container');
const newTplDom = await this.getRenderTemplate(data);
if (parentDiv) {
parentDiv.innerHTML = '';
parentDiv.appendChild(newTplDom);
} else {
console.log('automatic_discount_container is null');
}
}
doRender_(data) {
const renderData = data || {};
return this.templates_
.findAndRenderTemplate(this.element, renderData)
.then((el) => {
this.clearDom();
this.element.appendChild(el);
});
}
async getRenderTemplate(data) {
const renderData = data || {};
return this.templates_
.findAndRenderTemplate(this.element, { ...renderData, isRTL: this.isRTL })
.then((el) => {
this.clearDom();
return el;
});
}
setContainerDisabled(isDisable) {
const automaticDiscountEl = document.querySelector('.automatic_discount_container_outer');
if(isDisable) {
automaticDiscountEl.setAttribute('disabled', '');
} else {
automaticDiscountEl.removeAttribute('disabled');
}
}
// 绑定事件
bindEvent_() {
window.addEventListener('click', (e) => {
let containerNodes = document.querySelectorAll(".automatic-container .panel");
let bool;
Array.from(containerNodes).forEach((node) => {
if(node.contains(e.target)){
bool = true;
}
})
// 是否popover面板点击范围
if (bool) {
return;
}
if(e.target.classList.contains('drowdown-icon') || e.target.parentNode.classList.contains('drowdown-icon')){
return;
}
const nodes = document.querySelectorAll('.automatic-container');
Array.from(nodes).forEach((node) => {
node.classList.remove('open-dropdown');
})
// 兼容主题
this.toggleProductSticky(true);
})
// 监听变体变化
document.addEventListener('dj.variantChange', async(event) => {
// 重新渲染
const variant = event.detail.selected;
if (variant.product_id == '11a89611-a4b9-4d1a-a5db-48a5b96eaf1f' && variant.id != this.variant_id) {
this.variant_id = variant.id;
this.renderDiscountList();
}
});
}
// 兼容主题
handleFitTheme() {
// top 属性影响抖动
let productInfoEl = null;
if (window.SHOPLAZZA.theme.merchant_theme_name === 'Wind' || window.SHOPLAZZA.theme.merchant_theme_name === 'Flash') {
productInfoEl = document.querySelector('.product-info-body .product-sticky-container');
} else if (window.SHOPLAZZA.theme.merchant_theme_name === 'Hero') {
productInfoEl = document.querySelector('.product__info-wrapper .properties-content');
}
if(productInfoEl){
productInfoEl.classList.add('force-top-auto');
}
}
// 兼容 wind/flash /hero 主题 (sticky属性影响 popover 层级展示, 会被其他元素覆盖)
toggleProductSticky(isSticky) {
let productInfoEl = null;
if (window.SHOPLAZZA.theme.merchant_theme_name === 'Wind' || window.SHOPLAZZA.theme.merchant_theme_name === 'Flash') {
productInfoEl = document.querySelector('.product-info-body .product-sticky-container');
} else if (window.SHOPLAZZA.theme.merchant_theme_name === 'Hero') {
productInfoEl = document.querySelector('.product__info-wrapper .properties-content');
}
if(productInfoEl){
if(isSticky) {
// 还原该主题原有的sticky属性值
productInfoEl.classList.remove('force-position-static');
return;
}
productInfoEl.classList.toggle('force-position-static');
}
}
setupAction_() {
this.registerAction('handleDropdown', (invocation) => {
const discount_id = invocation.args.discount_id;
const nodes = document.querySelectorAll('.automatic-container');
Array.from(nodes).forEach((node) => {
if(node.getAttribute('id') != `automatic-${discount_id}`) {
node.classList.remove('open-dropdown');
}
})
const $discount_item = document.querySelector(`#automatic-${discount_id}`);
$discount_item && $discount_item.classList.toggle('open-dropdown');
// 兼容主题
this.toggleProductSticky();
});
}
triggerEvent_(name, data) {
const event = SPZUtils.Event.create(this.win, `${ TAG }.${ name }`, data || {});
this.action_.trigger(this.element, name, event);
}
isLayoutSupported(layout) {
return layout == SPZCore.Layout.CONTAINER;
}
}
SPZ.defineElement(TAG, SpzCustomProductAutomatic);
${function(){
const isRTL = originData.isRTL;
const isMobile = originData.isMobile;
const inProductDetail = originData.inProductDetail;
if (!inProductDetail) {
return `
Flash sale cannot be displayed here. Please move it to the product detail area.
(This prompt will not be displayed on the client-side)
`;
}
const flashsaleData = originData.flashsaleData;
const image_domain = originData.image_domain;
const discount_info = flashsaleData.discount_info;
const setting = flashsaleData.product_setting;
if (!discount_info || !setting) return ``;
const displayType = setting.display_type;
const banner = setting.banner;
const productDisplay = setting.product_display;
const bannerConfig = JSON.parse(banner.config);
const productDisplayConfig = JSON.parse(productDisplay.config);
const colorConfig = productDisplayConfig.color;
const countdownConfig = productDisplayConfig.countdown;
let titleIcon = ``;
let bgImg = ``;
const deg = `${isRTL ? -90 : 90}deg`;
const { banner_bg_start, banner_bg_end, banner_text } = colorConfig;
let bgStyle = `background: linear-gradient(${deg}, ${banner_bg_start} 0%, ${banner_bg_end} 100%);`;
let bannerColor = `color: ${banner_text};`
if (banner.type === "TYPE_CUSTOM") {
const { desktop, mobile, image_render } = bannerConfig;
const bgSize = image_render === "fill" ? "background-size: cover;background-position: center;" : "background-position: center;background-size: auto 100%;";
if (isMobile && mobile) {
bgStyle = `background: URL(${image_domain + mobile});${bgSize}`;
} else if (!isMobile && desktop) {
bgStyle = `background: URL(${image_domain + desktop});${bgSize}`;
}
} else {
if (banner.type === "TYPE_ONE") {
titleIcon = productDisplay.text ? `
` : "";
bgImg = ``
}
if (banner.type === "TYPE_TWO") {
titleIcon = productDisplay.text ? `
` : ""
}
}
const { sale_bar_background_color, progress_sale_bar_background_color_start, progress_sale_bar_background_color_end } = colorConfig;
const rate = discount_info.discount_sales_rate;
const progressBarStyle = `background: linear-gradient(${deg}, ${progress_sale_bar_background_color_start} 0%, ${progress_sale_bar_background_color_end} 100%);`;
const saleCount = productDisplay.sales_progress.format === "FORMAT_NUMBER" ? discount_info.discount_sales : `${rate}%`;
const progressBarDom = productDisplay.sales_progress.enabled && rate > 0 ? `
` : ``;
const { countdown_bg, countdown_text } = colorConfig;
const { end_opened, end_format } = countdownConfig;
const tempMap = {
"DD_SSS": "DD:HH:mm:ss:SSS",
"HH_SSS": "HH:mm:ss:SSS",
"DD_ss": "DD:HH:mm:ss",
"HH_ss": "HH:mm:ss"
}
const isShowDD = [tempMap.DD_SSS, tempMap.DD_ss].includes(end_format);
const isShowSSS = [tempMap.DD_SSS, tempMap.HH_SSS].includes(end_format);
const countdown = discount_info.ends_remaining_seconds;
const countdownDom = end_opened ? `
${function() {
if (banner.type === "TYPE_TWO") return `
`
return ``;
}()}
` : ``;
const flashSaleDesc = discount_info.limit_user_product_discount > -1 ? `
Promo products limited to ${discount_info.limit_user_product_discount} item per person
` : "";
return `
${bgImg}
${titleIcon}
${productDisplay.text}
${progressBarDom}
${countdownDom}
${flashSaleDesc}
`}()}
${function(){
const dd = data.dd; const hh = data.hh; const mm = data.mm; const ss = data.ss; const sss = data.SSS;
const hours = data.d * 24 + data.h;
return `
${dd}D
·
${hours}
${hh}
:
${mm}
:
${ss}
.
${sss}
`
}()}
class SpzCustomDiscountFlashsale extends SPZ.BaseElement {
constructor(element) {
super(element);
this.xhr_ = SPZServices.xhrFor(this.win);
this.getFlashSaleApi = "\/api\/storefront\/promotion\/flashsale\/display_setting\/product_setting";
this.timer = null;
this.variantId = "05684680-f222-4159-b767-ba7e0c1cd8a1";
// 促销活动数据
this.flashsaleData = {}
}
isLayoutSupported(layout) {
return layout == SPZCore.Layout.CONTAINER;
}
buildCallback() {
this.templates_ = SPZServices.templatesForDoc();
this.viewport_ = this.getViewport();
// 挂载bind函数 解决this指向问题
this.render = this.render.bind(this);
this.resize = this.resize.bind(this);
this.switchVariant = this.switchVariant.bind(this);
}
mountCallback() {
// 获取数据
this.getData();
this.element.onclick = (e) => {
const cur = this.win.document.querySelector(".app_discount_flashsale_desc");
if (this.flashsaleData.product_setting.is_redirection && appDiscountUtils.inProductBody(this.element) && e.target !== cur) {
this.win.open(`/promotions/discount-default/${this.flashsaleData.discount_info.id}`);
}
}
// 绑定
this.viewport_.onResize(this.resize);
// 监听子款式切换,重新渲染
this.win.document.addEventListener('dj.variantChange', this.switchVariant);
}
unmountCallback() {
// 解绑
this.viewport_.removeResize(this.resize);
this.win.document.removeEventListener('dj.variantChange', this.switchVariant);
// 清除定时器
if (this.timer) {
clearTimeout(this.timer);
this.timer = null;
}
}
resize() {
if (this.timer) {
clearTimeout(this.timer)
this.timer = null;
}
this.timer = setTimeout(() => {
this.render();
}, 200)
}
switchVariant(event) {
const variant = event.detail.selected;
if (variant.product_id == '11a89611-a4b9-4d1a-a5db-48a5b96eaf1f' && variant.id != this.variantId) {
this.variantId = variant.id;
this.getData();
}
}
getData() {
const reqBody = {
product_id: "11a89611-a4b9-4d1a-a5db-48a5b96eaf1f",
product_type: "default",
variant_id: this.variantId
}
this.flashsaleData = {};
this.win.fetch(this.getFlashSaleApi, {
method: "POST",
body: JSON.stringify(reqBody),
headers: {
"Content-Type": "application/json"
}
}).then(async (response) => {
if (response.ok) {
this.flashsaleData = await response.json();
this.render();
} else {
this.clearDom();
}
}).catch(err => {
this.clearDom();
});
}
clearDom() {
const children = this.element.querySelector('*:not(template)');
children && SPZCore.Dom.removeElement(children);
}
render() {
this.templates_
.findAndRenderTemplate(this.element, {
isMobile: appDiscountUtils.judgeMobile(),
isRTL: appDiscountUtils.judgeRTL(),
inProductDetail: appDiscountUtils.inProductBody(this.element),
flashsaleData: this.flashsaleData,
image_domain: this.win.SHOPLAZZA.image_domain,
})
.then((el) => {
this.clearDom();
this.element.appendChild(el);
})
}
}
SPZ.defineElement('spz-custom-discount-flashsale', SpzCustomDiscountFlashsale);
Product was out of stock.
Product is unavailable.
${function(){
const rules = data.data.rules;
return `
`
}()}
${function(){
const isCart = data.data.isCart;
const isCollection = data.data.isCollection;
const isProduct = data.data.isProduct;
const isIndex = data.data.isIndex;
return `
${isCart ? 'The items in the shopping cart do not participate in any recommendation rule. Add the participating items to your shopping cart to check the design.' : ''}
${isProduct ? 'This product did not participated in any recommendation rule. Switch to another product to check the design.' : ''}
${isCollection ? 'The items in this collection do not participate in any recommendation rule. Switch the participating items to check the design.' : ''}
${isIndex ? 'The home page do not participate in any recommendation rule.' : ''}
(This prompt would not display on client-side)
Recommended Products
`
}()}
${function(){
const rule = data.data;
const quickShopButtonVisible = !rule.config.quick_shop_button_type || rule.config.quick_shop_button_type === 'button';
const getImageHeight = function(image){
const image_size = rule.config.image_size || 0;
const imageWidth = image.width || 600;
const imageHeight = image.height || 800;
let ratio = 0;
if(image_size == 0){
ratio = (imageHeight / imageWidth).toFixed(2);
}else if(image_size == 1){
ratio = 1.5;
}else if(image_size == 2){
ratio = 1;
}else if(image_size == 3){
ratio = 0.75;
}
return imageWidth * ratio;
};
const toQuery = obj =>
Object.keys(obj)
.map(k =>
Array.isArray(obj[k])
? obj[k].map(v => `${k}[]=${encodeURIComponent(v)}`).join('&')
: `${k}=${encodeURIComponent(obj[k])}`
)
.join('&');
return `
`
}()}
const isSpecialHeroTheme = window.SHOPLAZZA?.theme?.merchant_theme_name == 'Hero' && window.SHOPLAZZA?.theme?.merchant_theme_c_version == '2.2.19';
const specialHeroThemeClassName = 'hero_2_2_19_smart_recommend_block';
class SpzSmartBlockComponent extends SPZ.BaseElement {
constructor(element) {
super(element);
this.templates_ = null;
this.container_ = null;
this.i18n_ = {};
this.config_ = {};
this.show_type_ = 3;
this.product_resource_id_ = '';
this.collection_resource_id_ = '';
this.cart_items_ = [];
this.customer_id_ = '';
this.order_id_ = '';
}
static deferredMount() {
return false;
}
isLayoutSupported(layout) {
return layout == SPZCore.Layout.CONTAINER;
}
buildCallback() {
const template_type = window.C_SETTINGS.meta.page.template_type;
if (template_type === 1) {
this.show_type_ = 3;
this.product_resource_id_ = window.C_SETTINGS.meta.page.resource_id;
} else if (template_type === 2) {
this.show_type_ = 4;
this.collection_resource_id_ = window.C_SETTINGS.meta.page.resource_id;
} else if (template_type === 15){
this.show_type_ = 5;
} else if (template_type === 13){
this.show_type_ = 6;
} else if (template_type === 20){
this.show_type_ = 7;
this.customer_id_ = window.C_SETTINGS.customer.customer_id;
} else if (template_type === 35){
this.show_type_ = 8;
this.order_id_ = window.location.pathname.split('/').pop();
}
this.templates_ = SPZServices.templatesForDoc(this.element);
this.setAction_();
}
mountCallback() {
const that = this;
const themeName = window.C_SETTINGS.theme.merchant_theme_name;
const isGeek = /Geek/.test(themeName);
this.fetchRules().then((res) => {
if (res && res.rules && res.rules.length) {
const blockEl = document.getElementById('smart_recommend_block');
this.initBlockClass(blockEl);
this.initItemClass(blockEl);
SPZ.whenApiDefined(blockEl).then((api) => {
api.render({data: res}, true).then(() => {
if (isGeek && that.show_type_ === 6) {
blockEl.querySelector('.plugin_container_wrpper').style.padding = '30px 0';
}
const recommendStyle = document.createElement('style');
recommendStyle.innerHTML = `
.plugin__recommend_container,.app-recommend-card {
display: none !important;
}
`;
document.head.appendChild(recommendStyle);
const fetchList = [];
res.rules.forEach((rule) => {
fetchList.push(this.fetchRuleProductList(rule.id));
});
const fetchAll = Promise.all(fetchList);
fetchAll.then((p_res) => {
res.rules.forEach((rule, index) => {
rule.products = p_res[index] && p_res[index].products;
if (rule.products && rule.products.length) {
const modalRender = document.getElementById('smart_recommend_js_root');
const $dest = document.getElementById('cart');
const isLifeStyle = /Life.*Style/.test(window.C_SETTINGS.theme.merchant_theme_name);
if (modalRender && isLifeStyle && $dest.clientWidth > 767) {
modalRender.classList.add('zb-mt-[-180px]')
}
}
const ruleEl = document.getElementById('smart_recommend_rule_' + rule.id);
SPZ.whenApiDefined(ruleEl).then((api) => {
api.render({data: rule}, true).then(() => {
that.impressListen(`#smart_recommend_rule_ul_${rule.id}`, function(){
that.trackRuleImpress(rule);
});
const btnElList = document.querySelectorAll(`#smart_recommend_rule_ul_${rule.id} button`);
btnElList.forEach((btnEl) => {
if (btnEl && rule.config && rule.config.quick_shop_button_bg_color && rule.config.quick_shop_button_text_color) {
btnEl.style.backgroundColor = rule.config.quick_shop_button_bg_color;
btnEl.style.color = rule.config.quick_shop_button_text_color;
}
})
if (isSpecialHeroTheme) {
ruleEl.querySelectorAll(`.smart_recommend_title`).forEach(dom=>{
dom.classList.add('type-title-font-family');
});
document.querySelectorAll(`.${specialHeroThemeClassName} #smart_recommend_rule_ul_${rule.id} .zb-recommend-price-line-through .money`).forEach(dom=>{
dom.classList.add('type-body-font-family');
});
}
});
});
});
});
})
})
} else {
if (window.top !== window.self) {
const template_type = window.C_SETTINGS.meta.page.template_type;
const holderEl = document.getElementById('smart_recommend_preview_no_data_placeholder');
SPZ.whenApiDefined(holderEl).then((api) => {
api.render({data: { isCart: template_type === 13, isCollection: template_type === 2, isProduct: template_type === 1, isIndex: template_type === 15 }}, true);
});
}
}
});
}
initBlockClass(blockEl) {
if (!blockEl) return;
if (blockEl.parentElement && blockEl.parentElement.offsetWidth === document.body.clientWidth) {
blockEl.classList.add('smart_recommend_block_fullscreen');
}
if (isSpecialHeroTheme) {
blockEl.classList.add(specialHeroThemeClassName);
}
}
initItemClass(blockEl) {
if (blockEl) {
const containerWidth = blockEl.offsetWidth;
let itemWidth = '';
if (containerWidth > 780) {
itemWidth = '16%';
} else if (containerWidth > 600) {
itemWidth = '20%';
} else {
itemWidth = '24%';
}
const itemStyleEl = document.createElement('style');
itemStyleEl.innerHTML = `.zb-recommend-li-item{ width: ${itemWidth}; }`;
document.body.appendChild(itemStyleEl);
}
}
setAction_() {
this.registerAction('quickShop', (data) => {
const that = this;
const product_id = data.args.product_id;
const productIndex = data.args.productIndex;
const rule_id = data.args.rule_id;
const ssp = data.args.ssp;
const scm = data.args.scm;
const cfb = data.args.cfb;
const ifb = data.args.ifb;
const modalRender = document.getElementById('smart_recommend_product_modal_render');
if (modalRender) {
document.body.appendChild(modalRender);
}
if (product_id) {
this.fetchProductData(product_id).then((res) => {
const product = res.products && res.products.length && res.products[0] || {};
product.cfb = cfb;
product.ifb = ifb;
SPZ.whenApiDefined(modalRender).then((api) => {
api.render({product: product, productIndex: productIndex, rule_id: rule_id, ssp: ssp, scm: scm, show_type: that.show_type_}, true).then(() => {
const modalEl = document.getElementById('smart_recommend_product_modal');
SPZ.whenApiDefined(modalEl).then((modal) => {
that.impressListen('#smart_recommend_product_modal', function(){
that.trackQuickShop({ rule_id: rule_id, product_id: product_id });
});
modal.open();
});
const formEl = document.getElementById('smart_recommend_product_form');
SPZ.whenApiDefined(formEl).then((form) => {
form.setProduct(product);
});
const variantEl = document.getElementById('smart_recommend_product_variants');
SPZ.whenApiDefined(variantEl).then((variant) => {
variant.handleRender(product);
});
});
})
});
}
});
this.registerAction('handleScroll', (data) => {
this.directTo(data.args.rule_id, data.args.direction);
});
this.registerAction('handleProductChange', (data) => {
const variant = data.args.data.variant;
const product = data.args.data.product;
const imageRenderEl = document.getElementById('smart_recommend_product_image');
SPZ.whenApiDefined(imageRenderEl).then((api) => {
api.render({ variant: variant, product: product });
});
});
this.registerAction('handleAtcSuccess', (detail) => {
const data = detail.args;
data.data.product = data.data.product || {};
data.data.variant = data.data.variant || {};
const product_id = data.data.product.id;
const product_title = data.data.product.title;
const variant_id = data.data.variant.id;
const price = data.data.variant.price;
const rule_id = data.rule_id;
const aid = `smart_recommend.${this.show_type_}.${rule_id}`;
const ifb = data.data.product.ifb;
const cfb = data.data.product.cfb;
const ssp = data.ssp;
const scm = data.scm;
const spm = `smart_recommend_${this.show_type_}.${data.spmIndex}`;
const params = {
id: product_id,
product_id: product_id,
number: 1,
name: product_title,
variant_id: variant_id,
childrenId: variant_id,
item_price: price,
source: 'add_to_cart',
_extra: {
aid: aid,
ifb: ifb,
cfb: cfb,
scm: scm,
spm: `..${window.C_SETTINGS.meta.page.template_name}.${spm}`,
ssp: ssp,
}
};
this.tranckAddToCart(params);
});
this.registerAction('addATCHook', (data) => {
const params = data.args;
const spm = `smart_recommend_${this.show_type_}.${params.spmIndex}`;
this.myInterceptor_ = window.djInterceptors && window.djInterceptors.track.use({
event: 'dj.addToCart',
params: {
aid: `smart_recommend.${this.show_type_}.` + params.rule_id,
ssp: params.ssp,
scm: params.scm,
cfb: params.cfb,
spm: `..${window.C_SETTINGS.meta.page.template_name}.${spm}`,
},
once: true
});
});
}
tranckAddToCart(detail) {
if (window.$) {
window.$(document.body).trigger('dj.addToCart', detail);
}
}
fetchRules() {
const payload = {
show_type: this.show_type_,
};
let that = this;
if (this.show_type_ === 6) {
let line_items = [];
return this.fetchCart().then((res) => {
if (res && res.cart && res.cart.line_items) {
line_items = res.cart.line_items.map((item) => {
return { product_id: item.product_id, variant_id: item.variant_id, quantity: item.quantity, price: item.price }
});
}
payload.line_items = line_items;
that.cart_items_ = line_items;
return that.fetchRulesRequest(payload);
});
} else {
if (this.show_type_ === 3) {
payload.line_items = [{ product_id: this.product_resource_id_ }];
} else if (this.show_type_ === 4) {
payload.collection_id = this.collection_resource_id_;
} else if (this.show_type_ === 7) {
payload.customer_id = this.customer_id_;
} else if (this.show_type_ === 8) {
payload.order_id = this.order_id_;
}
return this.fetchRulesRequest(payload);
}
}
fetchRulesRequest(payload) {
return fetch(window.C_SETTINGS.routes.root + "/api/possum/recommend_query", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(payload)
}).then(function(res){
if(res.ok){
return res.json();
}
});
}
fetchCart() {
return fetch(`/api/cart/cart-select?r=${Math.random().toString(36).slice(-4)}`)
.then((res) => {
if (res.ok) {
return res.json();
}
});
}
fetchRuleProductList(rule_id) {
const payload = {
page: 1,
limit: 100,
fields: ["title", "url", "image", "min_price_variant.price", "min_price_variant.compare_at_price"],
rule_id: rule_id,
};
if (this.show_type_ === 3) {
payload.line_items = [{ product_id: this.product_resource_id_ }];
} else if (this.show_type_ === 4) {
payload.collection_id = this.collection_resource_id_;
} else if (this.show_type_ === 6) {
payload.line_items = this.cart_items_;
} else if (this.show_type_ === 7) {
payload.customer_id = this.customer_id_;
} else if (this.show_type_ === 8) {
payload.order_id = this.order_id_;
}
return fetch(window.C_SETTINGS.routes.root + "/api/possum/recommend_products", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(payload)
}).then(function(res){
if(res.ok){
return res.json();
}
}).catch(function(err){
console.log(err);
});
}
fetchProductData(product_id) {
return fetch(window.C_SETTINGS.routes.root + "/api/possum/products", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
product_ids: [product_id],
fields: [ "images", "options", "min_price_variant", "variants"]
})
}).then(function(res){
if(res.ok){
return res.json();
}
}).catch(function(err){
console.log(err);
const loadingEl = document.getElementById('smart_recommend_loading');
if (loadingEl) {
loadingEl.style.display = 'none';
}
});
}
getStyle(ele, style) {
if (!ele) return;
if (window.getComputedStyle) {
return window.getComputedStyle(ele)[style];
}
return ele.currentStyle[style];
}
directTo(id, direction) {
const scrollElement = document.getElementById(`smart_recommend_rule_ul_${id}`);
const blockWidth = parseInt(this.getStyle(scrollElement, 'width'));
const scrollLength = (blockWidth * 0.19 - 12) * 5;
const scrollPoint = scrollElement.scrollWidth - scrollElement.clientWidth;
if (!scrollElement) return;
if (direction === 'left') {
if (document.dir === 'rtl') {
scrollElement.scrollTo({
left: Math.abs(scrollElement.scrollLeft) >= scrollPoint - 100 ? 0 : scrollElement.scrollLeft - scrollLength,
behavior: 'smooth'
});
return;
}
scrollElement.scrollTo({
left: Math.max(scrollElement.scrollLeft - scrollLength, 0),
behavior: 'smooth'
});
} else {
if (document.dir === 'rtl') {
scrollElement.scrollTo({
left: Math.abs(scrollElement.scrollLeft) >= scrollPoint + 100 ? 0 : scrollElement.scrollLeft + scrollLength,
behavior: 'smooth'
});
return;
}
scrollElement.scrollTo({
left: scrollElement.scrollLeft >= scrollPoint - 100 ? 0 : scrollElement.scrollLeft + scrollLength,
behavior: 'smooth'
});
}
}
trackRuleImpress(rule) {
if (window.sa && window.sa.track) {
window.sa.track("plugin_common", {
plugin_name: "upsell",
event_type: "impressions",
rule_id: rule.id,
ssp: rule.ssp,
scm: rule.scm,
show_type: this.show_type_,
support_app_block: window.C_SETTINGS.theme.support_app_block
});
window.sa.track("module_impressions", {
aid: `smart_recommend.${this.show_type_}.${rule.id}`,
support_app_block: window.C_SETTINGS.theme.support_app_block
});
}
}
trackQuickShop(data) {
window.sa && sa.track && sa.track("plugin_common", {
plugin_name: "upsell",
event_type: "quick_shop",
rule_id: data.rule_id,
product_id: data.product_id,
show_type: this.show_type_,
});
}
impressListen(selector, cb) {
const el = document.querySelector(selector);
const onImpress = (e) => {
if (e) {
e.stopPropagation();
}
cb();
};
if (el && !el.getAttribute('imprsd')) {
el.addEventListener('impress', onImpress)
} else if (el) {
onImpress();
}
}
}
SPZ.defineElement('spz-custom-smart-block', SpzSmartBlockComponent);
${(function(){
const product = data.product;
const toQuery = obj =>
Object.keys(obj)
.map(k =>
Array.isArray(obj[k])
? obj[k].map(v => `${k}[]=${encodeURIComponent(v)}`).join('&')
: `${k}=${encodeURIComponent(obj[k])}`
)
.join('&');
return `
${product.images.map((image) => { return `` }).join('')}
`;
})()}
${(function(){
const product = data.product;
const avail_variants = product.variants.filter(function(variant){
return variant.available;
});
const selected_variant = product.min_price_variant.available ? product.min_price_variant : avail_variants.length && avail_variants[0];
return `
`
})()}
${function() {
const minDays = parseInt('3');
const maxDays = parseInt('10');
const customText = "Estimated Delivery\uff1a{min_date} - {max_date}";
const minDate = new Date(Date.now() + (minDays * 86400000));
const maxDate = new Date(Date.now() + (maxDays * 86400000));
const formatDate = (minDate.getFullYear() == maxDate.getFullYear() && minDate.getFullYear() == new Date().getFullYear())
? new Intl.DateTimeFormat('en', { month: 'short', day: '2-digit' })
: new Intl.DateTimeFormat('en', { month: 'short', day: '2-digit', year: 'numeric' });
const tipText = customText.replace(/\{min_date\}/g, '' + formatDate.format(minDate) + '')
.replace(/\{max_date\}/g, '' + formatDate.format(maxDate) + '');
return `
${tipText}
`;
}()}
${function() {
const postageFreeAmount = 99.99;
const custom_text = "Buy {amount} more to enjoy FREE Shipping";
const totalPrice = +data.total_price;
const diffPrice = postageFreeAmount - totalPrice;
const percentDiff = (diffPrice > 0 ? (totalPrice / postageFreeAmount * 100) : 100) + '%';
let tipText = "Your order is free delivery";
if (diffPrice > 0) {
tipText = custom_text.replace('{amount}', `
`);
}
return `
`;
}()}
/** @private {string} */
class SpzCustomAnchorScroll extends SPZ.BaseElement {
static deferredMount() {
return false;
}
constructor(element) {
super(element);
/** @private {Element} */
this.scrollableContainer_ = null;
}
isLayoutSupported(layout) {
return layout == SPZCore.Layout.LOGIC;
}
buildCallback() {
this.viewport_ = this.getViewport();
this.initActions_();
}
setTarget(containerId, targetId) {
this.containerId = '#' + containerId;
this.targetId = '#' + targetId;
}
scrollToTarget() {
const container = document.querySelector(this.containerId);
const target = container.querySelector(this.targetId);
const {scrollTop} = container;
const eleOffsetTop = this.getOffsetTop_(target, container);
this.viewport_
.interpolateScrollIntoView_(
container,
scrollTop,
scrollTop + eleOffsetTop
);
}
initActions_() {
this.registerAction(
'scrollToTarget',
(invocation) => this.scrollToTarget(invocation?.caller)
);
this.registerAction(
'setTarget',
(invocation) => this.setTarget(invocation?.args?.containerId, invocation?.args?.targetId)
);
}
/**
* @param {Element} element
* @param {Element} container
* @return {number}
* @private
*/
getOffsetTop_(element, container) {
if (!element./*OK*/ getClientRects().length) {
return 0;
}
const rect = element./*OK*/ getBoundingClientRect();
if (rect.width || rect.height) {
return rect.top - container./*OK*/ getBoundingClientRect().top;
}
return rect.top;
}
}
SPZ.defineElement('spz-custom-anchor-scroll', SpzCustomAnchorScroll);
const STRENGTHEN_TRUST_URL = "/api/strengthen_trust/settings";
class SpzCustomStrengthenTrust extends SPZ.BaseElement {
constructor(element) {
super(element);
this.renderElement_ = null;
}
isLayoutSupported(layout) {
return layout == SPZCore.Layout.CONTAINER;
}
buildCallback() {
this.xhr_ = SPZServices.xhrFor(this.win);
const renderId = this.element.getAttribute('render-id');
SPZCore.Dom.waitForChild(
document.body,
() => !!document.getElementById(renderId),
() => {
this.renderElement_ = SPZCore.Dom.scopedQuerySelector(
document.body,
`#${renderId}`
);
if (this.renderElement_) {
this.render_();
}
this.registerAction('track', (invocation) => {
this.track_(invocation.args);
});
}
);
}
render_() {
this.fetchData_().then((data) => {
if (!data) {
return;
}
SPZ.whenApiDefined(this.renderElement_).then((apis) => {
apis?.render(data);
document.querySelector('#strengthen-trust-render-1539149753700').addEventListener('click',(event)=>{
if(event.target.nodeName == 'A'){
this.track_({type: 'trust_content_click'});
}
})
});
});
}
track_(data = {}) {
const track = window.sa && window.sa.track;
if (!track) {
return;
}
track('trust_enhancement_event', data);
}
parseJSON_(string) {
let result = {};
try {
result = JSON.parse(string);
} catch (e) {}
return result;
}
fetchData_() {
return this.xhr_
.fetchJson(STRENGTHEN_TRUST_URL)
.then((responseData) => {
if (!responseData || !responseData.data) {
return null;
}
const data = responseData.data;
const moduleSettings = (data.module_settings || []).reduce((result, moduleSetting) => {
return result.concat(Object.assign(moduleSetting, {
logos: (moduleSetting.logos || []).map((item) => {
return moduleSetting.logos_type == 'custom' ? this.parseJSON_(item) : item;
})
}));
}, []);
return Object.assign(data, {
module_settings: moduleSettings,
isEditor: window.self !== window.top,
});
});
}
}
SPZ.defineElement('spz-custom-strengthen-trust', SpzCustomStrengthenTrust);
${data.module_title}
To display this card to customers, you need to go to "Booster & Store Conversion" to turn on the trust enhancement feature.
${item.content.replaceAll("{store_name}","Mainny")}
To display this card to customers, you need to go to "Booster & Store Conversion" to turn on the trust enhancement feature.
Command armored history with this U.S. Army M60 Patton challenge coin! Featuring detailed tank engravings and Cold War insignia, it honors this legendary battle tank. A steel-clad tribute for tankers, veterans, and military collectors
Challenge Coin Size:1.96"*1.96"