Files
Rogers_Motors_Theme/autocart_assets/js/index.js
2024-04-08 06:32:26 -04:00

373 lines
11 KiB
JavaScript

let drawer;
let keyword;
let price;
let year;
let kilometres;
let dataStore;
let filterManager;
let appliedFilters;
let shouldUpdateFilters = true;
let modelFilter = [];
let makeFilters;
function sendReq() {
var formData = {
action: 'handle_autocart_form',
minPrice: price.getValueStart(),
maxPrice: price.getValue(),
minKilometres: kilometres.getValueStart(),
maxKilometres: kilometres.getValue(),
minYear: year.getValueStart(),
maxYear: year.getValue(),
autocart_nonce: jQuery('#autocart_nonce').val(),
};
const vehiclesContainer = document.querySelector('.vehicles-container');
// vehiclesContainer.textContent = 'Loading...';
// Add skeleton cards to the vehicles container
for (let i = 0; i < 6; i++) {
const skeletonCard = createSkeletonCard();
vehiclesContainer.appendChild(skeletonCard);
}
const filtersContainer = document.querySelector('.make-container');
for (let i = 0; i < 2; i++) {
const skeletonListItem = createSkeletonListItem();
filtersContainer.appendChild(skeletonListItem);
}
// Add skeleton list item to the filters container
// const skeletonListItem = createSkeletonListItem();
// filtersContainer.appendChild(skeletonListItem);
jQuery.ajax({
type: 'POST',
url: ajax_object.ajax_url,
data: formData,
success: function (response) {
const vehicles = response.data.vehicles;
if (dataStore) {
dataStore.unsubscribeAll();
}
// Initialize new data store
dataStore.vehicles = vehicles;
filterManager = new FilterManager(dataStore);
appliedFilters = new AppliedFilters(dataStore, filterManager);
// filterManager = new FilterManager(dataStore);
// appliedFilters = new AppliedFilters(dataStore, filterManager);
shouldUpdateFilters = true;
dataStore.subscribe((filteredVehicles) => {
console.log('dataStore has been changed');
handleSuccess(filteredVehicles);
});
dataStore.notifySubscribers(vehicles);
},
error: function (xhr, status, error) {
console.log(xhr.responseText);
console.log('Status: ' + status);
console.log('Error: ' + error);
jQuery('#inventory-search__search-button').text('Error');
},
});
}
function handleSuccess(vehicles, updateFilters = shouldUpdateFilters) {
if (updateFilters) {
createMakeList(vehicles);
createBodyTypeList(vehicles);
createTransmissionList(vehicles);
createExteriorList(vehicles);
}
const vehiclesContainer = document.querySelector('.vehicles-container');
vehiclesContainer.innerHTML = '';
vehicles.forEach((vehicleData) => {
const vehicle = new VehicleThumbnail(vehicleData);
// vehiclesContainer.appendChild(vehicle.generateCardHTML());
vehiclesContainer.appendChild(vehicle.generateCardElement());
});
}
function createMakeList(vehicles) {
const makeContainer = document.querySelector('.make-container');
makeContainer.innerHTML = '';
const makeCounts = vehicles.reduce((acc, vehicle) => {
const { make } = vehicle;
acc[make] = (acc[make] || 0) + 1;
return acc;
}, {});
let makeValue = document.querySelector('#autocart-make-field').value;
// if(makeValue){
// console.log('makeValue',makeValue);
// // dataStore.addFilter('make', makeValue);
// }
makeFilters = Object.entries(makeCounts).map(([make, count]) => {
return filterManager.createMakeFilter(
{
text: make,
checked: makeValue.toLowerCase() === make.toLowerCase(),
count,
models: fetchAvailableModels(vehicles, make),
},
dataStore
);
});
makeFilters.sort((a, b) => a.value.localeCompare(b.value));
makeFilters.forEach((make) => {
makeContainer.appendChild(make.generateCardHTML());
make.subscribe((m) => initModelContainer(m));
});
}
function createBodyTypeList(vehicles) {
const bodyTypeContainer = document.querySelector('.body-type-container');
bodyTypeContainer.innerHTML = '';
const bodyType = vehicles.reduce((acc, vehicle) => {
const { body_type } = vehicle;
acc[body_type] = (acc[body_type] || 0) + 1;
return acc;
}, {});
filterManager.resetList('body_type');
bodyTypeFilters = Object.entries(bodyType).map(([body_type, count]) =>
filterManager.createBodyTypeFilter({ text: body_type, count }, dataStore)
);
bodyTypeFilters.sort((a, b) => a.value.localeCompare(b.value));
bodyTypeFilters.forEach((body_type) => {
bodyTypeContainer.appendChild(body_type.initCheckbox());
// body_type.subscribe(m=> iniBodyTypeContainer(m))
});
}
function createTransmissionList(vehicles) {
const transmissionContainer = document.querySelector(
'.transmission-container'
);
transmissionContainer.innerHTML = '';
const transmission = vehicles.reduce((acc, vehicle) => {
const { transmission_type } = vehicle;
acc[transmission_type] = (acc[transmission_type] || 0) + 1;
return acc;
}, {});
filterManager.resetList('transmission_type');
transmissionFilters = Object.entries(transmission).map(
([transmission_type, count]) =>
filterManager.createTransmissionFilter(
{ text: transmission_type, count },
dataStore
)
);
transmissionFilters.sort((a, b) => a.value.localeCompare(b.value));
transmissionFilters.forEach((transmission) => {
transmissionContainer.appendChild(transmission.initCheckbox());
});
}
function createExteriorList(vehicles) {
console.log(vehicles);
const exteriorContainer = document.querySelector('.exterior-color');
exteriorContainer.innerHTML = '';
const exterior = vehicles.reduce((acc, vehicle) => {
const { exterior_color } = vehicle;
acc[exterior_color] = (acc[exterior_color] || 0) + 1;
return acc;
}, {});
filterManager.resetList('exterior_color');
exteriorFilters = Object.entries(exterior).map(([exterior_color, count]) =>
filterManager.createExteriorFilter(
{ text: exterior_color, count },
dataStore
)
);
exteriorFilters.sort((a, b) => a.value.localeCompare(b.value));
exteriorFilters.forEach((exterior) => {
exteriorContainer.appendChild(exterior.initCheckbox());
});
}
function initModelContainer(make) {
let list = [
...new Set(
filterManager.makeFilters
.filter((m) => m.checked == true)
.map((m) => m.models)
.flat()
),
];
const modelContainer = document.querySelector('.model-container');
if (list.length === 0) {
modelContainer.innerHTML = '<p>Please Select a Make</p>';
} else if (list && list.length > 0) {
modelContainer.innerHTML = '';
list.sort((a, b) => a.value.localeCompare(b.value));
list.forEach((model) => {
modelContainer.appendChild(model.initCheckbox());
});
} else {
modelContainer.innerHTML = '<p>No models available</p>';
}
}
function initTrimContainer(model) {
let list = [
...new Set(
filterManager.modelFilters
.filter((m) => m.checked == true)
.map((m) => m.trims)
.flat()
),
];
// const uniqueArray = [...new Set(array)];
const trimContainer = document.querySelector('.trim-container');
if (list.length === 0) {
trimContainer.innerHTML = '<p>Please Select a Model</p>';
} else if (list && list.length > 0) {
trimContainer.innerHTML = '';
list.sort((a, b) => a.value.localeCompare(b.value));
list.forEach((trim) => {
trimContainer.appendChild(trim.initCheckbox());
});
} else {
trimContainer.innerHTML = '<p>No trims available</p>';
}
}
function fetchAvailableModels(vehicles, make) {
const filteredModels = vehicles
.filter((vehicle) => vehicle.make === make)
.map((vehicle) => vehicle.model);
// Count occurrences of each model
const modelCounts = filteredModels.reduce((acc, model) => {
acc[model] = (acc[model] || 0) + 1;
return acc;
}, {});
// Convert to an array of objects
const modelsArray = Object.entries(modelCounts).map(([model, count]) => ({
model,
count,
}));
modelsArray.map((m) => (m['trims'] = fetchAvailableTrim(vehicles, m.model)));
return modelsArray;
}
function fetchAvailableTrim(vehicles, modelName) {
const filteredVehicles = vehicles.filter(
(vehicle) => vehicle.model === modelName
);
const trimCount = filteredVehicles.reduce((result, vehicle) => {
vehicle.trim.forEach((trim) => {
const existingTrim = result.find((item) => item.text === trim);
if (existingTrim) {
existingTrim.count += 1;
} else {
result.push({ text: trim, count: 1 });
}
});
return result;
}, []);
return trimCount;
}
function updateModel(models) {
console.log('updateModel', models);
}
function debounce(func, delay) {
let timeout;
return function () {
const context = this;
const args = arguments;
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(context, args), delay);
};
}
function updatePrice() {
const min = price.getValueStart();
const max = price.getValue();
const formattedMin = '$' + min.toLocaleString();
const formattedMax = '$' + max.toLocaleString();
document.getElementById(
'priceRange'
).textContent = `${formattedMin} to ${formattedMax}`;
debouncedSendReq();
}
function updateYear() {
const min = year.getValueStart();
const max = year.getValue();
document.getElementById('yearRange').textContent = `${min} to ${max}`;
debouncedSendReq();
}
function updateMileage() {
const min = kilometres.getValueStart();
const max = kilometres.getValue();
document.getElementById('KilometresRange').textContent = `${min} to ${max}`;
debouncedSendReq();
}
// Create debounced versions of sendReq
const debouncedSendReq = debounce(sendReq, 300);
function createSkeletonCard() {
const skeletonCard = document.createElement('div');
skeletonCard.classList.add(
'bg-red-200',
'rounded-lg',
'shadow-md',
'animate-pulse'
);
const innerHTML = `
<div class="h-40 bg-red-300 rounded-t-lg"></div>
<div class="p-4">
<div class="h-12 bg-red-300 rounded-t-lg"></div>
<div class="h-5 bg-red-400 rounded-t-lg"></div>
<div class="h-5 bg-red-300 rounded-t-lg"></div>
<div class="h-5 bg-red-400 rounded-t-lg"></div>
<div class="h-5 bg-red-300 rounded-b-lg"></div>
</div>
`;
skeletonCard.innerHTML = innerHTML;
return skeletonCard;
}
function createSkeletonListItem() {
const listItem = document.createElement('li');
listItem.classList.add(
'w-full',
'bg-custom-red',
'rounded-lg',
'shadow-md',
'animate-pulse'
);
const innerHTML = `
<div class="flex items-center justify-between p-1">
<div class="h-6 bg-custom-red-light w-2/3 rounded-lg"></div>
<div class="bg-custom-red-light w-1/6 h-6 rounded-lg"></div>
</div>
`;
listItem.innerHTML = innerHTML;
return listItem;
}