All Skincare Face Wash Face Wipes Makeup Removers Toners
${product?.brand}
${getTitle(product.familyName, product.name)}
${JSON.parse(product.display_attributes?.tags || '[]').length > 0 ? `
${JSON.parse(product.display_attributes?.tags || '[]').map(tag => { return `${tag} ` }).join('')}
` : ''}
${product.validRating ? `
${generateRating(product.rating)}
${product.reviewCount}
` : ''}
`; }); const container = document.querySelector('.CollectionsGrid__ProductCards.CollectionsGrid__ProductCards--3-Col'); if (container) { if (!append) { container.innerHTML = ''; } const productsEl = fragmentFromString(productsHTML); HSS.registerListeners('Landing Page Event', productsEl); container.appendChild(productsEl); registerGTMForAll(); } }; const onClickPage = (page, isActive) => { if (!isActive) { updateState({ pageNumber: page }); } }; const buildPagination = (metadata) => { const store = window.store; const state = store.get('state'); const activePage = state.pageNumber || 1; if (metadata?.maxPage === 1) { return ''; } let paginationHTML = `
`; // Add Previous button const isPrevDisabled = activePage === 1 ? 'disabled' : ''; paginationHTML += ` `; // Add page buttons with ellipsis for hidden pages for (let i = 1; i <= metadata?.maxPage; i++) { const isActive = i === activePage ? 'aria-current="page"' : ''; const isHidden = Math.abs(i - activePage) > 2 && i !== 1 && i !== metadata?.maxPage ? 'hidden' : ''; if (isHidden && i < activePage - 2) { if (!paginationHTML.includes("...
")) { paginationHTML += ` ...
`; } continue; } paginationHTML += ` `; } // Add Next button const isNextDisabled = activePage === metadata?.maxPage ? 'disabled' : ''; paginationHTML += ` `; paginationHTML += ` `; return paginationHTML; }; const updatePagination = (metadata, itemsPerPage, activePage) => { const paginationContainer = document.querySelector('#mb-pagination-desktop'); if (paginationContainer) { paginationContainer.innerHTML = buildPagination(metadata); window.scrollTo(0, 0); } }; const onClearAllFilters = () => { const store = window.store; const state = store.get('state'); updateState({ filters: [], pageNumber: 1, }); }; const handleCheck = (filterElement, from) => { const filterId = filterElement.getAttribute('data-id'); const filterValue = filterElement.getAttribute('data-value'); let isSelected = filterElement.checked ? true : false; // Update all matching elements const elements = document.querySelectorAll(`[data-id="${filterId}"][data-value="${filterValue}"]`); elements.forEach((input) => { input.checked = isSelected; }); // Update state in the store const store = window.store; const state = store.get('state'); const filterIndex = state.filters.findIndex((f) => f.id === filterId); let updatedFilters = [...state.filters]; if (filterIndex > -1) { const existingValueIndex = updatedFilters[filterIndex].values.findIndex((v) => v.value === filterValue); if (existingValueIndex > -1) { updatedFilters[filterIndex].values[existingValueIndex].selected = isSelected; } else { updatedFilters[filterIndex].values.push({ value: filterValue, selected: isSelected, }); } } else { updatedFilters.push({ id: filterId, values: [ { value: filterValue, selected: isSelected, }, ], }); } // Call updateState with the updated filters and other properties updateState({ filters: updatedFilters, pageNumber: 1, }); } const buildFilterLabel = (id, name, facetId, selected) => { return `
${name} `; }; let expandedFilterIds = []; let expandedFilterMobileIds = []; const onExpandFilterDesktop = (el) => { const getId = el.getAttribute('data-id'); const filterWrapper = el.closest('.Filters__Category').querySelector('.Filters__FiltersWrapper'); if (!filterWrapper) { console.log('filterWrapper not found'); return; } const isMobile = window.innerWidth < 769; if (filterWrapper.classList.contains('Filters__FiltersWrapper--open')) { if (isMobile) { expandedFilterMobileIds = expandedFilterMobileIds.filter(id => id !== getId); } else { expandedFilterIds = expandedFilterIds.filter(id => id !== getId); } } else { if (isMobile) { expandedFilterMobileIds.push(getId); } else { expandedFilterIds.push(getId); } } filterWrapper.classList.toggle('Filters__FiltersWrapper--open'); el.querySelector('.Filters__Arrow').classList.toggle('Filters__Arrow--open'); } const buildFilterCategory = (facet, isMobile) => { const labels = facet?.values?.map(value => buildFilterLabel(value.value, value.value, facet.id, value.selected)).join(''); const isExpandedMobile = expandedFilterMobileIds.includes(facet?.id); const isExpandedDesktop = expandedFilterIds.includes(facet?.id); const isExpanded = isMobile ? isExpandedMobile : isExpandedDesktop; return `
${facet.name.toUpperCase() === 'BRAND' ? `
` : ''}
${labels}
`; }; const buildFilters = (facets, isMobile) => { return facets?.filter(facet => !!facet?.values?.length)?.map(facet => buildFilterCategory(facet, isMobile)).join(''); }; const updateFilters = (facets) => { const isMobile = window.innerWidth < 769; const filterContainer = document.querySelector('#bm-filter-container'); const filterContainerMobile = document.querySelector('#bm-filter-container-mobile'); if (filterContainer) { filterContainer.innerHTML = buildFilters(facets, isMobile); } if (filterContainerMobile) { filterContainerMobile.innerHTML = buildFilters(facets, isMobile); } const filterDesktopCount = document.querySelector('#bm-filter-count-desktop'); const selectedFacetsCount = facets.reduce((count, facet) => { if (!facet?.values) return count; return count + facet?.values?.filter(value => value.selected).length; }, 0); if (filterDesktopCount) { if (selectedFacetsCount > 0) { filterDesktopCount.innerHTML = `(${selectedFacetsCount})`; } else { filterDesktopCount.innerHTML = ''; } } updateTopSelectedChips(); }; const updateTopSelectedChips = () => { const store = window.store; const state = store.get('state'); const facets = state.filters; const hasAtLeastOneSelected = facets?.some(facet => facet?.values?.some(value => value.selected === true)); const diableBtn = document.querySelector('#opt-clear-btn'); if (!hasAtLeastOneSelected) { const container = document.querySelector('#bm-filter-chips'); const containerMobile = document.querySelector('#bm-filter-chips-mobile'); if (container) { container.innerHTML = ''; } if (containerMobile) { containerMobile.innerHTML = ''; containerMobile.style.display = 'none' } if (diableBtn) { diableBtn.setAttribute('disabled', 'true'); } return; } if (diableBtn) { diableBtn.removeAttribute('disabled'); } let selectedChips = `
`; facets.forEach((facet, index) => { const selectedValues = (facet.values || []).filter( (value) => value.selected === true, ); if (selectedValues.length > 0) { selectedValues.forEach((v) => { let title; try { title = v.value.replace(" to ", " - "); } catch (err) { title = v.value || ''; } selectedChips += ` `; }); } }); selectedChips += `
`; selectedChips += ``; const container = document.querySelector('#bm-filter-chips'); const containerMobile = document.querySelector('#bm-filter-chips-mobile'); if (container) { container.innerHTML = selectedChips; } if (containerMobile) { containerMobile.innerHTML = selectedChips; containerMobile.style.display = 'flex' } }; const updatePriceRange = (products) => { products?.forEach((product) => { const calculatedSavings = calculateSavings( product?.regularPrice, product?.salePrice ); const priceRanges = product?.family_attributes?.priceRanges; const salePriceRanges = product?.family_attributes?.salePriceRanges; if (priceRanges?.length === 2 && salePriceRanges?.length === 2) { const initialSaleRange = parseFloat(salePriceRanges[0]); const finalSaleRange = parseFloat(salePriceRanges[1]); const initialPriceRange = parseFloat(priceRanges[0]); const finalPriceRange = parseFloat(priceRanges[1]); const rangeContainer = document.querySelector(`#optBMPrice-${product?.sku}`); if (rangeContainer && (initialSaleRange !== initialPriceRange || finalSaleRange !== finalPriceRange || (initialSaleRange === initialPriceRange && finalSaleRange === finalPriceRange))) { rangeContainer.innerHTML = `
$${initialSaleRange} - $${finalSaleRange}
${calculatedSavings?.save > 0 ? `
$${product?.regularPrice} (${Math.round(calculatedSavings?.savingsPercentage)}% off)
` : ''} `; } } }); }; const getPageData = async (metadataOnly = false) => { const productsPerPage = '24'; try { const store = window.store; const state = store.get('state'); const { pageNumber, maxPageNumber, sort, sortDirection, filters, pageSize, facets: previousFactes } = state; let body = { o: searchOrgId, p: searchPageId, pageSize, pageNum: pageNumber, sort, sortDirection, facets: filters, }; const selectedFilters = filters?.filter(facet => facet?.values?.some(value => value.selected === true))?.map(selected => { const findFacet = previousFactes?.find(it => it?.id === selected?.id); if (findFacet) { return ({ ...selected, name: findFacet?.name }) } return selected; }); const data = await HSS.search(body); // Loop through data.results and add "validRating" data?.results?.forEach((product) => { product.validRating = Math.round(product.rating) > 3 || (Math.round(product.rating) < 3 && product.reviewCount > 5); }); if (!metadataOnly) { updateProducts(data?.results, false); } const priorityOrder = [ "SORT BY", "BRAND", "PRICE", "TYPE", "BENEFIT", "CONCERN", "INGREDIENT PREFERENCE", "SIZE", "SHOP BY" ]; const facets = data.metadata.facets?.filter(facet => !!facet?.values?.length && facet.values.length > 1); selectedFilters.forEach(item => { const existingFacet = facets.find(facet => facet?.id === item?.id); if (existingFacet) { const uniqueValues = item.values.filter( newValue => !existingFacet.values.some(existingValue => existingValue.value === newValue.value) ); existingFacet.values = [...existingFacet.values, ...uniqueValues]; } else { facets.push(item); } }); facets.sort((a, b) => { const indexA = priorityOrder.indexOf(a?.name?.toUpperCase()); const indexB = priorityOrder.indexOf(b?.name?.toUpperCase()); if (indexA !== -1 && indexB !== -1) { // Both are in the priority list, sort by their order return indexA - indexB; } else if (indexA !== -1) { // Only a is in the priority list, it should come first return -1; } else if (indexB !== -1) { // Only b is in the priority list, it should come first return 1; } else { // Neither is in the priority list, sort alphabetically return a?.name?.localeCompare(b?.name); } }) const filteredFacets = updateState({ maxPageNumber: data.metadata.maxPage, totalResults: data.metadata.totalResults, facets: facets }, false) updateProductsCount(data?.metadata?.totalResults || 0); //updatePriceRange(data.results); updatePagination(data?.metadata, pageSize, pageNumber); updateFilters(facets) console.log(facets, 'facets') } catch (ex) { console.log('---PageData Error---', ex); } }; const onSearchBrand = (inputElement) => { const store = window.store; const state = store.get('state'); const facets = state.facets; const searchTerm = inputElement.value.toLowerCase(); // Convert search term to lowercase for case-insensitive matching // Find the 'Brand' facet from the provided data const brandFacet = facets.find(facet => facet.name === 'Brand'); if (!brandFacet) return; // Filter the brand values based on the search term const filteredBrands = brandFacet.values.filter(value => value.value.toLowerCase().includes(searchTerm) ); // Build the labels for the filtered brands const labels = filteredBrands.map(value => buildFilterLabel(value.value, value.value, brandFacet.id, value.selected) ).join(''); // Update the DOM with the filtered brands const brandFilterWrapper = document.querySelectorAll(`.facet-${brandFacet.name}`); if (brandFilterWrapper) { brandFilterWrapper.forEach(it => { it.innerHTML = labels; }) } }; const onClear = () => { // Clear the input field value const searchInput = document.querySelectorAll('.search-brand'); if (searchInput) { searchInput.forEach(input => { input.value = ''; onSearchBrand(input); }) } }; document.addEventListener('DOMContentLoaded', async () => { registerGTMForAll(); HSS.initSearch(hssUrl); let isMetaOnly = true; await getPageData(isMetaOnly); }); document.addEventListener('DOMContentLoaded', async () => { const store = window.store; const state = store.get('state'); const sort = state.sort || null; const sortDirection = state.sortDirection || null; const combinedSort = sort && sortDirection && sortDirection !== 'undefined' ? `${sort}_${sortDirection}` : ''; const finalSort = combinedSort ? combinedSort : sort; //Featured const DefaultSort = 'featured'; //Price, High to Low const price_desc = 'price_desc' //Price, Low To High const price_asc = 'price_asc' //Top Rated const rating = 'rating' const sortBtn = document.querySelectorAll('#mb-sort-label'); if (!finalSort) { const findDefaultInput = `input[name="sort-"][value="featured"]`; const featuredSort = document.querySelectorAll(findDefaultInput); if (!!featuredSort.length) { featuredSort.forEach((sort) => { sort.checked = true; }); sortBtn.forEach(btn => { btn.innerHTML = 'Featured'; }) } return; } const featuredSort = document.querySelectorAll(`input[name="sort-"][value="${finalSort}"]`); if (!featuredSort.length) { const findDefaultInput = `input[name="sort-"][value="featured"]`; const featuredSort = document.querySelectorAll(findDefaultInput); if (featuredSort.length) { featuredSort.forEach((sort) => { sort.checked = true; }); sortBtn.forEach(btn => { btn.innerHTML = 'Featured'; }) } return; } switch (finalSort) { case DefaultSort: featuredSort.forEach((sort) => { sort.checked = true; }); sortBtn.forEach(btn => { btn.innerHTML = 'Featured'; }) break; case price_desc: featuredSort.forEach((sort) => { sort.checked = true; }); sortBtn.forEach(btn => { btn.innerHTML = 'Price, High to Low'; }) break; case price_asc: featuredSort.forEach((sort) => { sort.checked = true; }); sortBtn.forEach(btn => { btn.innerHTML = 'Price, Low to High'; }) break; case rating: featuredSort.forEach((sort) => { sort.checked = true; }); sortBtn.forEach(btn => { btn.innerHTML = 'Top Rated'; }) break; default: if (!!featuredSort.length) { featuredSort.forEach((sort) => { sort.checked = true; }); sortBtn.forEach(btn => { btn.innerHTML = 'Featured'; }) } break; } })
Clinique
True Bronze Pressed Powder Bronzer
Hourglass
Ambient Lighting Bronzer
BestSeller
Jane Iredale
Glow Time Bronzer Stick
Pat McGrath Labs
Skin Fetish: Divine Bronzer
RMS Beauty
Buriti Bronzer
BestSeller
Kevyn Aucoin
The Neo-Bronzer
BestSeller
RMS Beauty
ReDimension Hydra Bronzer
BestSeller
Kjaer Weis
Matte Cream Bronzer Refill
Nars
Laguna Bronzing Powder
BestSeller
Estée Lauder
Bronze Goddess Powder Bronzer
New
Bobbi Brown
Bronzer Powder
BestSeller
Jane Iredale
PureBronze Shimmer Bronzer Refill
Jane Iredale
PureBronze Matte Bronzer Refill
Nars
Laguna Bronzing Cream
Lune+Aster
Soft Silk Bronzer
BestSeller
Kjaer Weis
Glow Bronzer Refill
BestSeller
Laura Mercier
Matte Radiance Baked Powder
BestSeller
Kjaer Weis
Pressed Powder Bronzer Refill
Sisley-Paris
Sun Glow Gel
Sisley-Paris
Phyto-Touche Sun Glow Powder
Victoria Beckham Beauty
Matte Bronzing Brick
BestSeller
RMS Beauty
ReDimension Hydra Bronzer Refill
BestSeller
Kosas
The Sun Show Baked Bronzer
New
Surratt
Artistique Bronzer Prefilled Compact
Related Products
Estée Lauder
Double Wear Stay-in-Place Foundation 2C0 Cool Vanilla
Anastasia Beverly Hills
Dipbrow Pomade Ash Brown
Estée Lauder
Futurist Hydra Rescue Moisturizing Makeup SPF 45 3N1 Ivory Beige
Clinique
Even Better Makeup Broad Spectrum SPF 15 TOFFEE
Related links High Pigment Bronzers Best Bronzer Natural Bronzers Compact Makeup Bronzers Creamy Bronzing Products Buildable Coverage Bronzers Easy Application Blushes Deep Skin Tone Bronzers Bronzer For Experts Glowy Bronzers