Performance Tool
Part #WILW749
$6.99
Details
Brand | Performance Tool |
---|---|
Manufacturer Part Number | W749 |
Vehicle Fitment
Related Products
Lisle Tools
Razor Blade Scraper | 30452000
$43.93
View Details
Performance Tool
Mini Razor Scraper | WILW5750
$5.19
View Details
Performance Tool
Mini Razor Scraper | WILW3200
$1.99
View Details
Performance Tool
Mini Razor Scraper | WILW9158
$5.09
View Details
Mr Gasket
Gasket Scraper - Razor/Plastic | MRG33270G
$30.19
View Details
Select a Store
Performance Tool
3-Position Razor Scraper
Part #WILW749
$6.99
${dealer.address1}, ${dealer.state}
`; } } async function makMarker(id) { if (oldId === id) return; const updateMarkerContent = (marker, imgSrc, alt = "") => { if (marker) { const pin = document.createElement('img'); pin.src = imgSrc; if (alt) pin.alt = alt; marker.content = pin; } }; const deactivateOldMarker = () => { if (oldId) { const oldMarker = myMarkers[oldId]; updateMarkerContent(oldMarker, 'https://cdn11.bigcommerce.com/s-tiejer0sju/stencil/a634b060-ec6d-013d-5f0c-6aca8e4ffbf3/e/84ee4f10-ca90-013d-ca0b-3a80c31d5c55/img/location_on.png'); const oldMarkerElement = document.getElementById(oldId); if (oldMarkerElement) { const oldCard = oldMarkerElement.closest('.dealer-card'); if (oldCard) oldCard.classList.remove('dealer-card--active'); } } }; deactivateOldMarker(); const newMarker = myMarkers[id]; updateMarkerContent(newMarker, 'https://cdn11.bigcommerce.com/s-tiejer0sju/stencil/a634b060-ec6d-013d-5f0c-6aca8e4ffbf3/e/84ee4f10-ca90-013d-ca0b-3a80c31d5c55/img/marker.png', id); const dealer = offlineStores.find((dealer) => dealer.id == id); if (!dealer) { console.warn(`Dealer with id ${id} not found`); return; } if (cartLocationBox) { map.panTo({ lat: Number(dealer.location_latitude), lng: Number(dealer.location_longitude), }); map.setZoom(14); } const currentCookieLocation = Cookies.get('location'); const dealerAsString = JSON.stringify(dealer); if (currentCookieLocation !== dealerAsString) { if (jsContext.customer) { try { const url = `${jsContext.lordcoAppUrl}/updateCustomerLocation`; const data = { customer: jsContext.customer.id, store_location: dealer.id, }; const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data), }); const locationData = await response.json(); if ( locationData?.success && locationData.nearest_location?.id ) { Cookies.set( 'location', JSON.stringify(locationData.nearest_location), { expires: 7 } ); updateSelectStore(locationData.nearest_location); } } catch (error) { console.error('Error updating customer location:', error); } } else { Cookies.set('location', dealerAsString, { expires: 7 }); updateSelectStore(dealer); } } oldId = id; } } function displayInventoryByLocation(dealer) { if (!dealer.inventory) return ''; const isOutOfStock = dealer.inventory.available_to_sell === 0; const isAvailableInStore = dealer.inventory.available_to_sell > 0 && dealer.inventory.settings.warning_level < dealer.inventory.available_to_sell; const isLimitedQty = dealer.inventory.available_to_sell > 0 && dealer.inventory.settings.warning_level >= dealer.inventory.available_to_sell; if (isOutOfStock) { return ' Out of Stock'; } else if (isAvailableInStore) { return `${dealer.inventory.available_to_sell} in stock`; } else if (isLimitedQty) { return 'Limited availability'; } else { return ''; } } function addToCartFromModal() { const quantityInput = document.querySelector( '#storeSelectorModal [data-quantity-change] .form-input--incrementTotal', ); const decreaseButton = document.querySelector( '#storeSelectorModal [data-action="dec"]', ); const increaseButton = document.querySelector( '#storeSelectorModal [data-action="inc"]', ); let qty = quantityInput.value; decreaseButton.addEventListener('click', (event) => { event.preventDefault(); qty--; if ( qty <= parseInt(quantityInput.getAttribute('data-quantity-min'), 10) ) { qty = quantityInput.getAttribute('data-quantity-min'); } quantityInput.value = qty; }); increaseButton.addEventListener('click', (event) => { event.preventDefault(); qty++; if ( qty >= parseInt(quantityInput.getAttribute('data-quantity-max'), 10) ) { qty = quantityInput.getAttribute('data-quantity-max'); } quantityInput.value = qty; }); quantityInput.addEventListener('change', (event) => { qty = parseInt(event.target.value); if ( qty >= parseInt( quantityInput.getAttribute('data-quantity-max'), 10, ) || qty <= parseInt( quantityInput.getAttribute('data-quantity-min'), 10, ) ) { qty = 1; quantityInput.value = 1; } }); } function generateInStoreDealerList(dealers) { const inStoreDealerListElement = document.getElementById( 'in-store-dealer-list', ); storeId = document .querySelector('.select-store') .getAttribute('data-id'); let allDealers = dealers; // Reorder dealers based on store inventory if (currentSku) { const stockDealers = dealers.filter( (e) => e.inventory && e.inventory.available_to_sell !== 0, ); const outOfStockDealers = dealers.filter( (e) => e.inventory && e.inventory.available_to_sell === 0, ); if ( allDealers.length === stockDealers.concat(outOfStockDealers).length ) allDealers = stockDealers.concat(outOfStockDealers); } const currentDealer = allDealers.find( (dealer) => dealer.id === parseInt(storeId), ); let currentFirstDealers = allDealers.filter( (e) => e.id !== currentDealer.id, ); currentFirstDealers.unshift(currentDealer); currentDealer.inventory && !cartLocationBox && !plpLayout && !convermaxResults && document .querySelector( '#storeSelectorModal .form-input--incrementTotal', ) .setAttribute( 'data-quantity-max', currentDealer.inventory.available_to_sell, ); // Generate the dealer list as before const inStoreDealerListMarkup = currentFirstDealers .map((inStoreDealer) => { const hoursHTML = generateHoursHTML(inStoreDealer.work_hours); return `
My pickup location
${ inStoreDealer.dealer_name }${ inStoreDealer.distance?.text }
${ inStoreDealer.phone ? inStoreDealer.phone + '
' : '' } ${inStoreDealer.address1}
${inStoreDealer.city}, ${inStoreDealer.state}
${displayInventoryByLocation( inStoreDealer, )}
View Store Details
`; }) .join(''); inStoreDealerListElement.innerHTML = inStoreDealerListMarkup; currentSku && !cartLocationBox && !plpLayout && !convermaxResults && addToCartFromModal(); } function generateHoursHTML(workHoursString) { const workHours = parseWorkHours(workHoursString); let hoursHTML = '
HOURS:
'; DAY_ORDERS.forEach((column) => { column.forEach((day) => { if (SHORT_DAYS[day]) { hoursHTML += `
${ SHORT_DAYS[day] }
${workHours[day] || 'Closed'}
`; } else { hoursHTML += `
`; } }); }); hoursHTML += '
'; return hoursHTML; } // Function to parse work_hours into a structured format function parseWorkHours(workHoursString) { if (!workHoursString) { return { Monday: 'Closed', Tuesday: 'Closed', Wednesday: 'Closed', Thursday: 'Closed', Friday: 'Closed', Saturday: 'Closed', Sunday: 'Closed', }; } const workHours = {}; const days = workHoursString.split(', '); days.forEach((dayInfo) => { const [day, hours] = dayInfo.split(': '); if (hours && hours.toLowerCase() !== 'closed') { const times = hours.split('–').map((time) => time.trim()); let openTime = times[0]; const closeTime = times[1]; if (!openTime.includes('AM') && !openTime.includes('PM')) { if (closeTime && closeTime.includes('PM')) { openTime += ' PM'; } else if (closeTime && closeTime.includes('AM')) { openTime += ' AM'; } } const openTimeFormatted = openTime; const closeTimeFormatted = closeTime || ''; var separator = ''; if (hours.toLowerCase() !== 'open 24 hours') { separator = ' – '; } workHours[ day.trim() ] = `${openTimeFormatted} ${separator} ${closeTimeFormatted}`; } else { workHours[day.trim()] = 'Closed'; } }); return workHours; } function timeToNumber(time) { let hour, period; time = time.trim().replace(/\s+/g, ' '); if (time && typeof time === 'string') { const parts = time.split(' '); hour = parts[0]; period = parts[1] || ''; } else { hour = '00:00'; period = ''; } let [h, m] = hour.split(':'); if (!m) { m = '00'; } h = parseInt(h, 10); m = parseInt(m, 10); if (period.toLowerCase() === 'pm' && h !== 12) { h += 12; } else if (period.toLowerCase() === 'am' && h === 12) { h = 0; } const timeNumber = h * 100 + m; return timeNumber; } // Convert number to time (e.g., 1000 -> "10:00 AM") function numberToTime(number) { let h = Math.floor(number / 100); const m = number % 100; const ampm = h >= 12 ? 'PM' : 'AM'; h = h % 12; h = h ? h : 12; const minute = m.toString().padStart(2, '0'); return `${h}:${minute} ${ampm}`; } function generateOnlineDealers(deaderList) { const dealerListElement = document.getElementById('online-dealer-list'); const dealerListMarkup = deaderList .map( (dealer) => `
${dealer.dealer_name}
Go to website
`, ) .join(''); dealerListElement.innerHTML = dealerListMarkup; } function generateCartLocationBox(dealers) { if (!cartLocationBox) return; const getToday = () => { const days = [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', ]; return days[new Date().getDay()]; }; const getCurrentTime = () => { const now = new Date(); return now.getHours() * 100 + now.getMinutes(); }; const isOpen = (workHoursString) => { const workHours = parseWorkHours(workHoursString); const today = getToday(); const currentTime = getCurrentTime(); // Parse the hours for today if (workHours && workHours[today]) { const hours = workHours[today] .split('–') .map((time) => timeToNumber(time.trim())); if (hours.length === 2) { const [openTime, closeTime] = hours; if (currentTime >= openTime && currentTime < closeTime) { return `Open until ${numberToTime(closeTime)}`; } } } return 'Closed'; }; storeId = document .querySelector('.select-store') .getAttribute('data-id'); const currentDealer = dealers.find( (dealer) => dealer.id === parseInt(storeId), ); const currentStatus = isOpen(currentDealer.work_hours); const hoursHTML = generateHoursHTML(currentDealer.work_hours); cartLocationBox.querySelector('.loadingSpinner') && cartLocationBox.querySelector('.loadingSpinner').remove(); cartLocationBox.innerHTML = `
Pickup Store
${ currentDealer.dealer_name }
${ currentDealer.phone ? `
${currentDealer.phone}
` : '' } ${ currentDealer.address1 ? `
${currentDealer.address1}
${currentDealer.city}, ${currentDealer.state}
` : '' }
${ currentStatus ? currentStatus : '' }
${ currentDealer.distance?.value ? `${currentDealer.distance?.text}` : '' }
`; } function generateDealers() { getDealers(); const container = document.querySelector('.in-store-dealer-list'); container.addEventListener('click', function (event) { const button = event.target.closest('.dealer-card__details'); if (button) { event.preventDefault(); const fullHoursDiv = button.nextElementSibling; const arrowIcon = button.querySelector('.arrow-icon'); fullHoursDiv.style.display = fullHoursDiv.style.display === 'none' ? 'block' : 'none'; arrowIcon.src = fullHoursDiv.style.display === 'none' ? 'https://cdn11.bigcommerce.com/s-tiejer0sju/stencil/a634b060-ec6d-013d-5f0c-6aca8e4ffbf3/e/84ee4f10-ca90-013d-ca0b-3a80c31d5c55/img/chevron_up.png' : 'https://cdn11.bigcommerce.com/s-tiejer0sju/stencil/a634b060-ec6d-013d-5f0c-6aca8e4ffbf3/e/84ee4f10-ca90-013d-ca0b-3a80c31d5c55/img/chevron_down.png'; } }); } function observeDealers() { const storeSelectorModal = document.getElementById('storeSelectorModal'); if (storeSelectorModal) { const observer = new MutationObserver((mutationsList, observer) => { for (const mutation of mutationsList) { if (storeSelectorModal.classList.value.includes('open')) { currentSku = storeSelectorModal.getAttribute('data-modal-sku'); getDealers(); return; } storeSelectorModal.setAttribute('data-modal-sku', ''); currentSku = ''; } }); observer.observe(storeSelectorModal, { attributes: true, attributeFilter: ['class'], }); const disconnectObserver = () => { observer.disconnect(); }; window.addEventListener('beforeunload', disconnectObserver); } } document.addEventListener('DOMContentLoaded', () => { generateDealers(); if (cartLocationBox || plpLayout || convermaxResults) { observeDealers(); } });