(async () => {
const container = document.querySelector('[data-app="shiprocket-smart-cart"]');
const shadowRoot = container.shadowRoot;
const MODE = "PROD"; //Acceptable Values = PROD || CHECKOUT-DEV || FASTRR-DEV
const getAPIEndpoints = (mode) => {
switch (mode) {
case "PROD":
return {
AGGREGATOR: "https://edge.pickrr.com/aggregator/api/ve1/aggregator-service",
PROMOTION: "https://edge.pickrr.com/promotion/api/ve1/promotion-service"
}
case "CHECKOUT-DEV":
return {
AGGREGATOR: "https://api-dev.pickrr.com/api/ve1/aggregator-service",
PROMOTION: "https://edge-service-dev.pickrr.com/promotion/api/ve1/promotion-service"
}
case "FASTRR-DEV":
return {
AGGREGATOR: "https://api-testing.pickrr.com/api/ve1/aggregator-service",
PROMOTION: "https://edge-service-dev.pickrr.com/promotion-fastrr/api/ve1/promotion-service"
}
default:
return {}
}
}
const ENV = getAPIEndpoints(MODE);
{/** HELPERS */}
const isDeepEqual = (value, other) => {
if (value === other) {
return true;
}
if (value == null || other == null || typeof value !== 'object' || typeof other !== 'object') {
return value !== value && other !== other; // NaN comparison
}
if (value.constructor !== other.constructor) {
return false;
}
if (value instanceof Date) {
return value.getTime() === other.getTime();
}
if (value instanceof RegExp) {
return value.toString() === other.toString();
}
if (Array.isArray(value)) {
if (value.length !== other.length) {
return false;
}
for (let i = 0; i < value.length; i++) {
if (!isDeepEqual(value[i], other[i])) {
return false;
}
}
return true;
}
// Compare properties
const keys = Object.keys(value);
if (keys.length !== Object.keys(other).length) {
return false;
}
for (const key of keys) {
if (!isDeepEqual(value[key], other[key])) {
return false;
}
}
return true;
}
const localStorageManager = {
localStorageAvailable: (function () {
try {
const testKey = `__test__${Math.random()}`;
localStorage.setItem(testKey, testKey);
localStorage.removeItem(testKey);
return true;
} catch (e) {
return false;
}
})(),
get: function (key) {
if (this.localStorageAvailable) {
return localStorage.getItem(key);
} else {
return null;
}
},
set: function (key, value) {
if (this.localStorageAvailable) {
localStorage.setItem(key, value);
}
},
remove: function (key) {
if (this.localStorageAvailable) {
localStorage.removeItem(key);
}
}
}
//remove coupon/freebie upon reload - for now
localStorageManager?.remove('fastrrCouponCode');
localStorageManager.remove('srCartSelectedFreebies');
// stores
let MILESTONE_DATA = [];
let MAX_VALUE;
let MILESTONE_VALUES;
let COUPONS_DATA = {}
let CURRENT_CART_SUMMARY = {};
let CURRENT_CART_ITEMS = {};
let CURRENT_FREEBIE_ITEMS = [];
let SELECTED_FREEBIES = [];
let SELECTED_FREEBIES_VARIANT_IDS = [];
let CURRENT_UPSELL_ITEMS = [];
let APPLIED_COUPON_DATA = null;
let CURRENT_THEME_CONFIG = {};
//UI flags/consts
let maxFreebieItemsForSelection = 0;
let isMilstoneAdded = false;
let isEnterCodeClicked = false;
let sellerId = null;
let isCouponDrawerOpen = false;
let isFreebieDrawerOpen = false;
let isOrderSummaryOpen = false;
let isFreebieSelection = false;
let currentActiveCouponDetails = null;
let showConfetti = true;
var showCouponBox = true;
let isThemeConfigPainted = false;
const progressSectionStickySeller = ["thedeconstruct.in", "www.trynooky.in"]?.includes(window.location.host);
const freebiesOnBottom = ["thedeconstruct.in"]?.includes(window.location.host);
const saveCurrentFreebiesToLS = ["thedeconstruct.in", "fastrr-checkout.myshopify.com"]?.includes(window.location.host);
//upsell
let currentVariant = {};
let currentVariantCombination = {};
let currentMultiVariantProduct = {}
let variantOutOfStockList = [];
let isUpsellVariantDrawerOpen = false;
//cart note
let currentNote = window?.shiprocketSmartCart?.currentCart?.note ?? "";
let isNoteDrawerOpen = false;
//global
window.shiprocketCartPriceCache = {};
window.srcSuggestedItemsExist = false;
window.srShowConfetti = false;
window.miniCartButtonloader = false;
//image URLS
const arrowIcon = "https://pickrr.s3.amazonaws.com:443/2025-07-28T06:04:01.669652_arrow.png";
const discount_image_url = `https://fastrr-boost-ui.pickrr.com/assets/images/svg/discount_icon.svg`;
const defaultAchievedMilestoneImage = "https://pickrr.s3.amazonaws.com:443/2025-08-01T06:57:59.706663_party_icon_colored.png";
const defaultMilestoneImage = "https://pickrr.s3.amazonaws.com:443/2025-08-01T06:27:20.558528_party_icon_outline.png";
const ACHIEVED_MILESTONE_IMAGES = {
SHIPPING:'https://pickrr.s3.amazonaws.com:443/2025-08-01T06:58:16.372817_free_shipping_colored.png',
FREEBIE: 'https://pickrr.s3.amazonaws.com:443/2025-08-01T06:58:38.040674_free_gift_colored.png',
}
const MILESTONE_IMAGES = {
SHIPPING:'https://pickrr.s3.amazonaws.com:443/2025-08-01T06:28:17.923048_free_shipping_outline.png',
FREEBIE: 'https://pickrr.s3.amazonaws.com:443/2025-08-01T06:28:39.652998_free_gift_outline.png',
}
// Default configurations
const DEFAULT_CONFIG = {
headerUiConfig: {
headerText: 'Shipping Cart',
headerTextColor: '#031222',
headerTextFontSize: '18px',
headerColor: '#ffffff',
headerTextAlignment: 'center',
headerIconColor: 'green'
},
buyNowButtonUIConfig: {
buttonSticker: 'Place Order',
backgroundColor: 'black',
borderColor: 'white',
textColor: 'white',
width: '100%',
height: '48px',
cornerRadius: '4px',
fontSize: '14px',
fontWeight: 'bold',
fontStyle: 'normal',
enableSticker: false,
stickerColor: '#FF4D4F',
stickerBgColor: '#FF4D4F',
stickerWidth: '100%',
sticketheight: null,
stickerText: '',
stickerCornerRadius: '8px',
enableSrLogo: false,
logoTheme: 'light'
},
cartUiConfig: {
themeColor: 'green',
overallBgColor: '#ffffff',
milestoneHeaderText: '',
upsellHeaderText: 'Similar Items You Might Also Like',
showDiscount: true,
showConfetti: true
},
bannerDetails: {
showBanner: false,
type: 'single',
text: '',
textColor: '#000000',
backgroundColor: '#ffffff',
fontWeight: 'normal',
fontSize: '14px',
subType: 'carousel',
carouselSlides: [],
carouselDuration: 3000 // 3 seconds per slide
}
};
const enrichCartWithCompareAtPrices = async (cartItems) => {
for (const item of cartItems) {
const variantId = item.variant_id;
const cartItemId = item.id;
// If not already cached, fetch variant data
if (!window.shiprocketCartPriceCache[variantId]) {
try {
const variantData = await fetch(`/variants/${variantId}.js`).then(res => res.json());
const price = variantData.price;
const compare = variantData.compare_at_price;
// Calculate discount %
let percent = 0;
if (compare && compare > price) {
percent = Math.round(((compare - price) / compare) * 100);
}
// Store in cache
window.shiprocketCartPriceCache[variantId] = {
price,
compare_at_price: compare,
percent_diff: percent
};
} catch (err) {
console.error('Failed to fetch variant', variantId, err);
continue;
}
}
// Now inject into DOM
const { compare_at_price, price, percent_diff } = window.shiprocketCartPriceCache[variantId];
if (compare_at_price > price) {
const container = shadowRoot.getElementById(`sr-cart-item-${cartItemId}`);
if (container && !container.querySelector('.sr-cart-cut-out-price')) {
const compareEl = document.createElement('div');
compareEl.className = 'sr-cart-cut-out-price';
compareEl.textContent = `₹${(compare_at_price / 100)?.toFixed(0)}`;
const percentEl = document.createElement('div');
percentEl.className = 'sr-cart-percent-discount-text';
percentEl.textContent = `${percent_diff}% off`;
container.appendChild(compareEl);
container.appendChild(percentEl);
}
}
}
}
const handleCompactModeOnMobile = () => {
try {
const style = document.createElement('style');
style.textContent = `
@media only screen and (max-width: 767px) {
#mini-cart-drawer {
width: 95% !important;
}
}
`;
shadowRoot.appendChild(style);
} catch (e) {}
}
const showConfettiHandler = () => {
if(showConfetti) {
confetti({
particleCount: 120,
spread: 70,
origin: getDimensions(),
zIndex: 999999999999999,
});
}
}
const filteredItemsForCouponsAPI = (items) => {
try {
const filteredItems = items?.map((item) => {
return {
qty: item.quantity,
price: (item.price)/100,
subTotal: (item.original_line_price)/100,
productId: item.product_id,
variantId: item.id,
customAttributes: item.properties
}
})
return filteredItems;
} catch (e) {
return []
}
}
const filteredItemsForCheckoutLinkAPI = (items) => {
try {
const filteredItems = items?.map((item) => {
return {
quantity: item.quantity,
price: (item.price)/100,
productId: item.product_id,
itemId: item.id,
customAttributes: item.properties
}
})
const currentFreebiesArray = isFreebieSelection ? SELECTED_FREEBIES : CURRENT_FREEBIE_ITEMS;
const freebieItems = currentFreebiesArray.map((freebie) => {
return {
quantity: 1,
price: freebie.price,
itemId: freebie.variantId,
productId: freebie.productId,
customAttributes: {
freebie: true
}
}
})
return [...filteredItems, ...freebieItems];
} catch (e) {
return []
}
}
const getDimensions = () => {
const getMiniCartDrawerDemensions = shadowRoot.querySelector("#mini-cart-drawer").getBoundingClientRect();
const x = (getMiniCartDrawerDemensions.left + getMiniCartDrawerDemensions.width / 2) / window.innerWidth;
const y = (getMiniCartDrawerDemensions.top + getMiniCartDrawerDemensions.height / 2) / window.innerHeight;
return {x, y}
}
const hideById = (id) => {
try {
shadowRoot.getElementById(id).classList.add("hidden")
} catch (e) {}
}
const unHideById = (id) => {
try {
shadowRoot.getElementById(id).classList.remove("hidden")
} catch (e) {}
}
window.showLoader = () => {
try {
shadowRoot.querySelector('.sr-mini-cart-full-page-loader').style.display = "flex";
} catch (e) {}
}
window.hideLoader = () => {
try {
shadowRoot.querySelector('.sr-mini-cart-full-page-loader').style.display = "none";
} catch (e) {}
}
const rotate180 = (id) => {
try {
shadowRoot.getElementById(id)?.classList.toggle('sr-cart-rotate-180')
} catch (error) {}
}
window.toggleCouponDrawer = () => {
try {
const drawer = shadowRoot.getElementById('sr-cart-coupons-drawer')
drawer.classList.toggle('active');
isCouponDrawerOpen = !isCouponDrawerOpen;
} catch (e) {}
}
window.toggleFreebieDrawer = () => {
try {
const drawer = shadowRoot.getElementById('sr-cart-freebies-drawer')
drawer.classList.toggle('active');
isFreebieDrawerOpen = !isFreebieDrawerOpen;
} catch (e) {}
}
window.toggleSmartCartOrderSummary = () => {
try {
const orderSummaryDrawer = shadowRoot.getElementById('sr-cart-order-summary-drawer');
orderSummaryDrawer.classList.toggle('active');
rotate180('order-total-arrow')
isOrderSummaryOpen = !isOrderSummaryOpen
} catch (e) {}
}
window.toggleSmartCartUpsellDrawer = () => {
try {
const upsellVariantDrawer = shadowRoot.getElementById('sr-cart-upsell-variant-drawer');
upsellVariantDrawer.classList.toggle('active');
isUpsellVariantDrawerOpen = !isUpsellVariantDrawerOpen
} catch (e) {}
}
window.toggleSmartCartNoteDrawer = () => {
try {
const noteDrawer = shadowRoot.getElementById('sr-cart-note-drawer');
noteDrawer.classList.toggle('active');
isNoteDrawerOpen = !isNoteDrawerOpen
} catch (e) {}
}
window.showSRSCToast = (message, duration = 3000) => {
const toastContainer = shadowRoot.getElementById('sr-cart-toast');
toastContainer.innerText = message;
//show
setTimeout(() => {
toastContainer.classList.add('active');
}, 100);
//hide
setTimeout(() => {
toastContainer.classList.remove('active');
}, duration);
}
const handleDiscounts = (data) => {
try {
const automaticCoupons = data?.couponsData?.couponList?.filter((discount) => discount?.discount_type?.toUpperCase() === "AUTOMATIC");
const manualCoupon = data?.couponsData?.couponList?.filter((discount) => discount?.discount_type?.toUpperCase() === "DISCOUNT")?.[0];
if(manualCoupon?.discount_amount > 0) {
//this happens upon cart modifications like +- of quantity
isSameCouponApplied = APPLIED_COUPON_DATA?.discount_code?.toUpperCase() === manualCoupon?.discount_code?.toUpperCase() ? true : false;
APPLIED_COUPON_DATA = manualCoupon;
handleSuccessfullCoupon(isSameCouponApplied)
}
//manualliy coupon applied but no discount amount
if (!manualCoupon?.discount_amount && data?.manuallyApplied) {
const error = data?.couponsData?.validationErrorMsgs?.[0] ?? "Please enter a valid coupon code."
handleInvalidCoupon(error)
}
//coupon already existed and re-tried on amount/item/etc change but unsuccessful
if (!manualCoupon?.discount_amount && APPLIED_COUPON_DATA) {
handleInvalidCoupon()
}
//paint automatic coupons
const automaticCouponContainer = shadowRoot.querySelector('.coupon_container');
let htmlContent = '';
if(automaticCoupons?.length > 0) {
automaticCouponContainer.innerHTML = "";
automaticCoupons.forEach(coupon => {
if (coupon.discount_amount > 0) {
htmlContent += `
Auto discount(${coupon.discount_code})
-₹${coupon.discount_amount.toFixed(2)}
`;
}
});
automaticCouponContainer.innerHTML += htmlContent;
} else {
htmlContent = ``;
automaticCouponContainer.innerHTML = "";
automaticCouponContainer.innerHTML = htmlContent;
}
} catch (e) {}
}
window.hideShiprocketSmartCartDrawers = () => {
try {
if(isUpsellVariantDrawerOpen) {
window.toggleSmartCartUpsellDrawer();
}
if(isCouponDrawerOpen) {
window.toggleCouponDrawer();
}
if(isNoteDrawerOpen) {
window.toggleSmartCartNoteDrawer();
}
if(isFreebieDrawerOpen) {
window.toggleFreebieDrawer();
}
if(isOrderSummaryOpen) {
window.toggleSmartCartOrderSummary()
}
} catch (e) {}
}
const updateHeaderQuantity = () => {
try {
const headerQuantityContainer = shadowRoot.getElementById('sr-cart-header-quantity');
//also update cart bubble icon quantity
const cartBubbleQuantityContainer = document.querySelector('#cart-icon-bubble .cart-count-bubble');
const cartIconContainer = document.getElementById('cart-icon-bubble');
const mainItemsQuantity = CURRENT_CART_ITEMS.reduce((sum, item) => sum + item.quantity, 0);
const freebieQuantity = isFreebieSelection ? SELECTED_FREEBIES?.length : CURRENT_FREEBIE_ITEMS?.length
const totalQuantity = mainItemsQuantity > 0 ? (mainItemsQuantity + freebieQuantity) : 0;
headerQuantityContainer.innerText = `(${totalQuantity})`;
if(cartBubbleQuantityContainer) {
cartBubbleQuantityContainer.innerText = totalQuantity
} else if(cartIconContainer && totalQuantity > 0) {
const cartIconContainer = document.getElementById('cart-icon-bubble');
const cartBubble = document.createElement('div');
cartBubble.className = "cart-count-bubble";
cartBubble.innerHTML = `${totalQuantity}`
cartIconContainer.appendChild(cartBubble)
}
} catch (e) { }
}
const sendCXToNativeCheckout = () => {
window.location.href = '/checkout';
hideLoader();
}
//APIS
const handleCheckoutLinkFlow = async () => {
try {
const payload = {
items: filteredItemsForCheckoutLinkAPI(CURRENT_CART_ITEMS),
sellerId: sellerId,
...(localStorageManager.get('fastrrCouponCode') && {couponCode: localStorageManager.get('fastrrCouponCode')}),
};
let response = await fetch(`${ENV.AGGREGATOR}/smartcart/storefrontUrl`, {
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
method: "POST",
body: JSON.stringify(payload),
});
if(!response.ok) {
throw new Error('Checkout link creation failed.')
}
response = await response?.json();
if(response.storefrontUrl) {
window.location.href = response.storefrontUrl
hideLoader();
} else {
sendCXToNativeCheckout();
}
//send cx to checkout link
} catch (e) {
sendCXToNativeCheckout()
}
}
window.handleShiprocketSmartCartBuy = () => {
try {
showLoader();
if(window.checkoutBuyer) { //if checkout enabled
shiprocketCheckoutEvents.buyCart(event, {source: "SRSC"})
hideLoader();
} else if(!sellerId) {
sendCXToNativeCheckout();
} else {
handleCheckoutLinkFlow();
}
} catch (e) {}
}
{/** NOTE HANDLER */}
window.editSmartCartNoteHandler = () => {
try {
const input = shadowRoot.getElementById('sr-cart-note-text-field');
const inputAction = shadowRoot.getElementById('sr-cart-note-save-button');
if(input.value?.trim() === "") {
inputAction.setAttribute('disabled', 'true');
} else {
inputAction.removeAttribute('disabled');
}
} catch (e) {}
}
window.handleAddNoteToCart = async (type) => {
try {
showLoader();
let noteToUpdate = "";
const input = shadowRoot.getElementById('sr-cart-note-text-field');
if(type === "ADD") {
noteToUpdate = input.value;
}
let response = await fetch('/cart/update.js', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
body: JSON.stringify({
note: noteToUpdate
})
})
if(!response.ok) {
showSRSCToast('Failed to update note.')
}
response = await response.json();
if(response) {
currentNote = response.note
paintNoteSection();
}
if(currentNote?.trim() === "") {
input.value = ""
}
if(isNoteDrawerOpen) {
window.toggleSmartCartNoteDrawer();
}
hideLoader();
} catch (e) {
hideLoader();
}
}
async function fetchData(cartItems, uiConfig, cartId, couponCode = "") {
try {
const itemsPayload = cartItems?.map((item) => {
return {
itemId: item?.variant_id,
price: item?.price / 100,
quantity: item?.quantity,
productId: item?.product_id
};
});
const finalPayload = {
cart_id: cartId,
domain_name: window.location.host,
require_mini_cart_config: true,
minicart_items_list: itemsPayload,
...(SELECTED_FREEBIES?.length > 0 && {selected_freebie_items: SELECTED_FREEBIES}),
coupon_code: (couponCode || APPLIED_COUPON_DATA?.discount_code)
};
const url =
`${ENV.AGGREGATOR}/mini-cart/`;
const response = await fetch(url, {
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
method: "POST",
body: JSON.stringify(finalPayload),
});
if (!response.ok) {
shadowRoot
.querySelector(".mini-card-sr-loader")
.setAttribute("style", "display: none !important;");
miniCartButtonloader = false;
throw new Error(`HTTP error! status: ${response}`);
}
const data = await response.json();
return data;
} catch (error) {
shadowRoot
.querySelector(".mini-card-sr-loader")
.setAttribute("style", "display: none !important;");
}
}
{/** UPSELL - START */}
const paintVariantDrawer = (data) => {
try {
const variantContentContainer = shadowRoot.getElementById('sr-upsell-variant-content');
const markup =
`
${currentVariant?.name}
${currentVariant.compareAtPrice > currentVariant.price
? `₹${currentVariant.compareAtPrice}`
: ''
}
₹${currentVariant.price}
${currentVariant.compareAtPrice > currentVariant.price
? `
${
((currentVariant.compareAtPrice - currentVariant.price) / currentVariant.compareAtPrice) * 100 > 10
? `${(((currentVariant.compareAtPrice - currentVariant.price) / currentVariant.compareAtPrice) * 100).toFixed(0)}% off`
: `Save ₹${currentVariant.compareAtPrice - currentVariant.price}`
}
`
: ''
}
${currentMultiVariantProduct?.variants?.length > 1
?
(currentMultiVariantProduct?.variants?.[0]?.options?.map(variantOption => {
return `
Select ${variantOption.name} :
${variantOption.values.map(option => {
const isOutOfStock = variantOutOfStockList?.includes(option);
const isSelected = option === currentVariantCombination?.[variantOption.name] && !isOutOfStock;
return `
${option}
`;
}).join('')}
`;
})).join('')
:
[]
.join('')}
`;
variantContentContainer.innerHTML = markup;
if(!isUpsellVariantDrawerOpen) {
window.toggleSmartCartUpsellDrawer();
}
// Attach event listeners to options
const variantOptions = shadowRoot.querySelectorAll(".variant-option-box");
variantOptions.forEach((button) => {
button.addEventListener("click", () => {
const isOutOfStock = button.getAttribute("data-option-stock")
if(isOutOfStock === "true") {
return
}
const optionName = button.getAttribute("data-option-name");
const optionValue = button.getAttribute("data-option-value");
handleUpsellItemChange({
type: "VARIANT_CHANGE",
variantChangeDetail: {
[optionName]: optionValue
}
})
});
});
//Attach listener to add to cart button
const ATC = shadowRoot.getElementById('variant-ATC-button')
ATC.addEventListener("click", () => {
handleUpsellClick({
variantId: currentVariant?.variantId
})
})
} catch (e) {}
}
const handleUpsellItemChange = (data) => {
try {
if(data?.type === "PRODUCT_CHANGE") {
currentVariant = data?.product?.variants?.[0]
currentMultiVariantProduct = data?.product
currentVariantCombination = currentVariant?.variantTypes
}
if(data?.type === "VARIANT_CHANGE") {
//Modify current variant combination here
currentVariantCombination = {
...currentVariantCombination,
...data?.variantChangeDetail
}
for (let i = 0; i < currentMultiVariantProduct?.variants?.length; i++) {
if (isDeepEqual(currentVariantCombination, currentMultiVariantProduct?.variants?.[i]?.variantTypes)) {
currentVariant = currentMultiVariantProduct?.variants?.[i];
break;
}
}
}
let stockOutObject = []
let selectedKey = [];
for (let key in currentVariantCombination) {
selectedKey.push(key);
}
for (let key in currentVariantCombination) {
currentMultiVariantProduct?.variants.forEach((variant) => {
if ((currentVariantCombination[key]?.toString()?.toLowerCase() === variant?.variantTypes[key]?.toString()?.toLowerCase()) || Object?.keys(currentVariantCombination)?.length === 1) {
if (variant?.qty <= 0) {
const data = Object?.keys(currentVariantCombination)?.length === 1 ? selectedKey : selectedKey?.filter((item) => item !== key);
data?.forEach((key) => {
stockOutObject.push(variant?.variantTypes[key])
})
}
}
})
}
const uniqueArray = stockOutObject?.filter((value, index, self) => {
return self.indexOf(value) === index;
});
variantOutOfStockList = uniqueArray;
paintVariantDrawer();
} catch (e) {}
}
async function handleUpsellClick(data) {
try {
// if multiple variants then paint variant drawer or view-info true
if(data?.hasVariants === "true" || data?.viewInfo) {
const product = CURRENT_UPSELL_ITEMS?.[data?.productIndex]
handleUpsellItemChange({
type: "PRODUCT_CHANGE",
product: product
})
return
}
showLoader();
const response = await fetch("/cart/add.js", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
id: data?.variantId,
quantity: 1,
properties: {
srsc_upsell_item: true
}
}),
});
hideLoader();
if (response.ok) {
const data = await response.json();
updateMiniCartSection();
if(isUpsellVariantDrawerOpen) {
window.toggleSmartCartUpsellDrawer();
}
showSRSCToast(`1 item added to cart successfully.`)
} else {}
} catch (error) {
hideLoader();
}
}
window.loadSimilarItems = function (initialItems, cartUiConfig) {
const productIdsWithStock = new Set();
const items = initialItems.filter(product => {
const variants = product?.variants || [];
const hasStock = variants.some(variant => variant?.qty > 0);
if (!hasStock)
{
return false;
}
if (productIdsWithStock?.has(product?.productId)) {
return false;
}
productIdsWithStock?.add(product?.productId);
return true;
});
CURRENT_UPSELL_ITEMS = items;
const similarItemsWrapper = shadowRoot.querySelector("#similar-item-wrapper");
const heading = shadowRoot.querySelector(".similar-item-heading");
heading.innerText = cartUiConfig?.upsellHeaderText ? cartUiConfig?.upsellHeaderText : 'Similar Items You Might Also Like';
if (items && items?.length) {
unHideById('similar-items-container');
heading.style.display = "block";
} else {
heading.style.display = "none";
similarItemsWrapper.innerHTML = "";
hideById('similar-items-container');
return
}
const upsellItems =
items &&
items
?.map(
(product, index) => {
const initialItemToShow = product?.variants?.length > 0 ? product?.variants?.[0] : product;
const numberOfVariants = product?.variants?.length;
const hasMultipleVariants = numberOfVariants > 1;
const buttonLabel = hasMultipleVariants
? `+${numberOfVariants - 1} ${numberOfVariants === 2 ? "option" : "options"}`
: "+ Add";
return (
`
${initialItemToShow.name}
`
+
(
initialItemToShow.compareAtPrice > initialItemToShow.price ?
`
₹${Number(initialItemToShow?.compareAtPrice?.toFixed(2))}` :
""
)
+
`
₹${initialItemToShow.price}`
+
(
initialItemToShow.compareAtPrice > initialItemToShow.price ?
`
${((Number(((initialItemToShow.compareAtPrice - initialItemToShow.price) / initialItemToShow.compareAtPrice)) * 100) > 10) ?
`${(Number(((initialItemToShow.compareAtPrice - initialItemToShow.price) / initialItemToShow.compareAtPrice)) * 100).toFixed(0)}% off` :
`Save ₹${initialItemToShow.compareAtPrice - initialItemToShow.price}`
}
` :
""
)
+
`
`)
}
)
.join("");
similarItemsWrapper.innerHTML = upsellItems;
const addToCartButtons = shadowRoot.querySelectorAll(".sr-upsell-item-action");
const upsellImageWrappers = shadowRoot.querySelectorAll(".sr-upsell-image-wrapper");
function attachUpsellHandler(element) {
element.addEventListener("click", () => {
const variantId = element.getAttribute("data-variant-id");
const hasVariants = element.getAttribute("data-has-multiple-variants");
const productIndex = element.getAttribute("data-product-index");
const viewInfo = element.getAttribute("data-view-info");
handleUpsellClick({
variantId,
hasVariants,
productIndex,
viewInfo
});
});
}
addToCartButtons.forEach(attachUpsellHandler);
upsellImageWrappers.forEach(attachUpsellHandler);
};
{/** UPSELL - END */}
// milestion section
function loadMilestones(milestoneData, cartUiConfig) {
try{
// progressbar Container
const progressBarContainerShopify = shadowRoot.getElementById(
"mini-cart-progress-section"
);
if(milestoneData?.length === 0) {
progressBarContainerShopify.innerHTML = ""
isMilstoneAdded = false;
return
}
// MILESTONE_VALUES = milestoneData?.map((m) => m.thresh_hold_value);
MILESTONE_VALUES = milestoneData
.map(m => Number(m.thresh_hold_value))
.filter(v => !isNaN(v));
MAX_VALUE = Math.max(...MILESTONE_VALUES);
// if (!progressBarContainerShopify) {
// shadowRoot.querySelector(".mini-card-sr-loader").setAttribute("style", "display: none !important;");
// return;
// }
progressBarContainerShopify.style.display = "block";
progressBarContainerShopify.style.position = "relative"
progressBarContainerShopify.style.zIndex = 1;
// elements created
const heading = document.createElement("div");
const subHeading = document.createElement("div");
const progressBarContainer = document.createElement("div");
const milestonesContainer = document.createElement("div");
const optionalMilestonesContainer = document.createElement("div");
const progressBar = document.createElement("div");
const progress = document.createElement("div");
const hr = document.createElement("hr");
// added class and id to the elements
progressBarContainer.className = "progress-container";
milestonesContainer.className = "milestones";
optionalMilestonesContainer.className = "milestones-optional";
progressBar.className = "progress-bar";
heading.className = "progress-bar-heading";
subHeading.className = "progress-bar-sub-heading";
progress.className = "progress";
progress.id = "progress";
hr.className = "mini-cart-divider";
// progress bar appended
progressBar.appendChild(progress);
//progressBarContainer.appendChild(progressBar);
//IMP: Keep progress bar tied to primary milestones container
milestonesContainer.appendChild(progressBar);
//primary milestones creator
milestoneData?.forEach((milestone, index) => {
const width = (milestone.thresh_hold_value / MAX_VALUE) * 100;
const milestoneDiv = document.createElement("div");
milestoneDiv.className = "milestone";
milestoneDiv.style.left = `${Math.min(100, width)}%`;
// Create the dot div
const dotDiv = document.createElement("div");
dotDiv.className = "milestone-dot";
dotDiv.setAttribute("data-discount-type", milestone?.discount_type);
// Create the text div
const textDiv = document.createElement("div");
textDiv.className = "milestone-text";
textDiv.innerHTML = `${
milestone.text ?? ""
}`;
// have to also change here
// if (index == 0) {
// milestoneDiv.classList.add("flex-start-column");
// textDiv.classList.add("text-left");
// }
// if (milestoneData?.length - 1 == index) {
// milestoneDiv.classList.add("last-milestone");
// // textDiv.classList.add("text-right");
// textDiv.classList.add("milestone_last_text");
// }
// Append dot and text to milestone
milestoneDiv.appendChild(dotDiv);
milestoneDiv.appendChild(textDiv);
//Append milestone to the container
milestonesContainer.appendChild(milestoneDiv);
});
{/** TODO */}
//Condition if any milestone contains text2
if(false) {
milestoneData?.forEach((milestone, index) => {
const width = (milestone.thresh_hold_value / MAX_VALUE) * 100;
const milestoneDiv = document.createElement("div");
milestoneDiv.className = "milestone-optional";
milestoneDiv.style.left = `${Math.min(100, width)}%`;
// Create the text div
const textDiv = document.createElement("div");
textDiv.className = "milestone-text-optional";
textDiv.innerHTML = `${
milestone.text2
}`;
milestoneDiv.appendChild(textDiv);
//Append milestone to the container
optionalMilestonesContainer.appendChild(milestoneDiv);
});
progressBarContainer.appendChild(optionalMilestonesContainer)
}
heading.innerHTML = cartUiConfig?.milestoneHeaderText ? cartUiConfig?.milestoneHeaderText : "";
subHeading.innerHTML = `You are ${0} away from free shipping`;
progressBarContainer.appendChild(milestonesContainer);
progressBarContainerShopify.appendChild(heading);
progressBarContainerShopify.appendChild(subHeading);
progressBarContainerShopify.appendChild(progressBarContainer);
//progressBarContainerShopify.appendChild(hr);
isMilstoneAdded = true;
if(shadowRoot.querySelector(".mini-card-sr-loader")){
shadowRoot.querySelector(".mini-card-sr-loader").setAttribute("style", "display: none !important;")
}
}catch(error){
if(shadowRoot.querySelector(".mini-card-sr-loader")){
shadowRoot.querySelector(".mini-card-sr-loader").setAttribute("style", "display: none !important;")
}
alert('mileston create error', error)
}
}
const unLockAmountToNearest = (
values,
target,
index,
isAllMilestonesAchieved
) => {
try {
const PROGRESS_BAR_HEADING = shadowRoot.querySelector(
".progress-bar-sub-heading"
);
const NEXT_MILESTONE_VALUE =
values[index + 1] - target > 0
? Math.round(values[index + 1] - target)
: 0;
const NEXT_MILESTONE_TEXT = MILESTONE_DATA?.[index + 1]?.text;
if (!isAllMilestonesAchieved) {
shadowRoot.querySelector(
".progress-bar-sub-heading"
).innerHTML = `You are ₹${NEXT_MILESTONE_VALUE} away from ${NEXT_MILESTONE_TEXT}`;
} else {
PROGRESS_BAR_HEADING.innerHTML = `Congrats you got ${
MILESTONE_DATA[MILESTONE_DATA.length - 1]?.text
}`;
}
} catch (error) {
PROGRESS_BAR_HEADING.innerHTML = `Something went wrong please update your cart`;
}
};
function updateProgressBar(value) {
try {
const progress = shadowRoot.getElementById("progress");
const milestones = shadowRoot.querySelectorAll(".milestone");
const milestoneDots = shadowRoot.querySelectorAll(".milestone-dot");
// Segmented progress logic for dynamic milestones
let segmentIndex = 0;
for (let i = 1; i < MILESTONE_VALUES?.length; i++) {
if (value < MILESTONE_VALUES[i]) {
segmentIndex = i - 1;
break;
}
segmentIndex = i;
}
const start = MILESTONE_VALUES?.[segmentIndex];
const end = MILESTONE_VALUES?.[segmentIndex + 1] || MILESTONE_VALUES?.[MILESTONE_VALUES?.length - 1];
let segmentProgress = 0;
if (end > start) {
segmentProgress = (value - start) / (end - start);
segmentProgress = Math.max(0, Math.min(1, segmentProgress));
}
const totalSegments = MILESTONE_VALUES?.length - 1;
let widthPercent = ((segmentIndex + segmentProgress) / totalSegments) * 100;
// Clamp width to just before the next milestone if not reached
if (value < end) {
const nextMilestonePercent = ((segmentIndex + 1) / totalSegments) * 100;
widthPercent = Math.min(widthPercent, nextMilestonePercent - 5); // 1% epsilon
}
if(progress) {
progress.style.width = `${Math.min(100, widthPercent)}%`;
}
let isAllMilestonesAchieved = false;
milestones?.forEach((milestone, index) => {
if (value >= MILESTONE_VALUES?.[index]) {
if(index !==0){
const imageUrl = ACHIEVED_MILESTONE_IMAGES?.[milestoneDots[index]?.dataset?.discountType] ?? defaultAchievedMilestoneImage;
milestoneDots[index].classList.remove("greyscale");
milestoneDots[index].innerHTML = `
`
if (milestones.length - 1 == index) {
isAllMilestonesAchieved = true;
} else {
isAllMilestonesAchieved = false;
}
}
unLockAmountToNearest(
MILESTONE_VALUES,
value,
index,
isAllMilestonesAchieved
);
if (!milestone.dataset.confettiShown && window.srShowConfetti) {
showConfettiHandler();
milestone.dataset.confettiShown = true;
}
} else {
const imageUrl = MILESTONE_IMAGES?.[milestoneDots[index]?.dataset?.discountType] ?? defaultMilestoneImage
milestone.classList.remove("active");
milestoneDots[index].classList.remove("active");
if(index !== 0) {
milestoneDots[index].classList.add("greyscale");
}
if(index !== 0) {
milestoneDots[index].innerHTML = `
`
}
isAllMilestonesAchieved = false;
delete milestone.dataset.confettiShown;
}
});
} catch (error) {}
}
// mileston end
function updateSummary(summary) {
try{
if(!summary){
console.error("updateSummary: summary data is missing rizwan");
return;
}
// selectors
const subTotal = shadowRoot.querySelector(".sr-sub-total");
const shipping = shadowRoot.querySelector(".shipping");
const total = shadowRoot.querySelector(".total-price");
//cut-out price shown along with total in sticky summary
const originalPrice = shadowRoot.querySelector(".summary-original-price");
//discount code check
const appliedCoupon = APPLIED_COUPON_DATA;
const couponDiscount = appliedCoupon?.discount_amount > 0 ? appliedCoupon?.discount_amount : 0;
const totalAmountAfterCoupon = ((summary?.total) ?? 0)
const subTotalAmount = summary?.subTotal ?? 0
//set inner text/html
total.innerHTML = `₹${Number(totalAmountAfterCoupon?.toFixed(2))}`
subTotal.innerHTML = `₹${Number(subTotalAmount?.toFixed(2))}`
if(subTotalAmount > totalAmountAfterCoupon) {
originalPrice.innerHTML = `₹${Number(subTotalAmount?.toFixed(2))}`
originalPrice.style.display = "block";
} else {
originalPrice.style.display = "none";
}
// const discount = shadowRoot.querySelector(".sr-discount");
// const discountWrapper = shadowRoot.querySelector(".discount_wrapper");
// const discountCode = shadowRoot.querySelector(".discount-code");
//DISCOUNT CODE SECTION
const discountCodeContainer = shadowRoot.querySelector(".sr-cart-discount-code-container");
//coupon discount
if(appliedCoupon) {
const discountCodeHTML = `
Coupon Code(${appliedCoupon?.discount_code})
-₹${appliedCoupon?.discount_amount}
`
discountCodeContainer.innerHTML = discountCodeHTML;
} else {
discountCodeContainer.innerHTML = ``;
}
// updating values
// discount.innerHTML = `₹${summary?.discount?.toFixed(2) ?? 0}`;
// summary?.discountType === "Percentage Discount"
// ? `${summary?.discount?.toFixed(2) ?? 0}%`
// : `₹${summary?.discount?.toFixed(2) ?? 0}`;
// if (summary?.discountName) {
// shadowRoot.querySelector(
// ".discount-code"
// ).textContent = `Discount (${summary?.discountName})`;
// } else {
// shadowRoot.querySelector(".discount-code").textContent = "Discount";
// }
} catch(error) {}
}
function createMiniCartItem(itemData) {
try{
const itemContainer = document.createElement("div");
itemContainer.className = "mini-cart-item freebie_item";
// itemContainer.className = '';
const flexWrapper = document.createElement("div");
flexWrapper.style.display = "flex";
const img = document.createElement("img");
img.src = itemData?.imgUrl; // Replace with actual image URL
img.alt = itemData?.name; // Replace with actual product title
img.className = "sr-cart-item-image";
const detailsContainer = document.createElement("div");
detailsContainer.className = "mini-cart-item-details";
const title = document.createElement("div");
title.className = "mini-cart-item-title";
title.innerHTML = `${itemData?.name}`;
const variant = document.createElement("div");
variant.className = "mini-cart-item-variant";
//push variant title and freebie image to diff containers later
variant.innerText = (itemData?.variantTitle && itemData?.variantTitle !== "Default Title") ? `${itemData?.variantTitle}` : "";
const freebiePriceContainer = document.createElement('div');
freebiePriceContainer.className = "freebie-price-container"
freebiePriceContainer.innerHTML = `
`
const price = document.createElement("div");
price.className = "mini-cart-item-price";
if(itemData?.compareAtPrice > 0 || itemData?.price > 0) {
price.innerHTML = `₹${ itemData?.compareAtPrice || itemData?.price } ₹0`; // Replace with actual price
}
freebiePriceContainer.prepend(price)
detailsContainer.appendChild(title);
detailsContainer.appendChild(variant);
detailsContainer.appendChild(freebiePriceContainer);
const imageContainer = document.createElement('div');
imageContainer.className = "sr-cart-item-image-container";
imageContainer.appendChild(img);
flexWrapper.appendChild(imageContainer);
flexWrapper.appendChild(detailsContainer);
//const controlsWrapper = document.createElement("div");
//controlsWrapper.className = "min-cart-item-controll-wrapper";
//controlsWrapper.appendChild(price);
itemContainer.appendChild(flexWrapper);
//itemContainer.appendChild(controlsWrapper);
return itemContainer;
} catch(error){}
}
function paintFreebiesUI(items) {
try{
const freebiesUIContainer = freebiesOnBottom ? shadowRoot.getElementById("free-item-container-bottom") : shadowRoot.getElementById("free-item-container");
freebiesUIContainer.innerHTML = "";
if (freebiesUIContainer) {
items.forEach((item) => {
const miniCartItem = createMiniCartItem(item);
freebiesUIContainer.appendChild(miniCartItem);
});
} else {
}} catch (error) {}
}
function themeConfig(themeUiConfig, headerUiConfig, buttonUiConfig){
try {
const MINI_CART_HEADER = shadowRoot.querySelector('.mini-cart-header');
const MINI_CART_TITLE = shadowRoot.querySelector('.mini-cart-title');
const MINI_CART_TITLE_FLEX = shadowRoot.querySelector('.mini-cart-title-flex');
const MINI_CART_PROGRESS_BAR = shadowRoot.querySelector('.progress-bar');
const MINI_CART_PROGRES_SECTION = shadowRoot.getElementById('mini-cart-progress-section');
const BUY_NOW_BUTTON = shadowRoot.querySelector('#sr-buy-now-button')
const BUY_NOW_BUTTON_TEXT = shadowRoot.querySelector('#sr-buy-now-btn-text')
const BUY_NOW_BUTTON_PAYMENT_ICONS = shadowRoot.querySelector('#sr-cart-payment-icon')
// Merge configurations with defaults
const headerConfig = {...headerUiConfig };
const buttonConfig = {...buttonUiConfig };
const themeConfig = {...themeUiConfig };
//set globally for access
// Hide coupons if showDiscount is false
showCouponBox = (themeConfig.hasOwnProperty('showDiscount') && !themeConfig.showDiscount) ? false : true;
showConfetti = themeConfig.showConfetti ?? true;
// Set overall background color
// Apply header styles
MINI_CART_HEADER.style.backgroundColor = headerConfig.headerColor || DEFAULT_CONFIG.headerUiConfig.headerColor;
MINI_CART_TITLE.textContent = headerConfig.headerText || DEFAULT_CONFIG.headerUiConfig.headerText;
MINI_CART_TITLE.style.color = headerConfig.headerTextColor || DEFAULT_CONFIG.headerUiConfig.headerTextColor;
MINI_CART_TITLE.style.fontSize = headerConfig.headerTextFontSize || DEFAULT_CONFIG.headerUiConfig.headerTextFontSize;
MINI_CART_TITLE_FLEX.style.justifyContent = headerConfig.headerTextAlignment;
// Apply button styles
BUY_NOW_BUTTON_TEXT.textContent = buttonConfig?.buttonSticker || DEFAULT_CONFIG.buyNowButtonUIConfig.buttonSticker;
BUY_NOW_BUTTON.style.backgroundColor = buttonConfig?.backgroundColor || DEFAULT_CONFIG.buyNowButtonUIConfig.backgroundColor;
if(buttonConfig?.borderColor ){
BUY_NOW_BUTTON.style.border = `1px solid ${buttonConfig?.borderColor}`;
}
BUY_NOW_BUTTON.style.width = buttonConfig?.width || DEFAULT_CONFIG.buyNowButtonUIConfig.width;
BUY_NOW_BUTTON.style.height = buttonConfig?.height || DEFAULT_CONFIG.buyNowButtonUIConfig.height;
BUY_NOW_BUTTON.style.borderRadius = buttonConfig?.cornerRadius || DEFAULT_CONFIG.buyNowButtonUIConfig.cornerRadius;
BUY_NOW_BUTTON.style.fontSize = buttonConfig?.fontSize || DEFAULT_CONFIG.buyNowButtonUIConfig.fontSize;
BUY_NOW_BUTTON.style.fontWeight = buttonConfig?.fontStyle || DEFAULT_CONFIG.buyNowButtonUIConfig.fontStyle;
BUY_NOW_BUTTON.style.color = buttonConfig?.textColor || DEFAULT_CONFIG.buyNowButtonUIConfig.textColor;
if(buttonConfig.ctaPaymentIcons) {
BUY_NOW_BUTTON_PAYMENT_ICONS.style.display = "block"
}
// Apply sticker if enabled
if(buttonConfig.enableSticker){
const checkoutSticker = shadowRoot.getElementById('checkout-sticker');
checkoutSticker.style.backgroundColor = buttonConfig?.stickerColor || DEFAULT_CONFIG.buyNowButtonUIConfig.stickerBgColor;
checkoutSticker.style.color = buttonConfig?.stickerTextColor || DEFAULT_CONFIG.buyNowButtonUIConfig.stickerColor;
checkoutSticker.style.borderRadius = buttonConfig?.stickerCornerRadius || DEFAULT_CONFIG.buyNowButtonUIConfig.stickerCornerRadius;
// checkoutSticker.style.width = buttonConfig.stickerWidth || DEFAULT_CONFIG.buyNowButtonUIConfig.stickerWidth;
checkoutSticker.style.height = buttonConfig?.sticketheight || DEFAULT_CONFIG.buyNowButtonUIConfig.sticketheight;
checkoutSticker.innerHTML = buttonConfig?.stickerText || DEFAULT_CONFIG.buyNowButtonUIConfig.stickerText;
}
// Apply logo if enabled
if(buttonConfig.enableSrLogo){
const srPoweredBy = shadowRoot.getElementById('sr-powered-by');
srPoweredBy.style.display = 'block'
if( buttonConfig.logoTheme === 'Dark'){
srPoweredBy.style.filter = 'invert(1)'
}
}
//progress section
if(MINI_CART_PROGRESS_BAR && themeConfig?.progressBarGradient && themeConfig?.progressBarBgColour){
MINI_CART_PROGRESS_BAR.style.background = `linear-gradient(to right, ${themeConfig?.progressBarBgColour},#FFF)`;
}
if(MINI_CART_PROGRES_SECTION && themeConfig?.progressSectionBgGradient && themeConfig?.progressSectionBgColor){
MINI_CART_PROGRES_SECTION.style.background = `linear-gradient(to left, ${themeConfig?.progressSectionBgColor},#FFF)`;
}
// Set CSS variables
shadowRoot.host.style.setProperty('--sr-mini-cart-primary-color', themeConfig.themeColor || DEFAULT_CONFIG.cartUiConfig.themeColor);
shadowRoot.host.style.setProperty('--sr-mini-cart-header-icon-color', headerConfig.headerIconColor || DEFAULT_CONFIG.headerUiConfig.headerIconColor);
shadowRoot.host.style.setProperty('--sr-mini-cart-header-text-color', headerConfig.headerTextColor || DEFAULT_CONFIG.headerUiConfig.headerTextColor);
if(themeConfig.progressBarBgColour && !themeConfig.progressBarGradient){
shadowRoot.host.style.setProperty('--sr-progress-bar-bg-color', themeConfig.progressBarBgColour);
}
if(themeConfig.progressSectionBgColor && !themeConfig.progressSectionBgGradient){
shadowRoot.host.style.setProperty('--sr-progress-section-bg-color', themeConfig.progressSectionBgColor);
}
if(themeConfig.overallBgColor){
shadowRoot.host.style.setProperty('--sr-overall-bg-color', themeConfig.overallBgColor);
}
if(themeConfig.showShippingCharges) {
unHideById('sr-cart-shipping-charges-container');
}
if(themeConfig.compactOnMobile) {
handleCompactModeOnMobile();
}
if(progressSectionStickySeller) {
MINI_CART_PROGRES_SECTION.style.position = "sticky";
MINI_CART_PROGRES_SECTION.style.top = 0;
}
} catch(error) {}
}
//COUPONS
window.handleViewMoreCouponClick = () => {
toggleCouponDrawer();
}
window.handleEnterCodeClick = () => {
isEnterCodeClicked = true;
unHideById("sr-cart-coupon-input")
hideById("sr-cart-enter-code")
unHideById("sr-cart-enter-code-divider")
}
window.couponApplyHandler = (inputId) => {
const couponCode = shadowRoot.getElementById(inputId).value;
if(couponCode) {
applyCoupon(couponCode)
} else {}
}
window.removeCouponHandler = () => {
localStorageManager.remove('fastrrCouponCode');
APPLIED_COUPON_DATA = null;
applyCoupon("")
}
window.handleCouponInputChange = (inputId, inputActionId) => {
try {
const input = shadowRoot.getElementById(inputId);
const inputAction = shadowRoot.getElementById(inputActionId);
if(input.value === "") {
inputAction.classList.add('disabled')
} else {
inputAction.classList.remove('disabled')
}
} catch (e) {}
}
window.handleCouponViewDetails = (couponIndex) => {
try {
const couponViewDetailsSection = `sr-coupon-details-${couponIndex}`;
const couponDownwardArrow = `sr-coupon-downward-icon-${couponIndex}`;
if(currentActiveCouponDetails === couponIndex) {
currentActiveCouponDetails = null;
hideById(couponViewDetailsSection);
rotate180(couponDownwardArrow);
} else {
//hide any active details
if(currentActiveCouponDetails) {
hideById(`sr-coupon-details-${currentActiveCouponDetails}`)
rotate180(`sr-coupon-downward-icon-${currentActiveCouponDetails}`)
}
currentActiveCouponDetails = couponIndex;
unHideById(couponViewDetailsSection);
rotate180(couponDownwardArrow);
}
} catch(e) {}
}
const getCouponInputHTML = (data = {}) => {
const isDrawer = data?.isDrawer;
const isHidden = COUPONS_DATA?.highlighted_coupon && !isEnterCodeClicked && !isDrawer ? "hidden" : "";
const uniqueInputId = `sr-cart-coupon-input-${Math.random()}`
const uniqueInputActionId = `sr-cart-coupon-input-action-${Math.random()}`
const inputClass = isDrawer ? "drawer" : "main"
return (
`
`
)
}
const getHighlightedCouponHTML = () => {
const coupon = COUPONS_DATA?.highlighted_coupon
return (
`

Save ₹${coupon?.amount}
${coupon?.code}
`
)
}
const getOtherCouponsHTML = (isSingleApplicableCoupon) => {
const totalCoupons = COUPONS_DATA?.all_coupons?.length;
return (
`
${isSingleApplicableCoupon ? `` : `${totalCoupons} more offer(s) available`}
`
)
}
const getCouponErrorHTML = (type) => {
return (
`
Please enter a valid coupon code
`
)
}
const getAppliedCouponHTML = () => {
const appliedCoupon = APPLIED_COUPON_DATA;
return (
`
${appliedCoupon?.discount_code}
Saved ₹${appliedCoupon?.discount_amount}
Remove
`
)
}
const getApplicableCouponsHTML = () => {
const applicableCoupons = COUPONS_DATA?.applicable_coupons;
let applicableCouponsHTML = `Available coupons
`;
applicableCouponsHTML += (applicableCoupons?.map((coupon) => {
const uniqueId = Math.random();
return (
`
${coupon?.code}
Apply
Apply coupon & save ₹${coupon.amount}!
` +
`
${coupon?.description ? `
${coupon?.description}
` : "<>>"}
${coupon?.tnc ? `
` : ""}
` +
`
${
coupon?.tnc?.split(",")?.map((value, index) => {
if(value?.length > 2){
return `${index + 1}. ${value}
`
};
}).join("")
}
` +
`
`
)
})).join("")
return applicableCouponsHTML;
}
const getNonApplicableCouponsHTML = () => {
const nonApplicableCoupons = COUPONS_DATA?.non_applicable_coupons;
let nonApplicableCouponsHTML = `Unlock coupons
`;
nonApplicableCouponsHTML += (nonApplicableCoupons?.map((coupon) => {
const uniqueId = Math.random();
return (
`
${coupon?.code}
Apply
` +
`${coupon?.validationErrorMsgs?.[0] ? `
${coupon?.validationErrorMsgs?.[0]}
` : ""}` +
`
${coupon?.description ? `
${coupon?.description}
` : "<>>"}
${coupon?.tnc ? `
` : ""}
` +
`
${
coupon?.tnc?.split(",")?.map((value, index) => {
if(value?.length > 2){
return `${index + 1}. ${value}
`
};
}).join("")
}
` +
`
`
)
})).join("")
return nonApplicableCouponsHTML;
}
const paintCouponsDrawer = () => {
try {
const coupons = COUPONS_DATA;
const couponDrawer = shadowRoot.getElementById('sr-cart-coupon-drawer-content');
const drawerCouponInput = getCouponInputHTML({
isDrawer: true
});
const couponError = getCouponErrorHTML("drawer");
const applicableCoupons = coupons?.applicable_coupons?.length > 0 ? getApplicableCouponsHTML() : "";
const nonApplicableCoupons = coupons?.non_applicable_coupons?.length > 0 ? getNonApplicableCouponsHTML() : "";
const drawerContent =
`
" "
${applicableCoupons}
${nonApplicableCoupons}
`
couponDrawer.innerHTML = drawerContent;
} catch (e) {}
}
const paintBannerUI = (data) => {
try {
const bannerContainer = shadowRoot.getElementById('sr-cart-banner');
const bannerConfig = data;
bannerContainer.style.display =
!bannerConfig?.showBanner &&
!(!bannerConfig?.hasOwnProperty('showBanner') && bannerConfig?.text)
? 'none' : 'block';
if(((bannerConfig?.showBanner) || (!bannerConfig?.hasOwnProperty('showBanner') && bannerConfig?.text))) {
// Set common styles
bannerContainer.style.fontWeight = bannerConfig?.fontWeight || DEFAULT_CONFIG.bannerDetails.fontWeight;
bannerContainer.style.fontSize = bannerConfig?.fontSize || DEFAULT_CONFIG.bannerDetails.fontSize;
shadowRoot.host.style.setProperty('--sr-banner-background-color', bannerConfig?.backgroundColor || DEFAULT_CONFIG.bannerDetails.backgroundColor);
shadowRoot.host.style.setProperty('--sr-banner-text-color', bannerConfig?.textColor || DEFAULT_CONFIG.bannerDetails.textColor);
// Handle different banner types
if(bannerConfig.type === 'carousel') {
const slides = [bannerConfig?.firstBannerText, bannerConfig?.secondBannerText, bannerConfig?.thirdBannerText].filter(Boolean);
const duration = slides?.length * 3;
const carouselSpans = slides.map((slide, idx) =>
`${slide}`
).join('');
bannerContainer.innerHTML = `
${carouselSpans}
`;
// Inject CSS only once
if (!shadowRoot.getElementById('sr-banner-carousel-css-style')) {
const style = document.createElement('style');
style.id = 'sr-banner-carousel-css-style';
style.textContent = `
.sr-banner-carousel-css {
display: flex;
white-space: nowrap;
overflow: hidden;
width: 100%;
position: relative;
height: 25px;
align-items: center;
}
.sr-banner-carousel-css span {
display: inline-block;
width: 100%;
opacity: 0;
transform: translateX(100%);
animation: sr-slideIn ${duration}s infinite;
animation-delay: calc(var(--index) * 3s);
text-align: center;
position: absolute;
left: 0;
right: 0;
line-height: 20px;
}
@keyframes sr-slideIn {
0%, 33% {
opacity: 0;
transform: translateX(100%);
}
5%, 28% {
opacity: 1;
transform: translateX(0);
}
33%, 100% {
opacity: 0;
transform: translateX(-100%);
}
}
`;
shadowRoot.appendChild(style);
}
} else {
// Single banner
bannerContainer.innerHTML = bannerConfig.text || DEFAULT_CONFIG.bannerDetails.text;
}
unHideById('sr-cart-banner')
}
} catch (e) {}
}
const paintSavingsBanner = () => {
try {
const customText = CURRENT_THEME_CONFIG?.customSavingsBannerText;
//🎉 You're saving {{TotalSavings}} 🎉!
const appliedCoupon = APPLIED_COUPON_DATA
const fallbackText = "🎉 Continue to safe checkout 🎉!";
const summarySavingsBanner = shadowRoot.getElementById('summary-combined-offer-badge');
const footerSavingsBanner = shadowRoot.getElementById('footer-combined-offer-badge');
const totalSavings = (CURRENT_CART_SUMMARY.discount ?? 0)
let textToInject = fallbackText
if(totalSavings > 0 && customText?.includes('{{TotalSavings}}')) {
textToInject = customText?.replace(/₹?\{\{TotalSavings\}\}/g, `₹${Number(totalSavings?.toFixed(2))}`);
} else if (customText && !customText?.includes('{{TotalSavings}}')) {
textToInject = customText
}
summarySavingsBanner.innerText = textToInject;
footerSavingsBanner.innerText = textToInject;
unHideById('summary-combined-offer-badge');
unHideById('footer-combined-offer-badge');
} catch (e) {}
}
const paintNoteSection = () => {
try {
const note = currentNote?.trim();
const noteContainer = shadowRoot.getElementById('sr-cart-note-section');
const markup = `
${note || "Add a note"}
`
+
(
(note)
?
(`
`)
:
(
`
`
)
)
+
`
`
noteContainer.innerHTML = markup;
unHideById('sr-cart-note-section')
} catch (e) {console.log('ERROR', e)}
}
const paintCouponsUI = () => {
try {
const isSingleApplicableCoupon = (COUPONS_DATA?.applicable_coupons?.length === 1 && COUPONS_DATA?.all_coupons?.length === 1) ? true : false;
const couponsContainer = shadowRoot.getElementById('sr-cart-coupons-container');
const couponsContainerSticky = shadowRoot.getElementById('sr-cart-coupons-container-sticky');
//a dummy hidden div to add height in case of sticky container
const hiddenCouponContainer = shadowRoot.getElementById('sr-cart-coupons-container-hidden');
const showViewMoreCoupons = (COUPONS_DATA?.applicable_coupons?.length > 1 || COUPONS_DATA?.non_applicable_coupons?.length > 0 || isSingleApplicableCoupon) ? true : false;
const highlightedCoupon = COUPONS_DATA?.highlighted_coupon ? getHighlightedCouponHTML() : "";
const couponInputBox = getCouponInputHTML();
const otherCoupons = showViewMoreCoupons ? getOtherCouponsHTML(isSingleApplicableCoupon) : "";
const couponError = getCouponErrorHTML("main");
const isCouponApplied = APPLIED_COUPON_DATA ? true : false;
const appliedCoupon = isCouponApplied ? getAppliedCouponHTML() : "";
const coupon_box =
`` +
(
!isCouponApplied
? `${highlightedCoupon}${couponInputBox}${couponError}`
: `${appliedCoupon}`
) +
`
` +
(
showViewMoreCoupons && !isCouponApplied
? `${otherCoupons}
`
: ''
);
if(couponsContainer && showCouponBox) {
if(CURRENT_THEME_CONFIG.stickyDiscountSection) {
couponsContainerSticky.innerHTML = coupon_box
hiddenCouponContainer.innerHTML = coupon_box?.replace(/id="[^"]*"/g, "");
unHideById('sr-cart-coupons-container-sticky')
} else {
couponsContainer.innerHTML = coupon_box;
}
}
if(showViewMoreCoupons) {
paintCouponsDrawer();
}
} catch (e) {}
}
window.handleFreebieAddition = (variantId) => {
if(SELECTED_FREEBIES?.length === maxFreebieItemsForSelection) {
showSRSCToast(`${maxFreebieItemsForSelection} item(s) already in the cart`)
return
}
showLoader();
const cartItems = CURRENT_CART_ITEMS;
const freebieObject = CURRENT_FREEBIE_ITEMS?.filter((freebie) => freebie?.variantId === variantId)?.[0]
if(freebieObject) {
SELECTED_FREEBIES?.push(freebieObject)
SELECTED_FREEBIES_VARIANT_IDS.push(variantId)
}
localStorageManager.set('srCartSelectedFreebies', JSON.stringify({freebieVariantIds: SELECTED_FREEBIES_VARIANT_IDS}))
paintFreebiesUI(SELECTED_FREEBIES)
miniCartInit(cartItems, false, new Date())
}
window.handleFreebieRemoval = (variantId) => {
showLoader();
const cartItems = CURRENT_CART_ITEMS;
const freebieObject = CURRENT_FREEBIE_ITEMS?.find((freebie) => freebie?.variantId === variantId);
if (freebieObject) {
// Remove from SELECTED_FREEBIES
const freebieIndex = SELECTED_FREEBIES.findIndex(freebie => freebie.variantId === variantId);
if (freebieIndex > -1) {
SELECTED_FREEBIES.splice(freebieIndex, 1);
}
// Remove from SELECTED_FREEBIES_VARIANT_IDS
const idIndex = SELECTED_FREEBIES_VARIANT_IDS.indexOf(variantId);
if (idIndex > -1) {
SELECTED_FREEBIES_VARIANT_IDS.splice(idIndex, 1);
}
}
localStorageManager.set('srCartSelectedFreebies', JSON.stringify({freebieVariantIds: SELECTED_FREEBIES_VARIANT_IDS}))
paintFreebiesUI(SELECTED_FREEBIES)
miniCartInit(cartItems, false, new Date());
}
const clearFreebieData = () => {
try {
SELECTED_FREEBIES = [];
SELECTED_FREEBIES_VARIANT_IDS = [];
isFreebieSelection = false;
paintFreebiesUI([]);
CURRENT_FREEBIE_ITEMS = [];
//hide freebie selector
hideById('sr-cart-freebie-selector-container');
localStorageManager.remove('srCartSelectedFreebies');
} catch (e) {}
}
const paintFreebieItemsList = () => {
try {
const freebieItemListContainer = shadowRoot.getElementById('sr-cart-freebies-item-list');
const freebieItems = CURRENT_FREEBIE_ITEMS;
//keep exact classes as upsell as styles don't differ, can be renamed later
const freebieItemsHTML =
freebieItems
?.map(
(item) => `
${item.name}
₹${item.price}
`
+
(
SELECTED_FREEBIES_VARIANT_IDS?.includes(item.variantId) ?
`
` :
`
`
)
+
`
`
)
.join("");
freebieItemListContainer.innerHTML = freebieItemsHTML;
} catch (e) {}
}
const paintFreebieSelector = () => {
try {
//check if there are selected freebies and they still need to appear upon a refetch
const selectedFreebieVariants = SELECTED_FREEBIES_VARIANT_IDS
if(selectedFreebieVariants?.length > 0) {
const currentFreebieVariants = CURRENT_FREEBIE_ITEMS?.map((item) => item.variantId);
for(let i=0; i 0) {
unHideById('sr-cart-freebie-selector-container');
selectedFreebieNumberContainer.innerText = SELECTED_FREEBIES?.length;
maxFreebieNumberContainer.innerText = maxFreebieItemsForSelection;
maxFreebieNumberDrawerContainer.innerText = maxFreebieItemsForSelection;
paintFreebieItemsList()
} else {
hideById('sr-cart-freebie-selector-container');
}
} catch (e) {}
}
const handleSuccessfullCoupon = (isSameCouponApplied) => {
try {
//re-do savings banner
paintSavingsBanner();
//re-do coupon UI to handle coupon application
paintCouponsUI();
//update order summary;
updateSummary(CURRENT_CART_SUMMARY);
const appliedCoupon = APPLIED_COUPON_DATA;
const couponCodeNameField = shadowRoot.getElementById('sr-cart-applied-coupon-name');
const couponCodeAmountField = shadowRoot.getElementById('sr-cart-applied-coupon-amount');
//set coupon to local for checkout
localStorageManager?.set('fastrrCouponCode', appliedCoupon?.discount_code)
//manipulate dom and show success dialog
couponCodeNameField.innerText = appliedCoupon?.discount_code;
couponCodeAmountField.innerText = appliedCoupon?.discount_amount;
if(isCouponDrawerOpen) {
toggleCouponDrawer();
}
if(!isSameCouponApplied) {
unHideById('sr-cart-coupon-success');
setTimeout(() => {
hideById('sr-cart-coupon-success');
}, 2000)
showConfettiHandler();
}
} catch (e) {}
}
const handleInvalidCoupon = (error = null) => {
try {
localStorageManager.remove('fastrrCouponCode');
//if coupon was already applied then only re-paint and update order summary
if(APPLIED_COUPON_DATA) {
paintCouponsUI();
updateSummary(CURRENT_CART_SUMMARY);
APPLIED_COUPON_DATA = null;
}
if(!error) {
return
}
if(isCouponDrawerOpen) {
unHideById('sr-cart-coupon-error-drawer')
const drawerCouponErrorContainer = shadowRoot.getElementById('sr-cart-coupon-error-drawer');
if(drawerCouponErrorContainer) {
drawerCouponErrorContainer.innerText = error
}
} else {
unHideById('sr-cart-coupon-error-main');
const mainCouponErrorContainer = shadowRoot.getElementById('sr-cart-coupon-error-main');
if(mainCouponErrorContainer) {
mainCouponErrorContainer.innerText = error
}
}
} catch (e) {}
}
window.applyCoupon = async (coupon) => {
try {
showLoader();
if(!APPLIED_COUPON_DATA) {
hideById('sr-cart-coupon-error-main')
hideById('sr-cart-coupon-error-drawer')
}
window.miniCartInit(CURRENT_CART_ITEMS, true, uniqueCartId, {}, coupon)
} catch (e) {
}
}
const fetchCoupons = async () => {
try {
const payload = {
sellerId: sellerId,
items: filteredItemsForCouponsAPI(CURRENT_CART_ITEMS),
subTotal: CURRENT_CART_SUMMARY?.total,
platform: "SHOPIFY"
}
let response = await fetch(
`${ENV.PROMOTION}/cart/suggest-coupons/cart`, {
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
method: "POST",
body: JSON.stringify(payload),
}
)
response = await response.json();
//filter coupons
const applicable_coupons = response?.data?.filter((coupon) => (coupon.applicable && !coupon.fomoCoupon))
const non_applicable_coupons = response?.data?.filter((coupon) => (!coupon.applicable && !coupon.fomoCoupon))
const highlighted_coupon = applicable_coupons?.length > 0 ? applicable_coupons?.[0] : null;
COUPONS_DATA = {
all_coupons: response?.data,
applicable_coupons: applicable_coupons,
non_applicable_coupons: non_applicable_coupons,
highlighted_coupon: highlighted_coupon
}
// if(APPLIED_COUPON_DATA) {
// await applyCoupon(APPLIED_COUPON_DATA?.discount_code)
// }
//send data to inject UI
paintCouponsUI()
} catch (e) {
paintCouponsUI()
}
}
window.miniCartInit = async function (cartItems, uiConfig, cartId, shopifyCartSummary, couponCode = "") {
try {
CURRENT_CART_ITEMS = cartItems;
const produdctIds = cartItems?.map((data) => data.variant_id);
const responseData = await fetchData(cartItems, uiConfig, cartId, couponCode);
if(responseData?.mini_cart_config_response?.sellerId) {
sellerId = responseData?.mini_cart_config_response?.sellerId
}
if (responseData) {
//set theme config in global store
CURRENT_THEME_CONFIG = responseData?.mini_cart_config_response?.cartUiConfig;
if (responseData?.progress_bar_details?.length && !isMilstoneAdded) {
MILESTONE_DATA = [
{
text: "",
discount_type: null,
discount_value: 0,
freebie_item_list: [],
mile_stone_type: "",
milestone_index: 0,
thresh_hold_value: 0,
},
...responseData?.progress_bar_details,
];
loadMilestones(MILESTONE_DATA, responseData?.mini_cart_config_response?.cartUiConfig);
}else {
// if(!responseData?.progress_bar_details?.length){
// loadMilestones([])
// }
if(shadowRoot.querySelector(".mini-card-sr-loader")){
shadowRoot.querySelector(".mini-card-sr-loader").setAttribute("style", "display: none !important;");
}
}
if (!responseData?.progress_bar_details?.length) {
hideById('mini-cart-progress-section')
shadowRoot.querySelector(".similar-item-heading").style.display = "none";
}
if (responseData?.cart_summary) {
CURRENT_CART_SUMMARY = responseData?.cart_summary;
updateSummary(responseData?.cart_summary);
updateProgressBar((responseData?.cart_summary?.milestoneTotal));
} else {
updateSummary(shopifyCartSummary);
}
if (responseData?.suggested_items) {
window.srcSuggestedItemsExist = true
const suggested_items = responseData?.suggested_items?.filter(
(items) => !produdctIds.includes(Number(items?.variantId)));
loadSimilarItems(suggested_items, responseData?.mini_cart_config_response?.cartUiConfig);
} else {
loadSimilarItems([]);
}
if(responseData?.freebie_item_list?.length > 0) {
CURRENT_FREEBIE_ITEMS = responseData?.freebie_item_list;
if(!responseData?.freebie_selection) {
isFreebieSelection = false;
paintFreebiesUI(responseData?.freebie_item_list);
}
else {
isFreebieSelection = true;
maxFreebieItemsForSelection = Math.min(responseData?.freebie_item_list?.length, responseData?.freebie_quantity)
paintFreebieSelector();
}
} else {
clearFreebieData();
}
if(
responseData?.mini_cart_config_response?.bannerDetails &&
(responseData?.mini_cart_config_response?.bannerDetails?.text?.trim() !== "" &&
(responseData?.mini_cart_config_response?.bannerDetails?.showBanner))
) {
paintBannerUI(responseData?.mini_cart_config_response?.bannerDetails);
}
if(responseData?.mini_cart_config_response?.cartUiConfig?.showSavingsBanner) {
paintSavingsBanner();
}
if(responseData?.mini_cart_config_response?.cartUiConfig?.enableGiftNote) {
paintNoteSection();
}
if(responseData?.mini_cart_config_response?.cartUiConfig?.showCompareAtPrice) {
enrichCartWithCompareAtPrices(CURRENT_CART_ITEMS);
}
//fetch coupons
if(!couponCode) {
fetchCoupons();
}
//update header quantity
updateHeaderQuantity();
//handle discounts
handleDiscounts({
manuallyApplied: couponCode ? true : false,
couponsData: responseData?.discount_data?.data
});
//handle theme config / TODO add flag if already done then avoid next call
if(!isThemeConfigPainted) {
isThemeConfigPainted = true;
themeConfig(
responseData?.mini_cart_config_response?.cartUiConfig,
responseData?.mini_cart_config_response?.headerUiConfig,
responseData?.mini_cart_config_response?.buyNowButtonUIConfig
);
}
if(saveCurrentFreebiesToLS) {
localStorageManager?.set('shiprocketSmartCartFreebies', JSON.stringify((responseData?.freebie_item_list || [])))
}
} else {
loadMilestones([]);
loadSimilarItems([]);
paintFreebiesUI([]);
updateSummary(shopifyCartSummary)
themeConfig()
// if(shadowRoot.querySelector('.mini-cart-order-btn')){
// shadowRoot.querySelector('.mini-cart-order-btn').textContent = 'Place order';
// }
// alert('Something Went Wrong')
}
//hide-loader
hideLoader();
} catch(error){
loadMilestones([]);
loadSimilarItems([]);
paintFreebiesUI([]);
themeConfig()
updateSummary(shopifyCartSummary)
// if(shadowRoot.querySelector('.mini-cart-order-btn')){
// shadowRoot.querySelector('.mini-cart-order-btn').textContent = 'Place order';
// }
// alert('Something Went Wrong')
//hide-loader
hideLoader();
}
};
try {
const script = document.createElement("script");
script.src =
"https://cdn.jsdelivr.net/npm/canvas-confetti@1.6.0/dist/confetti.browser.min.js";
document.head.appendChild(script);
} catch (error) {}
})()