theme and plugin sync

This commit is contained in:
2024-03-20 17:38:18 -04:00
commit 03e44e02f0
224 changed files with 56542 additions and 0 deletions

View File

@@ -0,0 +1,300 @@
<?php
/*
Template Name: Autocart Results
*/
get_header();
// Get filter values from URL parameters
$minPrice = isset($_GET['minPrice']) ? sanitize_text_field($_GET['minPrice']): null;
$maxPrice = isset($_GET['maxPrice']) ? sanitize_text_field($_GET['maxPrice']):null;
$minKilometres = isset($_GET['minKilometres']) ? sanitize_text_field($_GET['minKilometres']): null;
$maxKilometres = isset($_GET['maxKilometres']) ? sanitize_text_field($_GET['maxKilometres']):null;
$make = isset($_GET['make']) ? sanitize_text_field($_GET['make']):null;
$minYear = isset($_GET['minYear']) ? (int)sanitize_text_field($_GET['minYear']):null;
$maxYear = isset($_GET['maxYear']) ? (int)sanitize_text_field($_GET['maxYear']):null;
// echo '<pre>';var_dump($minYear);echo '<br>'; var_dump($maxYear);exit;
$startYear = 2012;
$endYear = (int)date('Y');
// Exit the script
// exit;
// Generate nonce
$ajax_nonce = wp_create_nonce("update-filters-ajax-nonce");
$response = get_transient("autocart_response");
?>
<!-- Main Content -->
<div class="flex-grow flex max-w-7xl mx-auto">
<!-- Left Drawer for Filters -->
<aside class="w-1/4 p-4 shadow-lg bg-white hidden md:block rounded">
<div class="mdc-select mdc-select--outlined .col-xl-3 rounded p-2 w-full" id="order-by">
<div class="mdc-select__anchor">
<span class="mdc-notched-outline">
<span class="mdc-notched-outline__leading"></span>
<span class="mdc-notched-outline__notch" style="border-left: none; border-right: none;">
<span id="outlined-select-label" class="mdc-floating-label">Sort By</span>
</span>
<span class="mdc-notched-outline__trailing"></span>
</span>
<span class="mdc-select__selected-text-container">
<span class="mdc-select__selected-text"></span>
</span>
<span class="mdc-select__dropdown-icon">
<svg class="mdc-select__dropdown-icon-graphic" viewBox="7 10 10 5" focusable="false">
<polygon class="mdc-select__dropdown-icon-inactive" stroke="none" fill-rule="evenodd" points="7 10 12 15 17 10"></polygon>
<polygon class="mdc-select__dropdown-icon-active" stroke="none" fill-rule="evenodd" points="7 15 12 10 17 15"></polygon>
</svg>
</span>
</div>
<div class="mdc-select__menu mdc-menu mdc-menu-surface mdc-menu-surface--fullwidth">
<ul class="mdc-list" role="listbox" aria-label="Sort By" id="sort-options-list">
<!-- Options will be dynamically added here using JavaScript -->
</ul>
</div>
</div>
<div class="space-y-2">
<!-- Panel 1 -->
<div class="border rounded p-2">
<div class="flex justify-between items-center p-4">
<div class="w-full text-left focus:outline-none transition"> Price </div>
<svg class="w-4 h-4 hover:bg-gray-200" fill="none" stroke="currentColor" viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M19 9l-7 7-7-7"></path>
</svg>
</div>
<div class="mt-2">
<div class="flex justify-center items-center">
<span id="priceRange" class="slider-readings"> <?php echo '$' . number_format($minPrice) . ' to $' . number_format($maxPrice) ?> </span></div>
<div class="mdc-slider mdc-slider--range" id="autocart-price-range-field">
<input class="mdc-slider__input" type="range" min="10000" max="80000" value="
<?php echo isset($minPrice)? $minPrice: 10000 ?>" name="rangeStart" aria-label="Continuous range slider demo">
<input class="mdc-slider__input" type="range" min="10000" max="80000" value="<?php echo isset($maxPrice)? $maxPrice: 80000 ?>" name="rangeEnd" aria-label="Continuous range slider demo">
<div class="mdc-slider__track">
<div class="mdc-slider__track--inactive"></div>
<div class="mdc-slider__track--active">
<div class="mdc-slider__track--active_fill"></div>
</div>
</div>
<div class="mdc-slider__thumb">
<div class="mdc-slider__thumb-knob"></div>
</div>
<div class="mdc-slider__thumb">
<div class="mdc-slider__thumb-knob"></div>
</div>
</div>
</div>
</div>
<!-- Panel 2 -->
<div class="border rounded p-2">
<div class="flex justify-between items-center p-4">
<div class="w-full text-left focus:outline-none transition"> Year </div>
<svg class="w-4 h-4 hover:bg-gray-200" fill="none" stroke="currentColor" viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M19 9l-7 7-7-7"></path>
</svg>
</div>
<div class="mt-2">
<div class="flex justify-center items-center">
<span id="yearRange" class="slider-readings"> <?php echo $minYear .' to '.$maxYear; ?> </span>
</div>
<div class="mdc-slider mdc-slider--range" id="autocart-year-range-field">
<input class="mdc-slider__input" type="range" min="<?php echo $startYear ?>" max="<?php echo $endYear ?>" value="<?php echo isset($minYear) ? $minYear : $startYear ?>" name="rangeStart" aria-label="Continuous range slider demo">
<input class="mdc-slider__input" type="range" min="<?php echo $startYear ?>" max="<?php echo $endYear ?>" value="<?php echo isset($maxYear) ? $maxYear : $endYear ?>" name="rangeEnd" aria-label="Continuous range slider demo">
<div class="mdc-slider__track">
<div class="mdc-slider__track--inactive"></div>
<div class="mdc-slider__track--active">
<div class="mdc-slider__track--active_fill"></div>
</div>
</div>
<div class="mdc-slider__thumb">
<div class="mdc-slider__thumb-knob"></div>
</div>
<div class="mdc-slider__thumb">
<div class="mdc-slider__thumb-knob"></div>
</div>
</div>
</div>
</div>
<!-- Panel 3 -->
<div class="border rounded p-2">
<div class="flex justify-between items-center p-4">
<div class="w-full text-left focus:outline-none transition"> Kilometres </div>
<svg class="w-4 h-4 hover:bg-gray-200" fill="none" stroke="currentColor" viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M19 9l-7 7-7-7"></path>
</svg>
</div>
<div class="mt-2">
<div class="flex justify-center items-center">
<span id="KilometresRange" class="slider-readings">19000 to 222000 </span>
</div>
<div class="mdc-slider mdc-slider--range" id="autocart-kilometres-range-field">
<input class="mdc-slider__input" type="range" min="19000" max="222000" value="19000" name="rangeStart" aria-label="Continuous range slider demo">
<input class="mdc-slider__input" type="range" min="19000" max="222000" value="222000" name="rangeEnd" aria-label="Continuous range slider demo">
<div class="mdc-slider__track">
<div class="mdc-slider__track--inactive"></div>
<div class="mdc-slider__track--active">
<div class="mdc-slider__track--active_fill"></div>
</div>
</div>
<div class="mdc-slider__thumb">
<div class="mdc-slider__thumb-knob"></div>
</div>
<div class="mdc-slider__thumb">
<div class="mdc-slider__thumb-knob"></div>
</div>
</div>
</div>
</div>
<!-- Panel 4 -->
<div class="border rounded p-2">
<div class="flex justify-between items-center p-4">
<div class="w-full text-left focus:outline-none transition"> Make </div>
<svg class="w-4 h-4 hover:bg-gray-200" fill="none" stroke="currentColor" viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M19 9l-7 7-7-7"></path>
</svg>
</div>
<div class="mt-2">
<ul class="make-container list-none text-gray-900 w-48 bg-white text-sm font-medium rounded-lg w-full">
</ul>
</div>
</div>
<div class="border rounded p-2">
<div class="flex justify-between items-center p-4">
<div class="w-full text-left focus:outline-none transition"> Model </div>
<svg class="w-4 h-4 hover:bg-gray-200" fill="none" stroke="currentColor" viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M19 9l-7 7-7-7"></path>
</svg>
</div>
<div class="mt-2">
<ul class="model-container list-none text-gray-900 w-48 bg-white text-sm font-medium rounded-lg w-full">
<p>Please Select a Make.</p>
</ul>
</div>
</div>
<div class="border rounded p-2">
<div class="flex justify-between items-center p-4">
<div class="w-full text-left focus:outline-none transition"> Trim </div>
<svg class="w-4 h-4 hover:bg-gray-200" fill="none" stroke="currentColor" viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M19 9l-7 7-7-7"></path>
</svg>
</div>
<div class="mt-2">
<ul class="trim-container list-none text-gray-900 bg-white text-sm font-medium rounded-lg w-full">
<p>Please Select a Model.</p>
</ul>
</div>
</div>
<div class="border rounded p-2">
<div class="flex justify-between items-center p-4">
<div class="w-full text-left focus:outline-none transition"> Body Style </div>
<svg class="w-4 h-4 hover:bg-gray-200" fill="none" stroke="currentColor" viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M19 9l-7 7-7-7"></path>
</svg>
</div>
<div class="mt-2">
<ul class="body-type-container list-none text-gray-900 bg-white text-sm font-medium rounded-lg w-full">
</ul>
</div>
</div>
<div class="border rounded p-2">
<div class="flex justify-between items-center p-4">
<div class="w-full text-left focus:outline-none transition"> Transmission </div>
<svg class="w-4 h-4 hover:bg-gray-200" fill="none" stroke="currentColor" viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M19 9l-7 7-7-7"></path>
</svg>
</div>
<div class="mt-2">
<ul class="transmission-container list-none text-gray-900 bg-white text-sm font-medium rounded-lg w-full">
</ul>
</div>
</div>
<div class="border rounded p-2">
<div class="flex justify-between items-center p-4">
<div class="w-full text-left focus:outline-none transition"> Exterior Color </div>
<svg class="w-4 h-4 hover:bg-gray-200" fill="none" stroke="currentColor" viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M19 9l-7 7-7-7"></path>
</svg>
</div>
<div class="mt-2">
<ul class="exterior-color list-none text-gray-900 bg-white text-sm font-medium rounded-lg w-full">
</ul>
</div>
</div>
</div>
<!-- Add more filters as needed -->
</aside>
<!-- Main Content -->
<div class="w-3/4 ml-1/4 p-4 pb-0 flex-grow">
<!-- Top App Bar with Menu Button -->
<header class="shadow-lg bg-white p-4 flex justify-between items-center rounded">
<div class="mt-2" id="applied-filters-block"></div>
<div class="flex items-center space-x-4">
<i id="grid-view" class="fas fa-th text-gray-500 cursor-pointer transition duration-300 transform hover:scale-110 hover:shadow-md ripple selected"></i>
<i id="list-view" class="fas fa-list text-gray-500 cursor-pointer transition duration-300 transform hover:scale-110 hover:shadow-md ripple"></i>
</div>
</header>
<!-- Vehicle List -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 mt-4 vehicles-container">
<!-- Vehicle Cards go here -->
</div>
</div>
</div>
<?php
wp_nonce_field('autocart_nonce', 'autocart_nonce'); ?> <?php get_footer();
if ($make) {
echo "<input type='hidden' id='autocart-make-field' value='$make'>";
} ?>
<script>
document.addEventListener('DOMContentLoaded', function () {
price = new mdc.slider.MDCSlider(document.querySelector('#autocart-price-range-field'));
year = new mdc.slider.MDCSlider(document.querySelector('#autocart-year-range-field'));
kilometres = new mdc.slider.MDCSlider(document.querySelector('#autocart-kilometres-range-field'));
price.listen('MDCSlider:input', updatePrice);
year.listen('MDCSlider:input', updateYear);
kilometres.listen('MDCSlider:input', updateMileage);
new DisplayMode();
dataStore = new DataStore([]);
new SortBy(dataStore);
sendReq();
});
</script>

View File

@@ -0,0 +1,455 @@
<?php
$priceRanges = [
[
'text' => 'All Prices',
'value' => [10000, 80000],
],
[
'text' => 'Under $10,000',
'value' => [0, 10000],
],
[
'text' => '$10,000 - $19,999',
'value' => [10000, 19000],
],
[
'text' => '$20,000 - $29,999',
'value' => [20000, 29000],
],
[
'text' => '$30,000 - $39,999',
'value' => [30000, 39000],
],
[
'text' => '$40,000 - $49,999',
'value' => [40000, 49000],
],
[
'text' => '$50,000 - $59,999',
'value' => [50000, 59000],
],
[
'text' => '$60,000 - $69,999',
'value' => [60000, 69000],
],
[
'text' => '$70,000 - $79,999',
'value' => [70000, 80000],
],
];
$startYear = 2012;
$endYear = (int)date('Y');
$years = range($startYear, $endYear);
array_unshift($years, 'All Years');
// Transform the array into an array of objects
$years = array_map(function ($year) use ($startYear, $endYear) {
if ($year == 'All Years') {
return ['text' => $year, 'value' => [$startYear, $endYear]];
} else {
return ['text' => $year, 'value' => [$year, $year]];
}
}, $years);
$carMakes = [
"All Makes", "Acura", "Audi", "BMW", "Ford", "GMC",
"Honda", "Hyundai", "Jaguar", "Jeep", "Kia",
"Lexus", "Mazda", "Mercedes-Benz", "Tesla", "Toyota", "Volkswagen"
];
?>
<form id="vehicle-search-form" name="vehicle-search-form" method="get" action="<?php echo esc_url(home_url('/index.php/autocart-results')); ?>" class="w-full bg-white px-6 lg:px-8 py-10 rounded-md">
<h2 class="text-xl lg:text-3xl font-bold mb-2 uppercase">Find your vehicle</h2>
<div class="sm:grid sm:grid-cols-2 gap-4">
<div>
<label class="block mb-2 text-sm font-medium text-gray-700" for="vehicle_search_make">Make</label>
<select class="w-full px-3 py-2 border rounded-md text-gray-700 focus:outline-none focus:border-red-500" id="vehicle_search_make" name="vehicle_search_make">
<?php foreach ($carMakes as $index => $make) : ?>
<option value="<?= strtolower(str_replace(' ', '', $make)); ?>" <?= $index === 0 ? 'selected' : ''; ?>>
<?= $make; ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div>
<label class="block mb-2 text-sm font-medium text-gray-700" for="vehicle_search_model">Model</label>
<select class="w-full px-3 py-2 border rounded-md text-gray-700 focus:outline-none focus:border-red-500" id="vehicle_search_model" name="vehicle_search_model">
<option value="" disabled="" selected="">Select Model</option>
<!-- <option value="Camry">Camry</option>
<option value="Accord">Accord</option>
<option value="F-150">F-150</option>
<option value="Silverado">Silverado</option>
<option value="Altima">Altima</option> -->
</select>
</div>
<div>
<label class="block mb-2 text-sm font-medium text-gray-700" for="vehicle_search_year">Year</label>
<select class="w-full px-3 py-2 border rounded-md text-gray-700 focus:outline-none focus:border-red-500" id="vehicle_search_year" name="vehicle_search_year">
<?php foreach ($years as $index => $year) : ?>
<option value="<?= htmlspecialchars(json_encode($year['value'])); ?>" <?= $index === 0 ? 'selected' : ''; ?>>
<?= $year['text']; ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div>
<label class="block mb-2 text-sm font-medium text-gray-700" for="vehicle_search_body_type">Body Type</label>
<select class="w-full px-3 py-2 border rounded-md text-gray-700 focus:outline-none focus:border-red-500" id="vehicle_search_body_type" name="vehicle_search_body_type">
<option value="" disabled="" selected="">Select Body Type</option>
<!-- <option value="Sedan">Sedan</option>
<option value="SUV">SUV</option>
<option value="Truck">Truck</option>
<option value="Hatchback">Hatchback</option>
<option value="Coupe">Coupe</option> -->
</select>
</div>
<div>
<label class="block mb-2 text-sm font-medium text-gray-700" for="vehicle_search_transmission">Transmission</label>
<select class="w-full px-3 py-2 border rounded-md text-gray-700 focus:outline-none focus:border-red-500" id="vehicle_search_transmission" name="vehicle_search_transmission">
<option value="" disabled="" selected="">Select Transmission</option>
<!-- <option value="Automatic">Automatic</option>
<option value="Manual">Manual</option>
<option value="CVT">CVT</option> -->
</select>
</div>
<div>
<label class="block mb-2 text-sm font-medium text-gray-700" for="vehicle_search_trim">Trim</label>
<select class="w-full px-3 py-2 border rounded-md text-gray-700 focus:outline-none focus:border-red-500" id="vehicle_search_trim" name="vehicle_search_trim">
<option value="" disabled="" selected="">Select Trim</option>
<!-- <option value="LE">LE</option>
<option value="EX">EX</option>
<option value="XLT">XLT</option>
<option value="LT">LT</option>
<option value="SV">SV</option> -->
</select>
</div>
<div class="flex flex-col col-span-2">
<div>
<label class="block mb-2 text-sm font-medium text-gray-700" for="autocart-kilometres-range-field">Kilometers</label>
<!-- <input class="w-full px-3 py-2 border rounded-md text-gray-700 focus:outline-none focus:border-red-500" type="hidden" id="autocart-kilometres-range-field" name="autocart-kilometres-range-field" min="16000" max="200000"> -->
</div>
<div class="range-container">
<div class="mdc-slider mdc-slider--range" id="autocart-kilometres-range-field">
<input class="mdc-slider__input" type="range" min="19000" max="222000" value="19000" name="rangeStart" aria-label="Continuous range slider demo">
<input class="mdc-slider__input" type="range" min="19000" max="222000" value="222000" name="rangeEnd" aria-label="Continuous range slider demo">
<div class="mdc-slider__track">
<div class="mdc-slider__track--inactive"></div>
<div class="mdc-slider__track--active">
<div class="mdc-slider__track--active_fill"></div>
</div>
</div>
<div class="mdc-slider__thumb">
<div class="mdc-slider__thumb-knob"></div>
</div>
<div class="mdc-slider__thumb">
<div class="mdc-slider__thumb-knob"></div>
</div>
</div>
<label class="block mb-2 text-sm font-medium text-white-700 range-label" for="autocart-kilometres-range-field">19000 to 222000</label>
</div>
<div>
<label class="block mb-2 text-sm font-medium text-gray-700" for="autocart-price-range-field">Price</label>
<!-- <input class="w-full px-3 py-2 border rounded-md text-gray-700 focus:outline-none focus:border-red-500" type="hidden" id="vehicle_search_price" name="vehicle_search_price" min="5000" max="70000"> -->
</div>
<div class="range-container">
<?php
$minPrice = $priceRanges[0]['value'][0];
$maxPrice = $priceRanges[count($priceRanges) - 1]['value'][1]; ?>
<div class="mdc-slider mdc-slider--range" id="autocart-price-range-field">
<input class="mdc-slider__input" type="range" min="<?php echo $minPrice; ?>" max="<?php echo $maxPrice; ?>" value="<?php echo isset($minPrice) ? $minPrice : 10000; ?>" name="rangeStart" aria-label="Continuous range slider demo">
<input class="mdc-slider__input" type="range" min="<?php echo $minPrice; ?>" max="<?php echo $maxPrice; ?>" value="<?php echo isset($maxPrice) ? $maxPrice : 80000; ?>" name="rangeEnd" aria-label="Continuous range slider demo">
<div class="mdc-slider__track">
<div class="mdc-slider__track--inactive"></div>
<div class="mdc-slider__track--active">
<div class="mdc-slider__track--active_fill"></div>
</div>
</div>
<div class="mdc-slider__thumb">
<div class="mdc-slider__thumb-knob"></div>
</div>
<div class="mdc-slider__thumb">
<div class="mdc-slider__thumb-knob"></div>
</div>
</div>
<label class="block mb-2 text-sm font-medium text-white-700 range-label" for="autocart-price-range-field"><?php echo '$' . number_format($minPrice) . ' to $' . number_format($maxPrice) ?></label>
</div>
</div>
<input type="hidden" name="maxPrice" id="autocart-max-price-field-input" />
<input type="hidden" name="minPrice" id="autocart-min-price-field-input" />
<input type="hidden" name="maxYear" id="autocart-max-year-field-input" />
<input type="hidden" name="minYear" id="autocart-min-year-field-input" />
<input type="hidden" name="make" id="autocart-make-field-input" />
<?php wp_nonce_field('autocart_nonce', 'autocart_nonce'); ?>
<div class="lg:col-span-2">
<button type="submit" aria-label="Find Your Vehicle Search" class="w-full bg-red-500 hover:bg-red-800 transition-colors duration-300 text-white font-medium py-2 px-4 rounded" id="inventory-search-button">
<i class="bi-search mr-2"></i>Search
</button>
</div>
</div>
</form>
<script>
let priceWidget;
document.addEventListener('DOMContentLoaded', function() {
priceWidget = new mdc.slider.MDCSlider(document.querySelector('#autocart-price-range-field'));
priceWidget.listen('MDCSlider:input', updatePiceWidget);
kilometresWidget = new mdc.slider.MDCSlider(document.querySelector('#autocart-kilometres-range-field'));
kilometresWidget.listen('MDCSlider:input', updateMileageWidget);
const year = document.querySelector('#vehicle_search_year');
const make = document.querySelector('#vehicle_search_make');
const model = document.querySelector('#vehicle_search_model');
// Initial AJAX request on document ready
handleFieldChange([{
property: 'body_type',
name: 'Body Type',
selector: '#vehicle_search_body_type'
},
{
property: 'transmission_type',
name: 'Transmission',
selector: '#vehicle_search_transmission'
},
{
property: 'make',
name: 'Make',
selector: '#vehicle_search_make'
},
{
property: 'model',
name: 'Model',
selector: '#vehicle_search_model'
}
]);
year.addEventListener('change', function() {
debouncedHandleFieldChange([{
property: 'body_type',
name: 'Body Type',
selector: '#vehicle_search_body_type'
},
{
property: 'transmission_type',
name: 'Transmission',
selector: '#vehicle_search_transmission'
},
{
property: 'make',
name: 'Make',
selector: '#vehicle_search_make'
},
{
property: 'model',
name: 'Model',
selector: '#vehicle_search_model'
}
])
});
make.addEventListener('change', function() {
debouncedHandleFieldChange([{
property: 'model',
name: 'Model',
selector: '#vehicle_search_model'
},
{
property: 'body_type',
name: 'Body Type',
selector: '#vehicle_search_body_type'
},
{
property: 'transmission_type',
name: 'Transmission',
selector: '#vehicle_search_transmission'
},
])
});
model.addEventListener('change', function() {
debouncedHandleFieldChange([{
property: 'trim',
name: 'Tim',
selector: '#vehicle_search_trim'
}])
});
const btns = document.getElementsByClassName("ripple-effect");
for (const btn of btns) {
btn.addEventListener("click", rippleEffect);
}
});
function updateMileageWidget() {
document.querySelector('label.range-label[for="autocart-kilometres-range-field"]').textContent = `${kilometresWidget.getValueStart()} to ${kilometresWidget.getValue()}`;
debouncedHandleFieldChange();
}
function updatePiceWidget() {
document.querySelector('label.range-label[for="autocart-price-range-field"]').textContent = `${priceWidget.getValueStart()} to ${priceWidget.getValue()}`;
debouncedHandleFieldChange();
}
function debounce(func, delay) {
let timeout;
return function() {
const context = this;
const args = arguments;
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(context, args), delay);
};
}
const debouncedHandleFieldChange = debounce(
function(inputs) {
handleFieldChange(inputs);
}, 300);
function handleFieldChange(inputs = []) {
// const price = document.querySelector('#autocart-price-field');
const year = document.querySelector('#vehicle_search_year');
const make = document.querySelector('#vehicle_search_make');
// let priceRange = JSON.parse(priceWidget.value);
// let minPrice = priceRange[0];
// let maxPrice = priceRange[1];
let yearRange = JSON.parse(year.value);
console.log('yearRange', yearRange)
let minYear = yearRange[0];
let maxYear = yearRange[1];
document.getElementById('autocart-max-price-field-input').value = priceWidget.getValue();;
document.getElementById('autocart-min-price-field-input').value = priceWidget.getValueStart();
document.getElementById('autocart-max-year-field-input').value = maxYear;
document.getElementById('autocart-min-year-field-input').value = minYear;
document.getElementById('autocart-make-field-input').value = make.value;
// var formData = {
// 'action': 'handle_autocart_form',
// 'minPrice': priceWidget.getValueStart(),
// 'maxPrice': priceWidget.getValue(),
// 'make': make.value,
// 'minYear': minYear,
// 'maxYear': maxYear,
// 'autocart_nonce': jQuery('#autocart_nonce').val(),
// };
var formData = {
'action': 'handle_autocart_form',
'minPrice': priceWidget.getValueStart(),
'maxPrice': priceWidget.getValue(),
'minKilometres': kilometresWidget.getValueStart(),
'maxKilometres': kilometresWidget.getValue(),
'minYear': minYear,
'maxYear': maxYear,
'make': make.value,
'autocart_nonce': jQuery('#autocart_nonce').val(),
};
jQuery("#inventory-search-button").text("Loading...");
jQuery.ajax({
type: 'POST',
url: ajax_object.ajax_url,
data: formData,
success: function(response) {
const vehicles = response.data.vehicles;
if (inputs) {
inputs.forEach(element => {
createOptions(vehicles, element);
});
}
jQuery("#inventory-search-button").text("Search (" + vehicles.length + ")");
},
error: function(xhr, status, error) {
console.log(xhr.responseText);
console.log('Status: ' + status);
console.log('Error: ' + error);
jQuery("#inventory-search-button").text("Error");
}
});
}
function rippleEffect(event) {
const btn = event.currentTarget;
btn.classList.add("overflow-hidden", "shadow", "relative");
const circle = document.createElement("span");
const rect = btn.getBoundingClientRect();
const diameter = Math.max(btn.clientWidth, btn.clientHeight);
const radius = diameter / 2;
const offsetX = event.clientX - rect.left;
const offsetY = event.clientY - rect.top;
circle.style.width = circle.style.height = `${diameter}px`;
circle.style.left = `${offsetX - radius}px`;
circle.style.top = `${offsetY - radius}px`;
circle.classList.add("ripple");
const ripple = btn.getElementsByClassName("ripple")[0];
if (ripple) {
ripple.remove();
}
btn.appendChild(circle);
}
function createOptions(vehicles, input) {
if (vehicles.length) {
const element = document.querySelector(input.selector);
// Remove existing options only
const existingOptions = element.querySelectorAll('option');
existingOptions.forEach(option => option.remove());
const counts = vehicles.reduce((acc, vehicle) => {
const value = vehicle[input.property];
acc[value] = (acc[value] || 0) + 1;
return acc;
}, {});
// Sort the property values alphabetically
const sortedValues = Object.keys(counts).sort();
// Add "All" at the beginning
sortedValues.unshift(`All ${input.name}s`);
// Create and append options
sortedValues.forEach(value => {
var option = document.createElement("option");
option.text = value;
option.value = value;
option.style.textTransform = "capitalize";
element.appendChild(option);
});
}
}
</script>

View File

@@ -0,0 +1,689 @@
<?php
/*
Template Name: Vehicle Template
*/
get_header();
?>
<style>
.modal {
transition: opacity 0.25s ease;
}
body.modal-active {
overflow-x: hidden;
overflow-y: visible !important;
}
span.ripple {
position: absolute;
border-radius: 50%;
transform: scale(0);
animation: ripple 600ms linear;
background-color: rgba(255, 255, 255, 0.7);
}
@keyframes ripple {
to {
transform: scale(4);
opacity: 0;
}
}
</style>
<?php
// Retrieve the autocart response data
$vehicle_id = isset($_GET['vehicle_id']) ? urldecode($_GET['vehicle_id']) : '';
if ($vehicle_id) {
// Retrieve the external token from WordPress options
$external_token = get_option('autocart_server_token');
$pluginToken = get_option('autocart_plugin_token'); // Retrieve the token from where you stored it
if ($external_token) {
// Make an external request to get vehicle details
$vehicle_details_url = REMOTE_SERVER_URL . '/api/v1/wp/vehicle/' . $vehicle_id;
$vehicle_details_response = wp_remote_get($vehicle_details_url, array(
'headers' => array(
'Authorization' => $external_token,
'Plugin' => $pluginToken
),
));
// Make another request to get vehicle images
$vehicle_images_url = REMOTE_SERVER_URL . '/api/v1/companies/1/vehicles/' . $vehicle_id . '/images';
$vehicle_images_response = wp_remote_get($vehicle_images_url, array(
'headers' => array(
'Authorization' => $external_token,
'Plugin' => $pluginToken
),
));
$vehicle_features = REMOTE_SERVER_URL . '/api/v1/companies/1/vehicles/' . $vehicle_id . '/vehiclefeatures';
$vehicle_features_response = wp_remote_get($vehicle_features, array(
'headers' => array(
'Authorization' => $external_token,
'Plugin' => $pluginToken
),
));
if (
!is_wp_error($vehicle_details_response) && !is_wp_error($vehicle_images_response)
&& wp_remote_retrieve_response_code($vehicle_details_response) === 200
&& wp_remote_retrieve_response_code($vehicle_images_response) === 200
&& wp_remote_retrieve_response_code($vehicle_features_response) === 200
) {
// Decode and print the vehicle details response
$vehicle_details = json_decode(wp_remote_retrieve_body($vehicle_details_response), true);
$vehicle_features = json_decode(wp_remote_retrieve_body($vehicle_features_response), true);
// Decode and print the vehicle images response
$vehicle_images = json_decode(wp_remote_retrieve_body($vehicle_images_response), true);
// var_dump($searchData); exit;
$filters = array(
'body_type' => $vehicle_details['body_type']
);
$similar_vehicles_response = wp_remote_post(REMOTE_SERVER_URL . '/api/v1/wp', array(
'body' => json_encode($filters), // The filters array will be sent in the body of the request
'headers' => array(
'Content-Type' => 'application/json', // Make sure to set the Content-Type header appropriately
'Authorization' => $external_token,
'Plugin' => $pluginToken
),
));
if (!is_wp_error($similar_vehicles_response) && wp_remote_retrieve_response_code($similar_vehicles_response) === 200) {
$similar_vehicles = json_decode(wp_remote_retrieve_body($similar_vehicles_response), true);
$filtered_vehicles = array_filter($similar_vehicles, function ($vehicle) use ($vehicle_details) {
return $vehicle['id_vehicle'] !== $vehicle_details['id_vehicle'];
});
// echo '<pre>';
// print_r($filtered_vehicles);
// echo '</pre>';
}
// Initialize an empty array to store grouped features
$groupedFeatures = array();
// Loop through the features and group them by category
foreach ($vehicle_features as $feature) {
$category = $feature['category'];
// Check if the category key exists in the grouped array
if (!array_key_exists($category, $groupedFeatures)) {
// If not, create an empty array for the category
$groupedFeatures[$category] = array();
}
// Add the feature to the corresponding category
$groupedFeatures[$category][] = $feature;
}
// Now $groupedFeatures contains features grouped by category
// print_r($groupedFeatures);
// echo '<pre>';
// print_r($searchData);
// echo '</pre>';
} else {
echo '<div class="bg-gray-100 dark:bg-gray-800 py-8">
<div class="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex flex-col md:flex-row"><p>Error retrieving vehicle details or images.</p></div></div</div>';
exit;
}
} else {
echo '<div class="bg-gray-100 dark:bg-gray-800 py-8">
<div class="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex flex-col md:flex-row"><p>Error: External token not found.</p>/div></div</div>';
exit;
}
} else {
echo '<div class="bg-gray-100 dark:bg-gray-800 py-8">
<div class="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex flex-col md:flex-row"><p>No vehicle found.</p></div></div</div>';
exit;
} ?>
<?php
// Assuming you have the images in the $vehicle_images array
$image_title = !empty($vehicle_images[0]['title']) ? $vehicle_images[0]['title'] : '';
$image_description = !empty($vehicle_images[0]['description']) ? $vehicle_images[0]['description'] : '';
?>
<div class="max-w-7xl mx-auto">
<div class="grid grid-cols-2">
<div class="relative group cursor-pointer">
<img src="<?php echo $vehicle_images[0]['url']; ?>" alt="<?php echo $image_title; ?>" class="w-full h-full object-cover">
<div class="absolute inset-0 bg-black opacity-0 group-hover:opacity-75 transition duration-500 ease-in-out"></div>
<div class="absolute inset-0 bottom-0 p-4 text-white group-hover:opacity-100 transition duration-500 ease-in-out" onclick="showFeaturedImage(0);openFeaturedImage()">
<h3><?php echo $image_title; ?></h3>
<p><?php echo $image_description; ?></p>
</div>
</div>
<div class="relative grid grid-cols-2">
<?php
$end = (!empty($vehicle_images) && count($vehicle_images) >= 5) ? 5 : count($vehicle_images);
// Start loop from index 1 to skip the first image
for ($i = 1; $i < $end; $i++) {
$image = $vehicle_images[$i];
// Extract image URL, title, and description
$image_url = $image['url'];
?>
<div class="relative group cursor-pointer">
<img src="<?php echo $image_url; ?>" alt="<?php echo $image_title; ?>" class="w-full h-full object-cover">
<div class="absolute inset-0 bg-black opacity-0 group-hover:opacity-75 transition duration-500 ease-in-out"></div>
<div class="absolute inset-0 bottom-0 p-4 text-white group-hover:opacity-100 transition duration-500 ease-in-out" onclick="showFeaturedImage(<?php echo $i; ?>);openFeaturedImage()">
<h3><?php echo $image_title; ?></h3>
<p><?php echo $image_description; ?></p>
</div>
</div>
<?php
}
?>
</div>
</div>
<div class="bg-gray-100 dark:bg-gray-800 py-4">
<!-- Single Car Information -->
<div class="lg:grid grid-cols-3 relative">
<!-- Vehicle Details -->
<div class="mx-auto col-span-2">
<!-- Single Car -->
<div class="m-4">
<h2 class="text-2xl font-bold text-gray-800 dark:text-white mb-2">
<!-- title -->
<?php echo $vehicle_details['year'] . ' ' . $vehicle_details['make'] . ' ' . $vehicle_details['model'] . ' ' . $vehicle_details['trim'] . ' - ' . $vehicle_details['exterior_color'] . ' ' . $vehicle_details['interior_color']; ?>
</h2>
<p> Stock #: <?php echo $vehicle_details['stock_number'] ?></p>
<hr class="my-4 border-gray-300">
<span class="font-bold text-gray-700 dark:text-gray-300">About this vehicle</span>
<div class="flex items-center mt-4">
<div class="text-gray-900 bg-white border border-gray-200 rounded-lg dark:bg-gray-700 dark:border-gray-600 dark:text-white">
<button type="button" class="relative inline-flex items-center w-full px-4 py-2 text-sm font-medium border-b border-gray-200 hover:bg-gray-100 hover:text-black-700 dark:border-gray-600 dark:hover:bg-gray-600 dark:hover:text-white text-black flex-row gap-2">
<i class="fas fa-tachometer-alt w-3 h-3 me-3"></i>
<span class="label">Kilometres</span>
<span class="value"><?php echo number_format($vehicle_details['mileage']) ?></span>
</button>
<button type="button" class="relative inline-flex items-center w-full px-4 py-2 text-sm font-medium border-b border-gray-200 hover:bg-gray-100 hover:text-black-700 dark:border-gray-600 dark:hover:bg-gray-600 dark:hover:text-white text-black flex-row gap-2">
<i class="fas fa-car-side w-3 h-3 me-3"></i>
<span class="label">Body Style</span>
<span class="value"><?php echo $vehicle_details['body_type'] ?></span>
</button>
<button type="button" class="relative inline-flex items-center w-full px-4 py-2 text-sm font-medium border-b border-gray-200 hover:bg-gray-100 hover:text-black-700 dark:border-gray-600 dark:hover:bg-gray-600 dark:hover:text-white text-black flex-row gap-2">
<i class="fas fa-cogs w-3 h-3 me-3"></i>
<span class="label">Engine</span>
<span class="value"><?php echo $vehicle_details['engine'] ?></span>
</button>
<button type="button" class="relative inline-flex items-center w-full px-4 py-2 text-sm font-medium border-b border-gray-200 hover:bg-gray-100 hover:text-black-700 dark:border-gray-600 dark:hover:bg-gray-600 dark:hover:text-white text-black flex-row gap-2">
<i class="fas fa-palette w-3 h-3 me-3"></i>
<span class="label">Exterior Colour</span>
<span class="value"><?php echo $vehicle_details['exterior_color'] ?></span>
</button>
<button type="button" class="relative inline-flex items-center w-full px-4 py-2 text-sm font-medium border-b border-gray-200 hover:bg-gray-100 hover:text-black-700 dark:border-gray-600 dark:hover:bg-gray-600 dark:hover:text-white text-black flex-row gap-2">
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 122.88 122.88" width="20" height="20">
<path d="M61.44,0A61.46,61.46,0,1,1,18,18,61.23,61.23,0,0,1,61.44,0Zm4.07,82.09a6.67,6.67,0,1,1-8.14,0V68.62H42.31V82.09a6.67,6.67,0,1,1-8.14,0V46.17a6.67,6.67,0,1,1,8.14,0V60.48H57.37V46.17a6.67,6.67,0,1,1,8.14,0V60.48H80.57V46.17a6.67,6.67,0,1,1,8.14,0V64a4.41,4.41,0,0,1,0,.52,4.07,4.07,0,0,1-4.07,4.07H65.51V82.09Zm33-57.76a52.46,52.46,0,1,0,15.38,37.11A52.29,52.29,0,0,0,98.55,24.33Z" />
</svg>
<span class="label">Transmission</span>
<span class="value"><?php echo $vehicle_details['transmission_type'] ?></span>
</button>
<button type="button" class="relative inline-flex items-center w-full px-4 py-2 text-sm font-medium border-b border-gray-200 hover:bg-gray-100 hover:text-black-700 dark:border-gray-600 dark:hover:bg-gray-600 dark:hover:text-white text-black flex-row gap-2">
<i class="fas fa-users w-3 h-3 me-3"></i>
<span class="label"># of Passengers</span>
<span class="value"><?php echo $vehicle_details['optional_seating'] ?></span>
</button>
<button type="button" class="relative inline-flex items-center w-full px-4 py-2 text-sm font-medium border-b border-gray-200 hover:bg-gray-100 hover:text-black-700 dark:border-gray-600 dark:hover:bg-gray-600 dark:hover:text-white text-black flex-row gap-2">
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 122.88 63.67" width="20" height="10">
<path d="M7.69,25.88c-8.3-4.22-7.35-8.92,1-8.43L10.55,21,14.4,9c1.51-4.71,4-9,9-9H66.89c4.24,0,6.94,3.09,8.37,7A9.88,9.88,0,0,1,79,6.69h24.8c3.38,0,6.2.12,9.29,2.32a12.64,12.64,0,0,1,2.66,2.57,32.64,32.64,0,0,1,3.39,6.15l3.2,6.66a2.53,2.53,0,0,1,.25,2.64l-2.52,8.19c-.2.45-.6.64-1.29.5a10.51,10.51,0,0,0-11.6,9c-.06.53,0,1.22-.44,1.54a1.48,1.48,0,0,1-1.09.15H87.15c-.1,2.72-.3,5.83-.52,9.46v5a2.81,2.81,0,0,1-2.81,2.8h-12a2.81,2.81,0,0,1-2.81-2.8V58.62H18.18v2.25a2.82,2.82,0,0,1-2.81,2.8H3.4a2.81,2.81,0,0,1-2.8-2.8V54.4a3,3,0,0,1,0-.43c-.91-11.62-2.19-22.1,7.06-28.09ZM86.78,37.44H85.31a.84.84,0,0,0-.85,1,1.07,1.07,0,0,0,1,1h19.89a.83.83,0,0,0,.84-1h0a1.07,1.07,0,0,0-1-1Zm-2.32,1ZM79.27,11h27.56a7.4,7.4,0,0,1,4.78,3.28l5.5,11.26.11,1.07H83.3L79.27,11Zm32.41,19.19h5.37a1.07,1.07,0,0,1,1,1h0a.83.83,0,0,1-.84.95h-5.37a1.07,1.07,0,0,1-1-.95h0a.83.83,0,0,1,.84-1ZM23,39.66,12.34,38.32C9.83,38,9.16,39.1,10,41.26l1.15,2.79a4.06,4.06,0,0,0,1.44,1.61,4.82,4.82,0,0,0,2.38.65l9.48.08c2.29,0,3.28-.92,2.56-3A5.11,5.11,0,0,0,23,39.66Zm41.27,0,10.63-1.34c2.51-.28,3.19.78,2.33,2.94l-1.15,2.79a4.06,4.06,0,0,1-1.44,1.61,4.82,4.82,0,0,1-2.38.65l-9.48.08c-2.29,0-3.28-.92-2.56-3a5.13,5.13,0,0,1,4-3.71ZM14.54,23.59h60l-2.9-12c-.79-3.66-3.08-6.84-6.84-6.84H25c-3.76,0-5.69,3.26-6.85,6.84l-3.61,12v0Z" style="fill: #000;"></path>
</svg>
<span class="label">Doors</span>
<span class="value"><?php echo $vehicle_details['doors'] ?></span>
</button>
<button type="button" class="relative inline-flex items-center w-full px-4 py-2 text-sm font-medium border-b border-gray-200 hover:bg-gray-100 hover:text-black-700 dark:border-gray-600 dark:hover:bg-gray-600 dark:hover:text-white text-black flex-row gap-2">
<i class="fas fa-gas-pump w-3 h-3 me-3"></i>
<span class="label">Fuel Type</span>
<span class="value"><?php echo $vehicle_details['fuel_type'] ?></span>
</button>
<button type="button" class="relative inline-flex items-center w-full px-4 py-2 text-sm font-medium border-b border-gray-200 hover:bg-gray-100 hover:text-black-700 dark:border-gray-600 dark:hover:bg-gray-600 dark:hover:text-white text-black flex-row gap-2">
<i class="fas fa-clipboard-check w-3 h-3 me-3"></i>
<span class="label">Condition</span>
<span class="value">Used</span>
</button>
<button type="button" class="relative inline-flex items-center w-full px-4 py-2 text-sm font-medium border-b border-gray-200 hover:bg-gray-100 hover:text-black-700 dark:border-gray-600 dark:hover:bg-gray-600 dark:hover:text-white text-black flex-row gap-2">
<i class="fas fa-palette w-3 h-3 me-3"></i>
<span class="label">Interior Colour</span>
<span class="value"><?php echo $vehicle_details['interior_color'] ?></span>
</button>
</div>
</div>
</div>
<!-- Description -->
<div class="m-4">
<!-- <span class="font-bold text-gray-700 dark:text-gray-300">Standard equipment</span> -->
<div id="accordion-equipment" data-accordion="collapse" data-active-classes="bg-white dark:bg-gray-900 text-gray-900 dark:text-white mt-4 transition-all duration-300" data-inactive-classes="text-gray-500 dark:text-gray-400">
<h2 id="accordion-features-heading-1" class="py-2 my-0">
<button type="button" class="flex items-center justify-between w-full p-5 font-medium rtl:text-right text-gray-500 border-b border-gray-200 gap-3 focus:bg-gray-700 rounded-lg dark:bg-gray-700 dark:border-gray-600 dark:text-white bg-white round-lg focus:text-white" data-accordion-target="#accordion-features-body-1" aria-expanded="true" aria-controls="accordion-features-body-1">
<span>Description</span>
<svg data-accordion-icon class="w-3 h-3 rotate-0 shrink-0" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 10 6">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5 5 1 1 5" />
</svg>
</button>
</h2>
<div id="accordion-features-body-1" class="text-gray-900 border border-gray-200 rounded-lg dark:bg-gray-700 dark:border-gray-600 dark:text-white transition-all duration-300" aria-labelledby="accordion-features-heading-1">
<div class="bg-white px-4 py-2 border-b border-gray-200 dark:border-gray-700 rounded-lg ">
<p class="mt-4 text-gray-600 dark:text-gray-300 text-sm mb-4">
<?php echo implode("<br><br>", explode(' ', $vehicle_details['comments'])); ?>
</p>
</div>
</div>
</div>
</div>
<!-- Options -->
<div class="m-4">
<p class="mb-4 font-bold text-gray-700 dark:text-gray-300">Options</p>
<div id="accordion-flush" data-accordion="collapse" data-active-classes="bg-white dark:bg-gray-900 text-gray-900 dark:text-white mt-4 transition-all duration-300" data-inactive-classes="text-gray-500 dark:text-gray-400">
<div class="md:grid grid-cols-3">
<ul class="col-span-1 flex-column space-y-4 text-sm font-medium text-gray-500 dark:text-gray-400 md:me-4 mb-4 md:mb-0">
<?php foreach ($groupedFeatures as $category => $features) : ?>
<?php
// Remove special characters and spaces from category for use in HTML IDs
$categorySlug = strtolower(preg_replace('/[^a-z0-9]/', '', $category));
?>
<button class="inline-flex items-center text-left px-4 py-3 rounded-lg hover:text-gray-900 bg-gray-50 hover:bg-gray-300 w-full dark:hover:bg-gray-700 dark:hover:text-white text-gray-900 border border-gray-200 dark:bg-gray-700 dark:border-gray-600 dark:text-white transition-all duration-300 ripple-effect" data-tab-target="#tab-<?= $categorySlug ?>-body-1" data-te-ripple-init>
<?= $category ?>
</button>
<?php endforeach; ?>
</ul>
<div class="sticky-container col-span-2 p-6 bg-gray-50 text-medium text-gray-900 border border-gray-200 rounded-lg dark:bg-gray-700 dark:border-gray-600 dark:text-white transition-all duration-300 top-32 lg:top-56" id="tabs-viewer">
</div>
<?php foreach ($groupedFeatures as $category => $features) : ?>
<?php
// Remove special characters and spaces from category for use in HTML IDs
$categorySlug = strtolower(preg_replace('/[^a-z0-9]/', '', $category));
?>
<div class="p-6 bg-gray-50 text-medium text-gray-500 dark:text-gray-400 dark:bg-gray-800 rounded-lg w-full tab-content hidden" id="tab-<?= $categorySlug ?>-body-1">
<h3 class="text-lg font-bold text-gray-900 dark:text-white mb-2"><?= $category ?></h3>
<?php foreach ($features as $feature) : ?>
<p class="mb-2 text-gray-500 dark:text-gray-400"><?= $feature['name'] . (isset($feature['value']) && !empty($feature['value']) ? ': <span>' . $feature['value'] . '</span>' : '') ?> </p>
<?php endforeach; ?>
</div>
<?php endforeach; ?>
</div>
<div class="p-4 text-sm text-gray-800 rounded-lg bg-gray-50 dark:bg-gray-800 dark:text-gray-300 mt-4" role="alert">
<span class="font-medium">*Standard Equipment</span> is the default equipment supplied for the Make and Model of this vehicle, but may not represent the final vehicle with additional / altered equipment options.
</div>
</div>
</div>
</div>
<!-- Vehicle Financing and Booking Widget -->
<div class="px-4 col-span-1 relative">
<div class="sticky-container grid gap-3 top-56">
<button role="button" class="prev px-2 py-2 rounded-full bg-neutral-100 text-neutral-900 group absolute top-1/4 left-4 transform -translate-y-1/2 z-10" aria-label="prev" onclick="navigateSlider(-1)">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5 group-active:-translate-x-2 transition-all duration-200 ease-linear">
<path stroke-linecap="round" stroke-linejoin="round" d="M15.75 19.5L8.25 12l7.5-7.5" />
</svg>
</button>
<div id="featuredImageContainer" class="ripple-effect" style="width: 100%;" onclick="openFeaturedImage()">
<img id="featuredImage" class="cursor-pointer h-auto max-w-full rounded-lg " src="#" alt="">
</div>
<div id="thumbnailContainer" class="no-scrollbar slides overflow-scroll smooth-scroll relative w-full whitespace-nowrap touch-pan-x before:shrink-0 after:shrink-0 before:w-[36vw] after:w-[36vw] snap-mandatory flex snap-x gap-2 border border-transparent rounded-lg dark:bg-gray-700 dark:border-transparent dark:text-white w-full">
<?php
// Display thumbnail images
foreach ($vehicle_images as $index => $image) {
if (isset($image['url'])) { ?>
<div class='slide flex-shrink-0 w-[70vw] h-[calc(70vw*1.5)] sm:w-[40vw] sm:h-[calc(40vw*1.5)] md:w-[25vw] md:h-[calc(25vw*1.5)] overflow-clip relative snap-center rounded-3xl w-16 h-16'>
<a href="<?php echo esc_url($image['url']) ?>" class="glightbox" data-glightbox="gallery">
<img src="<?php echo esc_url($image['url']) ?>" alt="Image <?php echo $index; ?>" class='block w-full h-full object-cover object-center absolute right-0 animate-parallax h-full w-full object-cover rounded-lg thumbnail' onclick="showFeaturedImage(<?php echo $index; ?>)" />
</a>
</div>
<?php
}
}
?>
</div>
<button role="button" class="next px-2 py-2 rounded-full bg-neutral-100 text-neutral-900 group absolute top-1/4 right-4 transform -translate-y-1/2 z-10" aria-label="next" onclick="navigateSlider(1)">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5 group-active:translate-x-2 transition-all duration-200 ease-linear">
<path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5" />
</svg>
</button>
<div class="flex items-center flex-wrap">
<div class="flex justify-between items-end w-full gap-4 relative whitespace-nowrap snap-x">
<div class="flex justify-between items-end w-full gap-4">
<div class="flex-1 text-gray-900 bg-white border border-gray-200 rounded-lg dark:bg-gray-700 dark:border-gray-600 dark:text-white w-full">
<div class="p-4">
<span class="text-xl font-semibold">
<span class="text-gray-600 dark:text-gray-300">
<?php echo $formattedPrice = '$ ' . number_format($vehicle_details['advertise_price']); ?>
</span>
</span>
<p class="text-xs text-gray-400">+ taxes and fees</p>
</div>
</div>
<div class="flex-1 text-gray-900 bg-white border border-gray-200 rounded-lg dark:bg-gray-700 dark:border-gray-600 dark:text-white w-full">
<div class="p-4">
<span class="text-xl font-semibold">
<span class="text-gray-600 dark:text-gray-300 paymentSpan">
<?php echo $formattedPrice = '$ ' . number_format(416); ?>
</span>
<i class="fas fa-calculator cursor-pointer" onclick="openFinanceModal()"></i>
</span>
<p class="text-xs text-gray-400"><span class="rateSpan">7.99</span> for <span class="loanTermSpan">12</span> Months </p>
</div>
</div>
</div>
</div>
</div>
<div class="flex items-center flex-wrap">
<div class="flex items-center justify-between w-full p-5 font-medium rtl:text-right text-gray-500 border-b border-gray-200 rounded-lg dark:bg-gray-700 dark:border-gray-600 dark:text-white bg-white round-lg focus:text-white flex-col gap-3">
<span class="text-red-600 self-start">Estimate Your Payments <i class="fas fa-greater-than text-xs"></i></span>
<!-- Primary Button -->
<button class="w-full bg-gray-500 hover:bg-gray-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline-gray focus:border-gray-700 ripple-effect" onclick="openAppointmentModal()">
Book a Private Appointment
</button>
<!-- Secondary Button -->
<button class="w-full mt-2 bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline-gray focus:border-gray-400 ripple-effect">
Apply for Financing
</button>
</div>
</div>
</div>
</div>
</div>
<!-- Similar Vehicles -->
<div class="flex flex-col md:flex-row max-w-7xl overflow-scroll no-scrollbar">
<div class="mx-auto px-4 mt-10">
<h2 class="text-2xl font-bold mb-4 px-4">Similar Vehicles</h2>
<?php if (!empty($filtered_vehicles)) : ?>
<div class="relative overflow-hidden rounded-lg">
<!-- Left scroll button -->
<button class="absolute left-5 z-10 p-2 bg-neutral-100 rounded-full hover:bg-gray-200 top-1/3" onclick="scrollCarouselLeft()">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5 group-active:-translate-x-2 transition-all duration-200 ease-linear">
<path stroke-linecap="round" stroke-linejoin="round" d="M15.75 19.5L8.25 12l7.5-7.5"></path>
</svg>
</button>
<!-- Right scroll button -->
<button class="absolute right-5 z-10 p-2 bg-neutral-100 rounded-full hover:bg-gray-200 top-1/3" onclick="scrollCarouselRight()">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5 group-active:translate-x-2 transition-all duration-200 ease-linear">
<path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5"></path>
</svg>
</button>
<!-- Vehicle cards -->
<div class="flex whitespace-nowrap overflow-x-scroll scroll-smooth px-4 pb-4 flex-stretch space-x-4">
<?php foreach ($filtered_vehicles as $vehicle) : ?>
<div class="flex-shrink-0 w-80">
<div class="bg-white rounded-lg shadow-md hover:shadow-lg transition duration-200 flex flex-col justify-between h-full">
<img src="<?php echo $vehicle['landingImage']; ?>" alt="Vehicle image" class="w-full object-cover rounded-tl-md rounded-tr-md mb-4">
<div class="p-4 ">
<div class="mb-2">
<h3 class="text-lg font-medium text-gray-700 truncate"><?php echo $vehicle['year'] . ' ' . $vehicle['make'] . ' ' . $vehicle['model'] . ' ' . implode(', ', $vehicle['trim']); ?></h3>
<p class="text-sm text-gray-500"><?php echo number_format($vehicle['mileage']) . ' miles - ' . $vehicle['exterior_color'] . ' - ' . $vehicle['transmission_type']; ?></p>
</div>
<div class="flex justify-between items-center">
<span class="text-base font-medium text-gray-700">$<?php echo number_format($vehicle['advertise_price']); ?></span>
<a href="vehicle-details/?vehicle_id=<?php echo $vehicle['id_vehicle']; ?>" class="inline-flex items-center px-3 py-2 text-sm font-medium text-center text-white bg-gray-700 rounded-lg hover:bg-gray-800 hover:text-white">View Details</a>
</div>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
<?php else : ?>
<p>No similar vehicles found.</p>
<?php endif; ?>
</div>
</div>
</div>
</div>
<?php
get_footer();
?>
<script>
// modal
const handleFinanceChanges = (financeForm) => {
if (document.querySelectorAll('.paymentSpan').length) {
document.querySelectorAll('.paymentSpan').forEach(el => {
el.textContent = (Number(financeForm.payment) || 0).toLocaleString('en-CA', {
style: 'currency',
currency: 'CAD'
});
})
}
// document.querySelectorAll('.paymentFrequencySpan').forEach(el=>{
// // el.textContent = ${financeForm.frequencyMap[financeForm.paymentFrequency]}
// })
if (document.querySelectorAll('.loanTermSpan').length) {
document.querySelectorAll('.loanTermSpan').forEach(el => {
el.innerHTML = `${financeForm.loanTerm}`;
})
}
if (document.querySelectorAll('.rateSpan').length) {
document.querySelectorAll('.rateSpan').forEach(el => {
el.innerHTML = `${financeForm.intRate}`;
})
}
};
const vehicleDetails = <?php echo json_encode($vehicle_details); ?>;
const appointmentForm = new AppointmentForm();
const financeForm = new FinanceForm(vehicleDetails, handleFinanceChanges);
const modal = new Modal(<?php echo $vehicle_id ?>);
document.body.appendChild(modal.initModal());
function openAppointmentModal() {
modal.toggleModal(appointmentForm);
appointmentForm.initializeFormInputs();
}
function openFinanceModal() {
modal.toggleModal(financeForm);
financeForm.initializeFormInputs();
}
// carousel
let lightbox;
let selectedSlide = 0;
function openFeaturedImage() {
lightbox = GLightbox({
selector: 'glightbox',
touchNavigation: true,
loop: true,
startAt: selectedSlide, // Set the starting slide
onClose: function() {
const slideElements = document.querySelectorAll('#thumbnailContainer .thumbnail');
if (slideElements.length >= lightbox.index) {
const selectedSlideElement = slideElements[lightbox.index];
showFeaturedImage(lightbox.index)
}
}
});
lightbox.open();
}
function showFeaturedImage(idx) {
event.preventDefault();
if (typeof lightbox !== 'undefined') {
lightbox.destroy();
}
setFeatureImage(idx);
}
function setFeatureImage(idx) {
const slideElements = document.querySelectorAll('#thumbnailContainer .thumbnail');
if (slideElements.length >= idx) {
const selectedSlideElement = slideElements[idx];
document.getElementById('featuredImage').src = selectedSlideElement.src;
selectedSlide = idx;
}
}
function navigateSlider(direction) {
selectedSlide += direction;
const slideElements = document.querySelectorAll('#thumbnailContainer .thumbnail');
if (selectedSlide < 0) {
selectedSlide = slideElements.length - 1;
} else if (selectedSlide >= slideElements.length) {
selectedSlide = 0;
}
setFeatureImage(selectedSlide);
}
jQuery(document).ready(function() {
var queryString = window.location.search;
var urlParams = new URLSearchParams(queryString);
var filters = JSON.parse(decodeURIComponent(urlParams.get('filters')));
console.log(filters);
setFeatureImage(0);
const accordionHeaders = document.querySelectorAll('[data-accordion-target]');
accordionHeaders.forEach(header => {
header.addEventListener('click', function() {
const target = document.querySelector(this.getAttribute('data-accordion-target'));
target.classList.toggle('max-h-0');
target.classList.toggle('overflow-hidden');
const expanded = target.classList.contains('max-h-0') ? 'false' : 'true';
this.setAttribute('aria-expanded', expanded);
const icon = this.querySelector('[data-accordion-icon]');
icon.style.transform = expanded === 'true' ? 'rotate(0deg)' : 'rotate(180deg)';
});
});
// ripple effect
const btns = document.getElementsByClassName("ripple-effect");
for (const btn of btns) {
btn.addEventListener("click", rippleEffect);
}
const tabs = document.querySelectorAll('[data-tab-target]');
tabs.forEach(tab => {
tab.addEventListener('click', () => {
const target = document.querySelector(tab.getAttribute('data-tab-target'));
document.querySelector('#tabs-viewer').innerHTML = target.innerHTML;
tabs.forEach(t => {
t.classList.remove('text-white', 'bg-gray-700', 'active');
t.classList.add('bg-gray-50');
});
tab.classList.add('text-white', 'bg-gray-700', 'active');
tab.classList.remove('bg-gray-50');
});
});
});
function rippleEffect(event) {
const btn = event.currentTarget;
// Add classes to the selected element
btn.classList.add("overflow-hidden", "shadow", "relative");
const circle = document.createElement("span");
const rect = btn.getBoundingClientRect();
const diameter = Math.max(btn.clientWidth, btn.clientHeight);
const radius = diameter / 2;
// Calculate the position relative to the button element
const offsetX = event.clientX - rect.left;
const offsetY = event.clientY - rect.top;
circle.style.width = circle.style.height = `${diameter}px`;
circle.style.left = `${offsetX - radius}px`;
circle.style.top = `${offsetY - radius}px`;
circle.classList.add("ripple");
const ripple = btn.getElementsByClassName("ripple")[0];
if (ripple) {
ripple.remove();
}
btn.appendChild(circle);
}
function scrollCarouselLeft() {
const carousel = document.querySelector('.overflow-x-scroll');
carousel.scrollTo({
left: carousel.scrollLeft - carousel.offsetWidth,
behavior: 'smooth'
});
// const carousel = document.querySelector('.overflow-x-scroll');
// carousel.scrollLeft -= carousel.offsetWidth;
}
function scrollCarouselRight() {
const carousel = document.querySelector('.overflow-x-scroll');
const maxScrollRight = carousel.scrollWidth - carousel.offsetWidth; // Calculate max scrollable distance
// Prevent scrolling beyond the end
if (carousel.scrollLeft >= maxScrollRight) {
return;
}
carousel.scrollTo({
left: carousel.scrollLeft + carousel.offsetWidth,
behavior: 'smooth'
});
}
</script>