442 lines
27 KiB
PHP
442 lines
27 KiB
PHP
<div class="container text-center main-page">
|
||
<div class="main-page-header">
|
||
<p class="top-title">Доступные автомобили</p>
|
||
<p class="title">Выберите лучший автомобиль</p>
|
||
</div>
|
||
<div class="container my-4">
|
||
<div class="row">
|
||
<div class="col-12 col-md-3 card-catalog-left-container">
|
||
<div class="text-end">
|
||
<button class="btn btn-outline" id="toggleFilterBtn">
|
||
<i class="bi bi-filter-right" style="vertical-align: -.1em;"></i>@lang('Фильтр')
|
||
</button>
|
||
</div>
|
||
<div class="card card-catalog-left-filter collapsible collapsed" id="filterCard">
|
||
<div class="card-body">
|
||
{{-- Дата начала --}}
|
||
<form method="GET" id="filter">
|
||
<div class="form-group mb-3 pb-4 d-flex flex-column justify-content-around align-content-center">
|
||
<label class="form-label d-block">Даты аренды</label>
|
||
<div class="d-flex flex-row justify-content-around align-content-center">
|
||
<input type="text"
|
||
class="form-control"
|
||
name="started_at"
|
||
id="started_at"
|
||
autocomplete="off"
|
||
inputmode="numeric"
|
||
pattern="\d{2}\.\d{2}\.\d{4}"
|
||
placeholder="дд.мм.гггг"
|
||
value="{{ request('started_at') }}"
|
||
style="max-width: 120px">
|
||
<span class="separator">–</span>
|
||
<input type="text"
|
||
class="form-control"
|
||
name="ended_at"
|
||
id="ended_at"
|
||
autocomplete="off"
|
||
inputmode="numeric"
|
||
pattern="\d{2}\.\d{2}\.\d{4}"
|
||
placeholder="дд.мм.гггг"
|
||
value="{{ request('ended_at') }}"
|
||
style="max-width: 120px">
|
||
</div>
|
||
</div>
|
||
|
||
{{-- Класс авто --}}
|
||
<div class="mb-3 pb-4">
|
||
<label class="form-label d-block">Класс авто</label>
|
||
<div class="btn-group" role="group" aria-label="Класс">
|
||
<input type="checkbox" class="btn-check" name="class_filters[]" value="Эконом" id="class_option1" {{ in_array('Эконом', (array) request('class_filters')) ? 'checked' : '' }}>
|
||
<label class="btn btn-outline-primary" for="class_option1">Эконом</label>
|
||
|
||
<input type="checkbox" class="btn-check" name="class_filters[]" value="Средний" id="class_option2" {{ in_array('Средний', (array) request('class_filters')) ? 'checked' : '' }}>
|
||
<label class="btn btn-outline-primary" for="class_option2">Средний</label>
|
||
|
||
<input type="checkbox" class="btn-check" name="class_filters[]" value="Бизнес" id="class_option3" {{ in_array('Бизнес', (array) request('class_filters')) ? 'checked' : '' }}>
|
||
<label class="btn btn-outline-primary" for="class_option3">Бизнес</label>
|
||
</div>
|
||
</div>
|
||
{{-- Тип кузова --}}
|
||
<div class="mb-3 pb-4">
|
||
<label class="form-label d-block">Тип кузова</label>
|
||
<div class="btn-group" role="group" aria-label="Кузов">
|
||
<input type="checkbox" class="btn-check" name="bodywork_filters[]" value="Седан" id="bodywork_option1" {{ in_array('Седан', (array) request('bodywork_filters')) ? 'checked' : '' }}>
|
||
<label class="btn btn-outline-primary" for="bodywork_option1">Седан</label>
|
||
|
||
<input type="checkbox" class="btn-check" name="bodywork_filters[]" value="Кроссовер" id="bodywork_option2" {{ in_array('Кроссовер', (array) request('bodywork_filters')) ? 'checked' : '' }}>
|
||
<label class="btn btn-outline-primary" for="bodywork_option2">Кроссовер</label>
|
||
|
||
<input type="checkbox" class="btn-check" name="bodywork_filters[]" value="Внедорожник" id="bodywork_option3" {{ in_array('Внедорожник', (array) request('bodywork_filters')) ? 'checked' : '' }}>
|
||
<label class="btn btn-outline-primary" for="bodywork_option3">Внедорожник</label>
|
||
</div>
|
||
</div>
|
||
|
||
{{-- Кнопка --}}
|
||
<div class="filter-buttons d-flex" style="gap: 5px;">
|
||
<button type="submit" class="btn btn-danger w-100" id="filter_reset" onclick="resetForm()">
|
||
@lang('Сбросить')
|
||
</button>
|
||
<button type="submit" class="btn btn-success w-100">
|
||
@lang('Искать')
|
||
</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card card-catalog-left mt-4">
|
||
<div class="card-body">
|
||
<p class="title">Все предложения включают:</p>
|
||
<ul>
|
||
<li><i class="material-symbols-outlined">done</i>
|
||
<span> Бесплатное перебронирование и отмена</span></li>
|
||
<li><i class="material-symbols-outlined">done</i>
|
||
<span> Лимит пробега по городу 200 км</span></li>
|
||
<li><i class="material-symbols-outlined">done</i> <span> Страхование гражданской ответственности</span></li>
|
||
<li><i class="material-symbols-outlined">done</i> <span> Эконом класс</span></li>
|
||
<li><i class="material-symbols-outlined">done</i> <span> Депозит</span></li>
|
||
<li><i class="material-symbols-outlined">done</i>
|
||
<span> Межгород по дополнительным тарифам</span></li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card card-catalog-left2 mt-4">
|
||
<div class="card-body">
|
||
<p class="title">Другие условия:</p>
|
||
<p class="cr-item">Минимальный возраст водителя - 21 год</p>
|
||
<p class="cr-item">Минимальный срок владения водительскими правами - 2 года</p>
|
||
<p class="title m-0">Прочие условия:</p>
|
||
<a href="https://pcar.kz/#faq" target="_blank" class="btn-link">Условия аренды автомобиля</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="col-12 col-md-9 mb-4 d-flex">
|
||
<div class="row custom-row w-100">
|
||
@php $carsValues = array_values($cars->toArray()); @endphp
|
||
@foreach($carsValues as $car)
|
||
<div class="col-12 col-md-6 mb-4">
|
||
<div class="car-card flex-grow-1">
|
||
<img class="img-fluid" src="{{ $car['photo'] ?? asset('img/default.png') }}" alt="Car Image">
|
||
<div class="title">{{ $car['brand'] . ' ' . $car['mark'] . ' - ' . $car['year'] }}</div>
|
||
<div class="card-car-chars">
|
||
<div class="add-li"><i class="material-symbols-outlined">ac_unit</i><p> Кондиционер</p></div>
|
||
<div class="add-li"><i class="material-symbols-outlined">auto_transmission</i><p> {{ $car['fuel_type'] }}</p></div>
|
||
<div class="add-li"><i class="material-symbols-outlined">groups</i><p> {{ $car['people'] }} мест</p></div>
|
||
</div>
|
||
<div class="car-card-footer">
|
||
<div class="cost">
|
||
<small>Базовая ставка</small>
|
||
@php
|
||
$tariffWithMin1 = collect($car['tariffs'])->firstWhere('min', 1);
|
||
@endphp
|
||
<p class="m-0">
|
||
@if($tariffWithMin1)
|
||
{{ $tariffWithMin1['price'] }} ₸
|
||
@endif
|
||
</p>
|
||
</div>
|
||
<a href="#" class="btn btn-primary open-rent-modal"
|
||
data-bs-toggle="modal"
|
||
data-bs-target="#rentModal"
|
||
data-photo="{{ $car['photo'] ?? asset('img/default.png') }}"
|
||
data-brand="{{ $car['brand'] }}"
|
||
data-mark="{{ $car['mark'] }}"
|
||
data-year="{{ $car['year'] }}"
|
||
data-fuel="{{ $car['fuel_type'] }}"
|
||
data-people="{{ $car['people'] }}"
|
||
data-id="{{ $car['id'] ?? '' }}">
|
||
@lang('Арендовать')
|
||
</a>
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
@endforeach
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="modal fade" id="rentModal" tabindex="-1" aria-labelledby="rentModalLabel" aria-hidden="true">
|
||
<div class="modal-dialog modal-lg" style="min-width: 75vw">
|
||
<div class="modal-content">
|
||
<div class="modal-body">
|
||
<div class="row justify-content-center align-items-start">
|
||
<form method="post" class="col-12 col-md-7">
|
||
<input hidden="" name="mark_id" id="mark_id" value="">
|
||
<input hidden="" name="color" id="color" value="">
|
||
<div class="car-card d-flex flex-grow-1 flex-row mb-4">
|
||
<img id="modalCarImage" class="img-fluid" src="" alt="Car Image" style="width: 50%; margin-right: 2rem;">
|
||
<div>
|
||
<div class="title" id="modalCarTitle"></div>
|
||
<div class="subtitle">@lang('или аналогичный')</div>
|
||
<div class="title-small mt-4 mb-2">@lang('Особенности автомобиля')</div>
|
||
<div class="card-car-chars">
|
||
<div class="add-li"><i class="material-symbols-outlined">ac_unit</i><p> @lang('Кондиционер')</p></div>
|
||
<div class="add-li"><i class="material-symbols-outlined">auto_transmission</i><p id="modalFuel"> </p></div>
|
||
<div class="add-li"><i class="material-symbols-outlined">groups</i><p id="modalPeople"> </p></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="card m-0 mb-4" style="overflow: visible;">
|
||
<div class="card-body">
|
||
<div class="mb-3">
|
||
<div class="row justify-content-center align-items-end">
|
||
<div class="col-12 col-md-6">
|
||
<label for="days" class="form-label">Срок аренды, дней <b>*</b></label>
|
||
<input type="number" name="days" class="form-control" id="days" value="7" required="">
|
||
</div>
|
||
<div class="col-12 col-md-6">
|
||
<div class="form-text">
|
||
Чем больше срок аренды, тем ниже базовая ставка.
|
||
<div class="popup-custom">
|
||
<span>Условия скидок <i class="material-symbols-outlined">help</i></span>
|
||
<div class="popup-block">
|
||
<p>@lang('Базовая суточная ставка на аренду данного автомобиля уменьшается в зависимости от срока аренды')</p>
|
||
<ul>
|
||
<li><b>16-30 дня:</b> 13000 ₸</li>
|
||
<li><b>3-5 дня:</b> 16000 ₸</li>
|
||
<li><b>1-2 дня:</b> 18000 ₸</li>
|
||
<li><b>6-15 дня:</b> 14500 ₸</li>
|
||
<li><b>30+ дня:</b> 7800 ₸</li>
|
||
</ul>
|
||
<p>@lang('Расчет итоговой суммы к оплате рассчитывается (кол-во дней * базовую ставку)')</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="card m-0 mb-4">
|
||
<div class="card-body">
|
||
<div class="mb-3">
|
||
<label class="form-label">Место и время получения <b>*</b></label>
|
||
<input placeholder="Введите адрес получения" type="text" class="form-control" name="pick-up-address" id="pick-up-address" required="">
|
||
<div class="row mt-3">
|
||
<div class="col-6">
|
||
<input type="date" class="form-control" id="pick-up-date" name="pick-up-date" required="" min="2025-05-02">
|
||
</div>
|
||
<div class="col-6">
|
||
<input type="time" class="form-control" name="pick-up-time" id="pick-up-time" value="09:00" required="">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<hr>
|
||
<div class="mb-3">
|
||
<label class="form-label">Место и время возврата <b>*</b></label>
|
||
<input placeholder="Введите адрес возврата" type="text" class="form-control" name="return-address" id="return-address" required="">
|
||
<div class="row mt-3">
|
||
<div class="col-6">
|
||
<input type="date" class="form-control" id="return-date" name="return-date" disabled="" required="">
|
||
</div>
|
||
<div class="col-6">
|
||
<input type="time" class="form-control" id="return-time" name="return-time" value="09:00" required="">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="mb-4 lst-btn">
|
||
<button type="submit" class="btn btn-primary btn-lg">Забронировать сейчас</button>
|
||
<p class="add-text2">Бесплатная отмена в любое время</p>
|
||
</div>
|
||
</form>
|
||
<div class="col-12 col-md-4 right-content">
|
||
<div class="card mb-4 card-type-2 price-info" style="border-radius: 8px;">
|
||
<div class="card-body">
|
||
<div class="title-small mb-3">Базовая ставка</div>
|
||
<div class="li-bl">
|
||
<div class="li-sp">Без скидки</div>
|
||
<div class="li-sp" id="base-without">32000 ₸</div>
|
||
</div>
|
||
<div class="li-bl">
|
||
<div class="li-sp">Со скидки</div>
|
||
<div class="li-sp" id="base-with">25 000 ₸</div>
|
||
</div>
|
||
<hr>
|
||
<div class="title-small mb-3">Общая цена</div>
|
||
<div class="li-bl">
|
||
<div class="li-sp">Аренда без скидки</div>
|
||
<div class="li-sp" id="summ-without">224 000 ₸</div>
|
||
</div>
|
||
<div class="li-bl">
|
||
<div class="li-sp">Аренда со скидки</div>
|
||
<div class="li-sp" id="sunn-with">175 000 ₸</div>
|
||
</div>
|
||
<hr>
|
||
<div class="li-bl">
|
||
<div class="title">Итого</div>
|
||
<div class="title" id="total">175 000 ₸</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="card card-type-2" style="border-radius: 8px;">
|
||
<div class="card-body">
|
||
<div class="muted-card-text">
|
||
Общая стоимость, включая установленные законом налоги. <br><br>
|
||
Обратите внимание, что на изображении и в технических характеристиках автомобиля представлена только примерная иллюстрация категории автомобиля (за исключением ошибок). Бронирование производится только для категории транспортного средства, но не для конкретного транспортного средства. <br><br>
|
||
Вся информация о размерах, весе и т.д. основана на наименьшей доступной категории модели. </div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
function debounce(func, wait) {
|
||
let timeout;
|
||
return function (...args) {
|
||
const context = this;
|
||
clearTimeout(timeout);
|
||
timeout = setTimeout(() => func.apply(context, args), wait);
|
||
};
|
||
}
|
||
|
||
const datepickerConfig = {
|
||
buttons: ['today', 'clear'],
|
||
autoClose: true
|
||
};
|
||
|
||
const startedAtPicker = new AirDatepicker('#started_at', datepickerConfig);
|
||
const endedAtPicker = new AirDatepicker('#ended_at', datepickerConfig);
|
||
|
||
document.addEventListener('DOMContentLoaded', function () {
|
||
const toggleBtn = document.getElementById('toggleFilterBtn');
|
||
const filterCard = document.getElementById('filterCard');
|
||
|
||
// Инициализация состояния по localStorage
|
||
let isExpanded = localStorage.getItem('filterOpened') === 'true';
|
||
|
||
if (isExpanded) {
|
||
filterCard.classList.add('expanded');
|
||
filterCard.style.transition = 'max-height 1.2s ease, opacity 1.2s ease';
|
||
}
|
||
|
||
toggleBtn.addEventListener('click', function (e) {
|
||
e.preventDefault();
|
||
|
||
if (!filterCard.classList.contains('expanded')) {
|
||
filterCard.style.transition = 'max-height 1.2s ease, opacity 1.2s ease';
|
||
filterCard.classList.add('expanded');
|
||
isExpanded = true;
|
||
} else {
|
||
filterCard.style.transition = 'max-height 0.4s ease, opacity 0.4s ease';
|
||
filterCard.classList.remove('expanded');
|
||
isExpanded = false;
|
||
}
|
||
|
||
localStorage.setItem('filterOpened', isExpanded);
|
||
});
|
||
|
||
const pickUpDateInput = document.getElementById('pick-up-date');
|
||
const returnDateInput = document.getElementById('return-date');
|
||
const daysInput = document.getElementById('days');
|
||
|
||
const today = new Date();
|
||
const yyyy = today.getFullYear();
|
||
const mm = String(today.getMonth() + 1).padStart(2, '0');
|
||
const dd = String(today.getDate()).padStart(2, '0');
|
||
const todayStr = `${yyyy}-${mm}-${dd}`;
|
||
|
||
pickUpDateInput.value = todayStr;
|
||
pickUpDateInput.setAttribute('min', todayStr);
|
||
|
||
function updateReturnDate() {
|
||
const pickUpDate = new Date(pickUpDateInput.value);
|
||
const rentalDays = parseInt(daysInput.value, 10);
|
||
|
||
if (!isNaN(rentalDays)) {
|
||
pickUpDate.setDate(pickUpDate.getDate() + rentalDays);
|
||
const returnYyyy = pickUpDate.getFullYear();
|
||
const returnMm = String(pickUpDate.getMonth() + 1).padStart(2, '0');
|
||
const returnDd = String(pickUpDate.getDate()).padStart(2, '0');
|
||
returnDateInput.value = `${returnYyyy}-${returnMm}-${returnDd}`;
|
||
}
|
||
}
|
||
|
||
updateReturnDate();
|
||
|
||
daysInput.addEventListener('input', updateReturnDate);
|
||
pickUpDateInput.addEventListener('change', updateReturnDate);
|
||
|
||
const modal = document.getElementById('rentModal');
|
||
|
||
document.querySelectorAll('.open-rent-modal').forEach(button => {
|
||
button.addEventListener('click', function () {
|
||
const photo = this.getAttribute('data-photo');
|
||
const brand = this.getAttribute('data-brand');
|
||
const mark = this.getAttribute('data-mark');
|
||
const year = this.getAttribute('data-year');
|
||
const fuel = this.getAttribute('data-fuel');
|
||
const people = this.getAttribute('data-people');
|
||
const id = this.getAttribute('data-id');
|
||
|
||
document.getElementById('modalCarImage').src = photo;
|
||
document.getElementById('modalCarTitle').innerText = `${brand} ${mark} - ${year}`;
|
||
document.getElementById('modalFuel').innerHTML = ` ${fuel}`;
|
||
document.getElementById('modalPeople').innerHTML = ` ${people} мест`;
|
||
document.getElementById('mark_id').value = id;
|
||
});
|
||
});
|
||
});
|
||
|
||
document.querySelectorAll('input[name="class_filters[]"]').forEach(checkbox => {
|
||
checkbox.addEventListener('click', function () {
|
||
if (this.checked) {
|
||
const wasChecked = this.dataset.checked === "true";
|
||
document.querySelectorAll('input[name="class_filters[]"]').forEach(cb => {
|
||
cb.checked = false;
|
||
cb.dataset.checked = "false";
|
||
});
|
||
|
||
if (!wasChecked) {
|
||
this.checked = true;
|
||
this.dataset.checked = "true";
|
||
}
|
||
} else {
|
||
this.dataset.checked = "false";
|
||
}
|
||
});
|
||
});
|
||
|
||
document.querySelectorAll('input[name="bodywork_filters[]"]').forEach(checkbox => {
|
||
checkbox.addEventListener('click', function () {
|
||
if (this.checked) {
|
||
const wasChecked = this.dataset.checked === "true";
|
||
document.querySelectorAll('input[name="bodywork_filters[]"]').forEach(cb => {
|
||
cb.checked = false;
|
||
cb.dataset.checked = "false";
|
||
});
|
||
|
||
if (!wasChecked) {
|
||
this.checked = true;
|
||
this.dataset.checked = "true";
|
||
}
|
||
} else {
|
||
this.dataset.checked = "false";
|
||
}
|
||
});
|
||
});
|
||
|
||
function resetForm() {
|
||
const form = document.getElementById('filter');
|
||
|
||
form.querySelectorAll('input').forEach(input => {
|
||
if (input.type === 'checkbox' || input.type === 'radio') {
|
||
input.checked = false;
|
||
} else {
|
||
input.value = '';
|
||
}
|
||
});
|
||
|
||
window.location.href = window.location.origin + window.location.pathname;
|
||
}
|
||
</script>
|