const page = CarPassPage;
const params = new URLSearchParams(window.location.search);
const state = {
centers: [],
vehicles: [],
selectedCenterId: Number(params.get("service_center_id") || 0) || null,
};
const SERVICE_NAMES = {
oil_change: "Замена масла",
diagnostics: "Диагностика",
maintenance: "Техническое обслуживание",
tire_service: "Шиномонтаж",
brakes: "Тормозная система",
repair: "Ремонт",
other: "Другое",
};
function selectedCenter() {
return state.centers.find((item) => item.id === state.selectedCenterId) || null;
}
function renderCenters() {
const root = document.querySelector("#serviceList");
root.innerHTML = state.centers.length
? state.centers.map((center) => `
`).join("")
: `
Подходящих СТО не найдено.
`;
root.querySelectorAll("[data-center]").forEach((button) => {
button.addEventListener("click", async () => {
state.selectedCenterId = Number(button.dataset.center);
renderCenters();
renderBookingHead();
await loadSlots();
});
});
}
function renderBookingHead() {
const center = selectedCenter();
document.querySelector("#bookingTitle").textContent = center ? (center.display_name || center.name) : "Выберите сервис";
document.querySelector("#bookingHint").textContent = center
? [center.city, center.address, center.working_hours].filter(Boolean).join(" · ") || "Выберите удобное время записи."
: "Выберите СТО слева, потом автомобиль, услугу и свободное окно.";
}
function renderVehicles() {
const select = document.querySelector("#vehicleSelect");
select.innerHTML = state.vehicles.length
? state.vehicles.map((car) => ``).join("")
: ``;
select.disabled = !state.vehicles.length;
}
async function loadCenters(filters = {}) {
const query = new URLSearchParams();
query.set("has_slots", "true");
if (filters.city) query.set("city", filters.city);
if (filters.specialization) query.set("specialization", filters.specialization);
state.centers = await page.api(`/sto/catalog?${query.toString()}`);
if (state.selectedCenterId && !state.centers.some((item) => item.id === state.selectedCenterId)) {
state.centers = [await page.api(`/service-centers/${state.selectedCenterId}`).catch(() => null), ...state.centers].filter(Boolean);
}
if (!state.selectedCenterId && state.centers.length) state.selectedCenterId = state.centers[0].id;
renderCenters();
renderBookingHead();
}
async function loadVehicles() {
state.vehicles = await page.api("/my/vehicles");
renderVehicles();
}
async function loadSlots() {
const center = selectedCenter();
const select = document.querySelector("#slotSelect");
if (!center) {
select.innerHTML = ``;
select.disabled = true;
return;
}
const form = document.querySelector("#bookingForm");
const data = page.formData(form);
const date = data.date || page.today();
const serviceType = data.service_type || "maintenance";
const duration = data.estimated_duration_minutes || "60";
document.querySelector("#slotHint").textContent = "Проверяю свободные окна...";
const slots = await page.api(`/sto/${center.id}/available-slots?service_type=${encodeURIComponent(serviceType)}&date_from=${date}&date_to=${date}&duration_minutes=${duration}`);
select.disabled = !slots.length;
select.innerHTML = slots.length
? slots.map((slot) => ``).join("")
: ``;
document.querySelector("#slotHint").textContent = slots.length ? "Выберите удобное окно." : "Попробуйте другую дату или длительность.";
}
document.querySelector("#filterForm").addEventListener("submit", async (event) => {
event.preventDefault();
await page.runAction(event.currentTarget.querySelector("button"), "Ищу СТО...", async () => {
await loadCenters(page.formData(event.currentTarget));
await loadSlots();
});
});
["#serviceTypeSelect", "#durationSelect", "#bookingDateInput"].forEach((selector) => {
document.querySelector(selector).addEventListener("change", () => {
loadSlots().catch((error) => page.toast(error.message || "Не удалось обновить окна", "error"));
});
});
document.querySelector("#bookingForm").addEventListener("submit", async (event) => {
event.preventDefault();
const center = selectedCenter();
const data = page.formData(event.currentTarget);
if (!center) {
page.toast("Выберите СТО", "error");
return;
}
if (!data.vehicle_id) {
page.toast("Добавьте автомобиль перед записью", "error");
return;
}
await page.runAction(document.querySelector("#createBookingBtn"), "Отправляю заявку...", async () => {
await page.api("/appointments", {
method: "POST",
body: JSON.stringify({
service_center_id: center.id,
vehicle_id: Number(data.vehicle_id),
service_type: data.service_type,
service_name: SERVICE_NAMES[data.service_type] || "Обслуживание",
requested_start_at: data.slot,
estimated_duration_minutes: Number(data.estimated_duration_minutes || 60),
customer_comment: data.customer_comment || null,
}),
});
page.toast("Заявка отправлена в СТО");
window.setTimeout(() => { window.location.href = "/?section=appointments"; }, 700);
});
});
page.boot(async () => {
document.querySelector("#bookingDateInput").value = page.today();
await Promise.all([loadCenters(), loadVehicles()]);
await loadSlots();
});