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(); });