23.8
(function() {
const STATUS = {
LOADING: 'loading',
FINISH: 'finish'
};
const RESULT = {
EMPTY: 'data-empty'
};
class SPZCustomCartSku extends SPZ.BaseElement {
renderData = [];
/**
* add to cart reselect item, and delete process:
* 1. record reselect id before show reselect modal
* 2. add to cart success, mark `needDeleteReselectRecord` to true
* 3. close reselect modal / drawer
* 4. spz-cart re-render, triggered mounted event
* 5. call refresh
*/
// mark delete reselect id
recordReselectId = null;
// mark should delete reselect record after spz-cart mounted event
needDeleteReselectRecord = false;
refreshLock = false;
addToCartSuccess = false;
// cache paused refresh data
refreshDataCache = [];
// cache similar products data, for manual add to cart
similarData = [];
constructor(element) {
super(element);
this.xhr_ = SPZServices.xhrFor(this.win);
this.action_ = SPZServices.actionServiceForDoc(this.element);
}
setupAction_() {
this.registerAction('refresh', (invocation) => {
const data = invocation && invocation.args && invocation.args.data || {};
this.refresh(data);
});
this.registerAction('deleteReselect', SPZCore.Types.debounce(
this.win,
(invocation) => {
this.deleteReselect(invocation?.args?.id);
},
200
));
this.registerAction('deleteInvalid', SPZCore.Types.debounce(
this.win,
(invocation) => {
this.deleteInvalid(invocation?.args?.id);
},
200
));
this.registerAction('setReselectRecordId', (invocation) => {
this.setReselectRecordId(invocation?.args?.id);
});
this.registerAction('clearNeedReselectRecord', (invocation) => {
this.clearNeedReselectRecord();
});
this.registerAction('registerDeleteReselectTask', (invocation) => {
this.registerDeleteReselectTask(invocation?.args?.data);
});
this.registerAction('lockRefresh', (invocation) => {
this.lockRefresh();
});
this.registerAction('releaseRefreshLock', (invocation) => {
this.releaseRefreshLock();
});
this.registerAction('manualAddToCart', (invocation) => {
this.manualAddToCart(invocation?.args?.id);
});
this.registerAction('syncSimilarData', (invocation) => {
this.syncSimilarData(invocation?.args?.data);
});
// DEBUG
this.registerAction('log', (invocation) => {
const data = invocation && invocation.args && invocation.args.data || {};
console.log('log', invocation);
});
}
buildCallback() {
this.setupAction_();
}
isLayoutSupported(layout) {
return true;
}
/**
* 数据去重
* @param {Array} data
*/
uniq_(data) {
const result = [];
for(let i = 0; i < data.length; i++) {
if(!result.includes(data[i])) {
result.push(data[i]);
}
}
return result;
}
checkRefreshLock() {
if (this.refreshLock) {
return false;
}
return true;
}
setLoading(isLoading) {
SPZCore.Dom.toggleAttribute(this.element, STATUS.LOADING, isLoading);
SPZCore.Dom.toggleAttribute(this.element, STATUS.FINISH, !isLoading);
}
setDataResult(data) {
const isDataEmpty = !data.reselectSkus.length && !data.invalidSkus.length && !data.line_items.length;
SPZCore.Dom.toggleAttribute(this.element, RESULT.EMPTY, isDataEmpty);
}
// 存在多次请求顺序问题
async refresh(_data) {
// 接口失败时返回数据不为对象
if ((typeof _data !== 'object' || !Array.isArray(_data.line_items))) {
const newData = {
line_items: [],
reselectSkus: [],
invalidSkus: [],
displayInvalidSkus: []
};
this.trigger_('refreshError', newData);
this.setLoading(false);
return;
}
if (!this.checkRefreshLock()) {
this.setRefreshCache(_data);
return;
}
this.setLoading(true);
let data = _data;
if (this.needDeleteReselectRecord && this.recordReselectId) {
let hasError = false;
try {
data = await this.deleteReselectRecordBeforeRefresh(_data);
} catch (e) {
hasError = true;
console.error(e);
const newData = {
...data,
reselectSkus: [],
invalidSkus: [],
displayInvalidSkus: []
};
this.trigger_('refreshError', newData);
this.setLoading(false);
this.setDataResult(newData);
return;
}
this.needDeleteReselectRecord = false;
if (hasError) {
return;
}
}
// 获取失效商品
const invisibleItems = data.ineffectives;
// 获取失效商品内仅售罄商品的sku
const soldOutItems = invisibleItems.filter(item => item.reason === "line_item_sold_out");
// 通过失效 sku 获取 spu, 注意去重
const soldOutSpuIds = this.uniq_(soldOutItems.map(item => item.product_id));
const querySpuIds = soldOutSpuIds.map(spuId => `ids[]=${spuId}`).join('&');
if (!soldOutSpuIds.length) {
const newData = {
...data,
reselectSkus: [],
invalidSkus: [],
displayInvalidSkus: []
};
this.trigger_('refreshSuccess', newData);
this.renderData = newData;
this.setLoading(false);
this.setDataResult(newData);
return;
}
// 请求 spu 下其他 sku 库存
this.xhr_.fetchJson(`/api/product/list?limit=${soldOutSpuIds.length}&${querySpuIds}`)
.then(res => {
const reselectSkus = [];
const invalidSkus = [];
// spu 维度展示
const displayInvalidSkus = [];
res.data.list.forEach(product => {
// spu 匹配, 存在多 sku 情况
const soldOutSkus = soldOutItems.filter(item => item.product_id === product.id);
if (!soldOutSkus.length) {
return;
}
// 通过失效 sku 获取 spu 下其他 sku 库存, 存在其他可用库存时标记为 "Reselect" 按钮可用
//const allowReselect = product.variants
// .filter(variant => variant.option1 === soldOutProduct.variant.option1 && variant.option2 === soldOutProduct.variant.option2 && variant.option3 === soldOutProduct.variant.option3)
// .some(variant => variant.available);
// 查询售罄 sku 对应商品是否可加购, 标记为 Reselect 可用项
if (product.available) {
reselectSkus.push(...soldOutSkus);
// 若商品不可用(全部 sku 售罄), 归纳到失效商品列表
} else {
invalidSkus.push(...soldOutSkus);
// spu 维度, 仅添加一项 sku
displayInvalidSkus.push(soldOutSkus[0]);
}
});
const newData = {
...data,
reselectSkus,
invalidSkus,
displayInvalidSkus
};
this.trigger_('refreshSuccess', newData);
this.renderData = newData;
this.setLoading(false);
this.setDataResult(newData);
})
.catch(err => {
this.setLoading(false);
console.error(err);
this.trigger_('refreshError', data);
}).finally(() => {
});
}
async deleteReselect(id, ignoreEmit) {
if (!id) {
return;
}
const targetSku = this.renderData.reselectSkus.find(item => item.id === id);
try {
const res = await this.xhr_.fetchJson(`/api/cart/${targetSku.variant_id}`, {
method: 'DELETE',
body: {
id: targetSku.id,
product_id: targetSku.product_id,
variant_id: targetSku.variant_id,
}
});
const newData = {
...this.renderData,
reselectSkus: this.renderData.reselectSkus.filter(item => item.id !== id),
};
this.renderData = newData;
!ignoreEmit && this.trigger_('deleteSuccess', newData);
} catch (err) {
console.error(err);
!ignoreEmit && this.trigger_('deleteError', err);
}
}
deleteInvalid(id) {
if (!id) {
return;
}
const targetSku = this.renderData.invalidSkus.find(item => item.id === id);
this.xhr_.fetchJson(`/api/cart/${targetSku.variant_id}`, {
method: 'DELETE',
body: {
id: targetSku.id,
product_id: targetSku.product_id,
variant_id: targetSku.variant_id,
}
})
.then(res => {
const newData = {
...this.renderData,
invalidSkus: this.renderData.invalidSkus.filter(item => item.id !== id),
displayInvalidSkus: this.renderData.displayInvalidSkus.filter(item => item.id !== id),
};
this.trigger_('deleteSuccess', newData);
this.renderData = newData;
})
.catch(err => {
console.error(err);
this.trigger_('deleteError', err);
});
}
// record reselect sku id before show reselect modal
setReselectRecordId(id) {
if (!id) {
return;
}
this.recordReselectId = id;
}
async deleteReselectRecordBeforeRefresh(data) {
if (!this.recordReselectId) {
return;
}
await this.deleteReselect(this.recordReselectId, true);
return {
...data,
ineffectives: data.ineffectives.filter(item => item.id !== this.recordReselectId)
}
}
clearNeedReselectRecord() {
this.needDeleteReselectRecord = false;
}
registerDeleteReselectTask(productData) {
const targetSku = this.renderData.reselectSkus.find(item => item.id === this.recordReselectId);
if (targetSku?.variant_id && productData?.variant.id) {
if (targetSku.variant_id === productData?.variant.id) {
this.needDeleteReselectRecord = false;
return;
}
}
this.needDeleteReselectRecord = true;
}
// pause cart refresh(trigger by similar products)
lockRefresh() {
if (this.refreshLock) {
return;
}
this.refreshLock = true;
}
releaseRefreshLock() {
if (!this.refreshLock) {
return;
}
this.refreshLock = false;
this.refreshWithCache();
}
// direct add_to_cart(trigger by similar products)
async manualAddToCart(id) {
const target = this.similarData.find(item => item.id === id);
this.lockRefresh();
try {
const res = await this.xhr_.fetchJson(`/api/cart`, {
method: 'POST',
body: {
note: '',
product_id: target.id,
quantity: '1',
variant_id: target.variants[0].id,
refer_info: {
source: 'add_to_cart'
}
}
});
const newCartItems = res.data.items;
this.setRefreshCache(newCartItems, true);
} catch (err) {
console.error(err);
}
}
syncSimilarData(data) {
this.similarData = data.data;
}
setRefreshCache(data, patch) {
if (patch) {
this.refreshDataCache = {
...this.refreshDataCache,
line_items: [...this.refreshDataCache.line_items, ...data]
};
} else {
this.refreshDataCache = data;
}
}
refreshWithCache() {
this.refresh(this.refreshDataCache);
}
mountCallback() {
}
unmountCallback() {
}
/**
* trigger event
* @param {Object} data
*/
trigger_(name, data) {
const event = SPZUtils.Event.create(this.win, `spz-custom-cart-sku.${name}`, {
data,
});
this.action_.trigger(this.element, name, event);
}
}
SPZ.defineElement('spz-custom-cart-sku', SPZCustomCartSku);
}())
(function () {
class SPZCustomCartTrack extends SPZ.BaseElement {
constructor(element) {
super(element);
this.action_ = SPZServices.actionServiceForDoc(this.element);
}
isLayoutSupported(layout) {
return true;
}
buildCallback() {
this.setupAction_();
}
hash(val) {
const hashKey = Object.keys(val).sort((a, b) => a - b).reduce((acc, k) => {
acc += `{'${k}':'${val[k]}'}`;
return acc;
}, '');
return hashKey;
}
trackExtra(key, value) {
console.log('trackExtra...', key, value);
if (!window.sa) {
return;
}
const hashKey = this.hash(value);
let hasExtraInfo = false;
if (window.sa.eventInfo && window.sa.eventInfo[key] && window.sa.eventInfo[key].extra_properties) {
hasExtraInfo = window.sa.eventInfo[key].extra_properties.some(p => {
return hashKey === this.hash(p);
});
}
if (hasExtraInfo) {
return;
}
window.sa && window.sa.registerExtraInfo(key, value);
}
delExtraTrack(key, value) {
const hashKey = this.hash(value);
if (window.sa.eventInfo && window.sa.eventInfo[key] && window.sa.eventInfo[key].extra_properties) {
window.sa.eventInfo[key].extra_properties = window.sa.eventInfo[key].extra_properties.filter(p => hashKey !== this.hash(p));
}
}
track(key, value) {
console.log('tracking...', key, value);
window.sa && window.sa.track(key, value);
}
setupAction_() {
this.registerAction('registerReselectAtc', () => {
this.trackExtra('add_to_cart', {
function_name: 'Farida',
action_type: 'reselect'
});
});
this.registerAction('clearReselectAtc', () => {
this.delExtraTrack('add_to_cart', {
function_name: 'Farida',
action_type: 'reselect'
});
});
this.registerAction('registerSimilarAtc', () => {
this.trackExtra('add_to_cart', {
function_name: 'Farida',
action_type: 'similar_product'
});
});
this.registerAction('clearSimilarAtc', () => {
this.delExtraTrack('add_to_cart', {
function_name: 'Farida',
action_type: 'similar_product'
});
});
const clickParams = {
business_type: 'product_plugin',
event_name: 'function_click',
function_name: 'Farida',
plugin_name: 'Farida',
template_name: 'cart',
template_type: '13',
module: 'online_store',
module_type: 'online_store',
tab_name: '',
card_name: '',
event_developer: 'ccbken',
event_type: 'click',
};
this.registerAction('trackDelReselect', () => {
this.track('function_click', {
...clickParams,
event_info: JSON.stringify({
action_type: 'cart_delete',
element_type: 'sku'
})
});
});
this.registerAction('trackClickReselect', () => {
this.track('function_click', {
...clickParams,
event_info: JSON.stringify({
action_type: 'reselect',
element_type: 'sku'
})
});
});
this.registerAction('trackDelSimilar', () => {
this.track('function_click', {
...clickParams,
event_info: JSON.stringify({
action_type: 'cart_delete',
element_type: 'spu'
})
});
});
this.registerAction('trackClickSimilar', () => {
this.track('function_click', {
...clickParams,
event_info: JSON.stringify({
action_type: 'reselect',
element_type: 'spu'
})
});
});
this.registerAction('trackOpenSimilar', () => {
this.track('function_expose', {
...clickParams,
event_name: 'function_expose',
event_type: 'expose',
event_info: JSON.stringify({
popup_name: 'farida_product_popup'
})
});
});
}
}
SPZ.defineElement('spz-custom-cart-track', SPZCustomCartTrack);
}())
غير صالح(${data.invalidSkus.length})
*${item.quantity}
${item.item_text}
${discount_item.title}
(- )
${item.item_text}
إعادة التحديد
إعادة تحديد مواصفات المنتج
إعادة تحديد مواصفات المنتج
سلة التسوق الخاصة بك فارغة
استمرار في التسوق
${function() {
const textArray = ("\u062d\u0641\u0638 {{save_amount}}").split(/\{\{\s*save_amount\}\}/);
if (textArray.length > 0 && textArray.length < 2) {
textArray.push('');
}
return textArray.map((text, index) => {
if (index == 0) {
return `${text} `;
}
return `
${text}
`;
}).join('');
}()}
${function() {
const textArray = ("\u062d\u0641\u0638 {{save_amount}}").split(/\{\{\s*save_amount\}\}/);
if (textArray.length > 0 && textArray.length < 2) {
textArray.push('');
}
return textArray.map((text, index) => {
if (index == 0) {
return `${text} `;
}
return `
${text}
`;
}).join('');
}()}
${discount_application.title}:
-
${data.invalid_msg}
الدفع
الشحن والضرائب ورموز الخصم المحسوبة عند الخروج.
${data.invalid_msg}
${function() {
const textArray = ("\u062d\u0641\u0638 {{save_amount}}").split(/\{\{\s*save_amount\}\}/);
if (textArray.length > 0 && textArray.length < 2) {
textArray.push('');
}
return textArray.map((text, index) => {
if (index == 0) {
return `${text} `;
}
return `
${text}
`;
}).join('');
}()}
${function() {
const textArray = ("\u062d\u0641\u0638 {{save_amount}}").split(/\{\{\s*save_amount\}\}/);
if (textArray.length > 0 && textArray.length < 2) {
textArray.push('');
}
return textArray.map((text, index) => {
if (index == 0) {
return `${text} `;
}
return `
${text}
`;
}).join('');
}()}
${function() {
const textArray = ("\u062d\u0641\u0638 {{save_amount}}").split(/\{\{\s*save_amount\}\}/);
if (textArray.length > 0 && textArray.length < 2) {
textArray.push('');
}
return textArray.map((text, index) => {
if (index == 0) {
return `${text} `;
}
return `
${text}
`;
}).join('');
}()}
${discount_application.title}:
-
الدفع
${data.invalid_msg}
الدفع
الشحن والضرائب ورموز الخصم المحسوبة عند الخروج.
الاجمالي:
تخفيض:
-
${discount_application.title}:
-
الدفع
الشحن والضرائب ورموز الخصم المحسوبة عند الخروج.
const summaryStickyRender = document.querySelector('#cart-drawer-summary-sticky-render');
if (summaryStickyRender) {
document.body.style.setProperty('--cart-drawer-summary-sticky-height', summaryStickyRender.clientHeight + 'px');
}
${function() {
const variantData = data.variant || data.product.variants.find(v => v.available) || data.product.variants[0];
const saveType = null;
const productLabelDiscountOn = null;
return `
${saveType == 'percentage'
? `-${variantData.off_ratio}%`
: `- `
}
`;
}()}
See detail
${function() {
let variantImageShowed = false;
const currentProduct = data.product;
// fix default selected variant
let selectedValues = data.selectedValues;
if (Object.keys(data.selectedValues.length === 0)) {
const selectedVariant = currentProduct.variants.find(v => v.available) || currentProduct.variants[0];
if (selectedVariant) {
selectedVariant.options.forEach((option, idx) => {
if (!selectedValues[option.name]) {
selectedValues[option.name] = [];
}
if (selectedValues[option.name].indexOf(option.value) === -1) {
selectedValues[option.name].push(option.value);
}
});
}
}
return (currentProduct.options || []).map((option, index) => {
const optionName = option.name || '';
const position = `option${index + 1}`;
let isThumbImage = false;
if (currentProduct.need_variant_image && !variantImageShowed) {
const variantNames = ["color"] || [];
for (let i = 0, len = variantNames.length; i < len; i++) {
const name = variantNames[i].toLowerCase();
if (name === optionName.toLowerCase()) {
isThumbImage = true;
variantImageShowed = true;
}
}
}
const variantType = "button";
const thumbStyle = "image_with_text";
return `
${optionName}:
${option.values.map((value, idx) => {
const selected = data.selectedValues[optionName] == value ? 'checked' : '';
let thumbImage = null;
if (isThumbImage) {
const variants = currentProduct.variants;
for (let i = 0, len = variants.length; i < len; i++) {
const variant = variants[i];
if (variant[position] == value && thumbImage == null) {
thumbImage = variant.image;
break;
}
}
}
return `
${value}
`
}).join('')}
${optionName}
${option.values.map(value => {
const selected = data.selectedValues[optionName] == value ? 'selected' : '';
return `${value} `
}).join('')}
`
}).join('');
}()}
${data.originData && data.originData.value || data.value}
${data.index + 1}/${data.total}
${Array(data.total).fill(0).map((num, index) => {
return ` `;
}).join('')}
${function(){
const wholesale_enabled = false;
const qty = data.quantity || 1;
const currentSelectVariant = data.variant;
const defaultVariant = (data.product && data.product.variants && data.product.variants[0]);
const productVariant = {"id":"3c5d5684-2a79-4775-a4fa-2b35e5844afb","product_id":"fac73765-8aa6-437d-9c9d-b2324df539fb","title":"17''","weight_unit":"kg","inventory_quantity":9995,"sku":"17''A0226300","barcode":"","position":1,"option1":"17''","option2":"","option3":"","note":"","image":null,"wholesale_price":[{"price":16,"min_quantity":1}],"weight":"0","compare_at_price":"177","price":"16","retail_price":"177","available":true,"url":"\/ar\/products\/round-cut-graduated-fine-necklace-jn39?variant=3c5d5684-2a79-4775-a4fa-2b35e5844afb","available_quantity":9995,"options":[{"name":"Chain Length","value":"17''"}],"off_ratio":91,"flashsale_info":[],"sales":670};
const variantData = currentSelectVariant || defaultVariant || productVariant;
const wholesale_price = variantData.wholesale_price || [];
if(wholesale_enabled && wholesale_price.length > 0) {
let wholesaleIndex = wholesale_price.findIndex(item => {
return item.min_quantity > qty;
});
if(wholesaleIndex < 0){
wholesaleIndex = wholesale_price.length - 1;
}else if(wholesaleIndex > 0){
wholesaleIndex = wholesaleIndex - 1;
}
const wholesalePrice = wholesale_price[wholesaleIndex] || '';
return `
`
}else {
const price = variantData && variantData.price;
return price != undefined ? `
` : ' ';
}
}()}
${function() {
const selectedVariant = data.variant;
const isSoldOut = ((selectedVariant && !selectedVariant.available) || (!selectedVariant && !productData.available));
const statusLan = isSoldOut ?
"\u0646\u0641\u0630\u062a \u0627\u0644\u0643\u0645\u064a\u0647 " :
"\u0623\u0636\u0641 \u0625\u0644\u0649 \u0627\u0644\u0633\u0644\u0629";
return `
${statusLan}
`;
}()}
const summaryStickyRender = document.querySelector('#cart-reselect-drawer-summary-sticky-render');
if (summaryStickyRender) {
document.body.style.setProperty('--cart-reselect-drawer-summary-sticky-height', summaryStickyRender.clientHeight + 'px');
}
${function(){
const productData = data.product;
let product_change_event = '',
mouse_over_event = ' ';
mouse_out_event = '';
const product_options = productData.options.filter(Boolean) || [];
for (let opt of product_options) {
product_change_event = product_change_event + `cart-reselect-drawer-selected-variant-${opt.name}.rerender(data=event.selectedValues.${opt.name});`;
mouse_out_event = mouse_out_event + `cart-reselect-drawer-selected-variant-${opt.name}.rerender(data=event.selectData.${opt.name});`;
mouse_over_event = mouse_over_event + `@${opt.name}Mouseover="cart-reselect-drawer-selected-variant-${opt.name}.rerender(data=event);"`;
}
const selectedVariant = productData.variants.find(v => v.available) || productData.variants[0];
const statusLan = ((selectedVariant && !selectedVariant.available) || (!selectedVariant && !productData.available)) ?
"\u0646\u0641\u0630\u062a \u0627\u0644\u0643\u0645\u064a\u0647 " :
"\u0623\u0636\u0641 \u0625\u0644\u0649 \u0627\u0644\u0633\u0644\u0629";
const mobSelectedVariant = productData.variants.find(v => v.available) || productData.variants[0];
const mobInitialSlideIndex = productData.images.findIndex((item) => item.src === selectedVariant.image.src);
const mobImages = productData.images;
const mobImageSize = productData.images.length;
const stickyEvent = "cart-reselect-drawer-summary-sticky-render.toggleClass(class='visible', force=false);cart-reselect-drawer-summary-sticky-compensation-container.toggleClass(class='visible', force=false);cart-reselect-drawer-observer.restart();cart-reselect-drawer-summary-sticky-render.rerender(data=event);";
return `
${function() {
const force_image_size = 'natural';
const thumbnailPosition = 'below';
const selectedVariant = data.product.variants.find(v => v.available) || data.product.variants[0];
const initialSlideIndex = data.product.images.findIndex((item) => item.src === selectedVariant.image.src);
const images = data.product.images;
const imageSize = data.product.images.length;
return `
${data.product.images.map((item, index0) => {
const extra = index0 === initialSlideIndex ? 'ssr size-ratio="2"' : '';
return `
`;
}).join('')}
${imageSize > 1 ? `
${images.map((index1) => {
return ` `;
}).join('')}
` : ''}
${imageSize > 1 ? `
${images.map((imageItem, index1) => {
const extra2 = initialSlideIndex == index1 ? 'selected' : '';
return`
`;
}).join('')}
` : ''}`;
}()}
`;
}()}
${function(){
const currentSelectVariant = data.variant;
const defaultVariant = (data.product && data.product.variants && data.product.variants[0]);
const variantData = currentSelectVariant || defaultVariant || data;
const retail_price = variantData.retail_price || 0;
return `
`
}()}
${function(){
const wholesale_enabled = false;
const qty = data.quantity || 1;
const currentSelectVariant = data.variant;
const defaultVariant = (data.product && data.product.variants && data.product.variants[0]);
const productVariant = {"id":"3c5d5684-2a79-4775-a4fa-2b35e5844afb","product_id":"fac73765-8aa6-437d-9c9d-b2324df539fb","title":"17''","weight_unit":"kg","inventory_quantity":9995,"sku":"17''A0226300","barcode":"","position":1,"option1":"17''","option2":"","option3":"","note":"","image":null,"wholesale_price":[{"price":16,"min_quantity":1}],"weight":"0","compare_at_price":"177","price":"16","retail_price":"177","available":true,"url":"\/ar\/products\/round-cut-graduated-fine-necklace-jn39?variant=3c5d5684-2a79-4775-a4fa-2b35e5844afb","available_quantity":9995,"options":[{"name":"Chain Length","value":"17''"}],"off_ratio":91,"flashsale_info":[],"sales":670};
const variantData = currentSelectVariant || defaultVariant || productVariant;
const wholesale_price = variantData.wholesale_price || [];
if(wholesale_enabled && wholesale_price.length > 0) {
let wholesaleIndex = wholesale_price.findIndex(item => {
return item.min_quantity > qty;
});
if(wholesaleIndex < 0){
wholesaleIndex = wholesale_price.length - 1;
}else if(wholesaleIndex > 0){
wholesaleIndex = wholesaleIndex - 1;
}
const wholesalePrice = wholesale_price[wholesaleIndex] || '';
return `
`
}else {
const price = variantData && variantData.price;
return price != undefined ? `
` : ' ';
}
}()}
${(function(){
const get_random_six_digits = () => {
return Math.random().toString().slice(-6)
};
const wholesale_enabled = false;
const setting_product_image_display = "133.33%";
const product_image = data.image;
const secondary_image = data.secondImage;
const image_width = product_image.width;
let image_height = product_image.height;
if(setting_product_image_display == '100%'){
image_height = image_width;
}else if(setting_product_image_display == '133.33%'){
image_height = image_width * 1.3333;
};
let product_image_hover_on = false;
const has_save_label = true && ((+data.compare_at_price) > (+data.price));
const is_single_variant = data.variants.length == 1;
const min_price_variant_href = (data.min_price_variant && data.min_price_variant.available) ? data.min_price_variant.withinUrl : data.withinUrl;
const retail_price_max = data.retail_price_max || data.compare_at_price_max;
const THUMBNAILS_MAX_SIZE = 3;
const thumbnails = data.thumbVariants.slice(0, THUMBNAILS_MAX_SIZE);
const image_wrap_id = 'image_wrap_' + get_random_six_digits();
const image_carousel_id = 'image_carousel_' + get_random_six_digits();
const thumbnails_selector_id = 'thumbnails_selector_' + get_random_six_digits();
const form_id = 'form_' + get_random_six_digits();
const mixed_wholesale = data.mixed_wholesale;
let atc_handler = '';
if (data.has_only_default_variant) {
atc_handler = `custom-cart-drawer-sku.manualAddToCart(id=${data.id});add-card-toast-success.showToast(content='اضيف بنجاح');`;
} else {
atc_handler = `cart-invalid-drawer-quick-shop-render.render(src='/ar/api/products/${data.id}',redo=true);cart-invalid-product-detail-drawer.open();`;
}
return `
`
})()}
${function() {
const isEmpty = data && data.length === 0;
if (isEmpty) {
return ``;
}
return ``;
}()}
${Array(data.total).fill(0).map((num, index) => {
return ` `;
}).join('')}
${function() {
let variantImageShowed = false;
const currentProduct = data.product;
// fix default selected variant
let selectedValues = data.selectedValues;
if (Object.keys(data.selectedValues.length === 0)) {
const selectedVariant = currentProduct.variants.find(v => v.available) || currentProduct.variants[0];
if (selectedVariant) {
selectedVariant.options.forEach((option, idx) => {
if (!selectedValues[option.name]) {
selectedValues[option.name] = [];
}
if (selectedValues[option.name].indexOf(option.value) === -1) {
selectedValues[option.name].push(option.value);
}
});
}
}
return (currentProduct.options || []).map((option, index) => {
const optionName = option.name || '';
const position = `option${index + 1}`;
let isThumbImage = false;
if (currentProduct.need_variant_image && !variantImageShowed) {
const variantNames = ["color"] || [];
for (let i = 0, len = variantNames.length; i < len; i++) {
const name = variantNames[i].toLowerCase();
if (name === optionName.toLowerCase()) {
isThumbImage = true;
variantImageShowed = true;
}
}
}
const variantType = "button";
const thumbStyle = "image_with_text";
return `
${optionName}:
${option.values.map((value, idx) => {
const selected = data.selectedValues[optionName] == value ? 'checked' : '';
let thumbImage = null;
if (isThumbImage) {
const variants = currentProduct.variants;
for (let i = 0, len = variants.length; i < len; i++) {
const variant = variants[i];
if (variant[position] == value && thumbImage == null) {
thumbImage = variant.image;
break;
}
}
}
return `
${value}
`
}).join('')}
${optionName}
${option.values.map(value => {
const selected = data.selectedValues[optionName] == value ? 'selected' : '';
return `${value} `
}).join('')}
`
}).join('');
}()}
${data.originData && data.originData.value || data.value}
${function() {
const variantData = data.variant || data.product.variants.find(v => v.available) || data.product.variants[0];
const saveType = "amount";
const productLabelDiscountOn = true;
return `
${saveType == 'percentage'
? `-${variantData.off_ratio}%`
: `- `
}
`;
}()}
See detail
${function(){
const currentSelectVariant = data.variant;
const defaultVariant = (data.product && data.product.variants && data.product.variants[0]);
const variantData = currentSelectVariant || defaultVariant || data;
const retail_price = variantData.retail_price || 0;
return `
`
}()}
${function(){
const wholesale_enabled = false;
const qty = data.quantity || 1;
const currentSelectVariant = data.variant;
const defaultVariant = (data.product && data.product.variants && data.product.variants[0]);
const productVariant = {"id":"3c5d5684-2a79-4775-a4fa-2b35e5844afb","product_id":"fac73765-8aa6-437d-9c9d-b2324df539fb","title":"17''","weight_unit":"kg","inventory_quantity":9995,"sku":"17''A0226300","barcode":"","position":1,"option1":"17''","option2":"","option3":"","note":"","image":null,"wholesale_price":[{"price":16,"min_quantity":1}],"weight":"0","compare_at_price":"177","price":"16","retail_price":"177","available":true,"url":"\/ar\/products\/round-cut-graduated-fine-necklace-jn39?variant=3c5d5684-2a79-4775-a4fa-2b35e5844afb","available_quantity":9995,"options":[{"name":"Chain Length","value":"17''"}],"off_ratio":91,"flashsale_info":[],"sales":670};
const variantData = currentSelectVariant || defaultVariant || productVariant;
const wholesale_price = variantData.wholesale_price || [];
if(wholesale_enabled && wholesale_price.length > 0) {
let wholesaleIndex = wholesale_price.findIndex(item => {
return item.min_quantity > qty;
});
if(wholesaleIndex < 0){
wholesaleIndex = wholesale_price.length - 1;
}else if(wholesaleIndex > 0){
wholesaleIndex = wholesaleIndex - 1;
}
const wholesalePrice = wholesale_price[wholesaleIndex] || '';
return `
`
}else {
const price = variantData && variantData.price;
return price != undefined ? `
` : ' ';
}
}()}
${function(){
const wholesale_enabled = false;
const qty = data.quantity || 1;
const currentSelectVariant = data.variant;
const defaultVariant = (data.product && data.product.variants && data.product.variants[0]);
const productVariant = {"id":"3c5d5684-2a79-4775-a4fa-2b35e5844afb","product_id":"fac73765-8aa6-437d-9c9d-b2324df539fb","title":"17''","weight_unit":"kg","inventory_quantity":9995,"sku":"17''A0226300","barcode":"","position":1,"option1":"17''","option2":"","option3":"","note":"","image":null,"wholesale_price":[{"price":16,"min_quantity":1}],"weight":"0","compare_at_price":"177","price":"16","retail_price":"177","available":true,"url":"\/ar\/products\/round-cut-graduated-fine-necklace-jn39?variant=3c5d5684-2a79-4775-a4fa-2b35e5844afb","available_quantity":9995,"options":[{"name":"Chain Length","value":"17''"}],"off_ratio":91,"flashsale_info":[],"sales":670};
const variantData = currentSelectVariant || defaultVariant || productVariant;
const wholesale_price = variantData.wholesale_price || [];
if(wholesale_enabled && wholesale_price.length > 0) {
let wholesaleIndex = wholesale_price.findIndex(item => {
return item.min_quantity > qty;
});
if(wholesaleIndex < 0){
wholesaleIndex = wholesale_price.length - 1;
}else if(wholesaleIndex > 0){
wholesaleIndex = wholesaleIndex - 1;
}
const wholesalePrice = wholesale_price[wholesaleIndex] || '';
return `
`
}else {
const price = variantData && variantData.price;
return price != undefined ? `
` : ' ';
}
}()}
${function() {
const selectedVariant = data.variant;
const isSoldOut = ((selectedVariant && !selectedVariant.available) || (!selectedVariant && !productData.available));
const statusLan = isSoldOut ?
"\u0646\u0641\u0630\u062a \u0627\u0644\u0643\u0645\u064a\u0647 " :
"\u0623\u0636\u0641 \u0625\u0644\u0649 \u0627\u0644\u0633\u0644\u0629";
return `
${statusLan}
`;
}()}
const summaryStickyRender = document.querySelector('#cart-invalid-drawer-quick-shop-summary-sticky-render');
if (summaryStickyRender) {
document.body.style.setProperty('--cart-product-drawer-summary-sticky-height', summaryStickyRender.clientHeight + 'px');
}
${function() {
const variantData = data.variant || data.product.variants.find(v => v.available) || data.product.variants[0];
const saveType = "amount";
const productLabelDiscountOn = true;
return `
${saveType == 'percentage'
? `-${variantData.off_ratio}%`
: `- `
}
`;
}()}
See detail
${function(){
const productData = data.product;
let product_change_event = '',
mouse_over_event = ' ',
mouse_out_event = '';
const product_options = productData.options.filter(Boolean) || [];
for (let opt of product_options) {
product_change_event = product_change_event + `cart-invalid-drawer-quick-shop-selected-variant-${opt.name}.rerender(data=event.selectedValues.${opt.name});`;
mouse_out_event = mouse_out_event + `cart-invalid-drawer-quick-shop-selected-variant-${opt.name}.rerender(data=event.selectData.${opt.name});`;
mouse_over_event = mouse_over_event + `@${opt.name}Mouseover="cart-invalid-drawer-quick-shop-selected-variant-${opt.name}.rerender(data=event);"`;
}
const selectedVariant = productData.variants.find(v => v.available) || productData.variants[0];
const statusLan = ((selectedVariant && !selectedVariant.available) || (!selectedVariant && !productData.available)) ?
"\u0646\u0641\u0630\u062a \u0627\u0644\u0643\u0645\u064a\u0647 " :
"\u0623\u0636\u0641 \u0625\u0644\u0649 \u0627\u0644\u0633\u0644\u0629";
const mobSelectedVariant = productData.variants.find(v => v.available) || productData.variants[0];
const mobInitialSlideIndex = productData.images.findIndex((item) => item.src === selectedVariant.image.src);
const mobImages = productData.images;
const mobImageSize = productData.images.length;
const stickyEvent = "cart-invalid-drawer-quick-shop-summary-sticky-render.toggleClass(class='visible', force=false);cart-invalid-drawer-quick-shop-summary-sticky-compensation-container.toggleClass(class='visible', force=false);cart-invalid-drawer-quick-shop-observer.restart();cart-invalid-drawer-quick-shop-summary-sticky-render.rerender(data=event);";
return `
${function() {
const force_image_size = 'natural';
const thumbnailPosition = 'below';
const selectedVariant = data.product.variants.find(v => v.available) || data.product.variants[0];
let initialSlideIndex = data.product.images.findIndex((item) => item.src === selectedVariant.image.src);
if (initialSlideIndex === -1) {
initialSlideIndex = 0;
}
const images = data.product.images;
const imageSize = data.product.images.length;
console.log('cart-product-drawer product images render', data, selectedVariant, initialSlideIndex, images, imageSize);
return `
${images.map((item, index0) => {
const extra = index0 === initialSlideIndex ? 'ssr size-ratio="2"' : '';
return `
`;
}).join('')}
${imageSize > 1 ? `
${images.map((index1) => {
return ` `;
}).join('')}
` : ''}
${imageSize > 1 ? `
${images.map((imageItem, index1) => {
const extra2 = initialSlideIndex == index1 ? 'selected' : '';
return`
`;
}).join('')}
` : ''}`;
}()}
`;
}()}
${function(){
const productData = data.product;
let product_change_event = '',
mouse_over_event = ' ';
mouse_out_event = '';
const product_options = productData.options.filter(Boolean) || [];
for (let opt of product_options) {
product_change_event = product_change_event + `quick-shop-selected-variant-${opt.name}.rerender(data=event.selectedValues.${opt.name});`;
mouse_out_event = mouse_out_event + `quick-shop-selected-variant-${opt.name}.rerender(data=event.selectData.${opt.name});`;
mouse_over_event = mouse_over_event + `@${opt.name}Mouseover="quick-shop-selected-variant-${opt.name}.rerender(data=event);"`;
}
const selectedVariant = productData.variants.find(v => v.available) || productData.variants[0];
const statusLan = ((selectedVariant && !selectedVariant.available) || (!selectedVariant && !productData.available)) ?
"\u0646\u0641\u0630\u062a \u0627\u0644\u0643\u0645\u064a\u0647 " :
"\u0623\u0636\u0641 \u0625\u0644\u0649 \u0627\u0644\u0633\u0644\u0629";
return `
`
}()}
${function(){
const currentSelectVariant = data.variant;
const defaultVariant = (data.product && data.product.variants && data.product.variants[0]);
const variantData = currentSelectVariant || defaultVariant || data;
const retail_price = variantData.retail_price || 0;
return `
`
}()}
${function(){
const wholesale_enabled = false;
const qty = data.quantity || 1;
const currentSelectVariant = data.variant;
const defaultVariant = (data.product && data.product.variants && data.product.variants[0]);
const productVariant = {"id":"3c5d5684-2a79-4775-a4fa-2b35e5844afb","product_id":"fac73765-8aa6-437d-9c9d-b2324df539fb","title":"17''","weight_unit":"kg","inventory_quantity":9995,"sku":"17''A0226300","barcode":"","position":1,"option1":"17''","option2":"","option3":"","note":"","image":null,"wholesale_price":[{"price":16,"min_quantity":1}],"weight":"0","compare_at_price":"177","price":"16","retail_price":"177","available":true,"url":"\/ar\/products\/round-cut-graduated-fine-necklace-jn39?variant=3c5d5684-2a79-4775-a4fa-2b35e5844afb","available_quantity":9995,"options":[{"name":"Chain Length","value":"17''"}],"off_ratio":91,"flashsale_info":[],"sales":670};
const variantData = currentSelectVariant || defaultVariant || productVariant;
const wholesale_price = variantData.wholesale_price || [];
if(wholesale_enabled && wholesale_price.length > 0) {
let wholesaleIndex = wholesale_price.findIndex(item => {
return item.min_quantity > qty;
});
if(wholesaleIndex < 0){
wholesaleIndex = wholesale_price.length - 1;
}else if(wholesaleIndex > 0){
wholesaleIndex = wholesaleIndex - 1;
}
const wholesalePrice = wholesale_price[wholesaleIndex] || '';
return `
`
}else {
const price = variantData && variantData.price;
return price != undefined ? `
` : ' ';
}
}()}
${function() {
let variantImageShowed = false;
const currentProduct = data.product;
return (currentProduct.options || []).map((option, index) => {
const optionName = option.name || '';
const position = `option${index + 1}`;
let isThumbImage = false;
if (currentProduct.need_variant_image && !variantImageShowed) {
const variantNames = ["color"] || [];
for (let i = 0, len = variantNames.length; i < len; i++) {
const name = variantNames[i].toLowerCase();
if (name === optionName.toLowerCase()) {
isThumbImage = true;
variantImageShowed = true;
}
}
}
const variantType = "button";
const thumbStyle = "image_with_text";
return `
${optionName}:
${option.values.map((value, idx) => {
const selected = data.selectedValues[optionName] == value ? 'checked' : '';
let thumbImage = null;
if (isThumbImage) {
const variants = currentProduct.variants;
for (let i = 0, len = variants.length; i < len; i++) {
const variant = variants[i];
if (variant[position] == value && thumbImage == null) {
thumbImage = variant.image;
break;
}
}
}
return `
${value}
`
}).join('')}
${optionName}
${option.values.map(value => {
const selected = data.selectedValues[optionName] == value ? 'selected' : '';
return `${value} `
}).join('')}
`
}).join('');
}()}
${data.originData && data.originData.value || data.value}