const page = CarPassPage; const APPROVED_STATUSES = new Set(["approved", "verified"]); const MANAGER_ROLES = new Set(["owner", "manager"]); const state = { centers: [], activeCenterId: null, catalog: null, }; function activeCenter() { return state.centers.find((item) => item.id === state.activeCenterId) || null; } function roleLabel(role) { return { owner: "Владелец", manager: "Менеджер", receptionist: "Администратор", mechanic: "Механик" }[role] || role || "СТО"; } function timeValue(value) { return String(value || "").slice(0, 5); } function setScheduleForm(settings) { const form = document.querySelector("#bookingSettingsForm"); form.open_time.value = timeValue(settings.open_time || "09:00"); form.close_time.value = timeValue(settings.close_time || "18:00"); form.lunch_break_start.value = timeValue(settings.lunch_break_start || ""); form.lunch_break_end.value = timeValue(settings.lunch_break_end || ""); form.slot_duration_minutes.value = settings.slot_duration_minutes ?? 30; form.booking_buffer_minutes.value = settings.booking_buffer_minutes ?? 0; form.max_parallel_bookings.value = settings.max_parallel_bookings ?? 1; form.timezone.value = settings.timezone || "Asia/Seoul"; form.accepts_online_booking.checked = settings.accepts_online_booking !== false; const days = new Set(settings.working_days || [0, 1, 2, 3, 4]); form.querySelectorAll('[name="working_days"]').forEach((input) => { input.checked = days.has(Number(input.value)); }); } function schedulePayload(form, centerId) { const data = page.formData(form); const workingDays = [...form.querySelectorAll('[name="working_days"]:checked')].map((input) => Number(input.value)); return { service_center_id: centerId, working_days: workingDays, open_time: data.open_time || "09:00", close_time: data.close_time || "18:00", lunch_break_start: data.lunch_break_start || null, lunch_break_end: data.lunch_break_end || null, timezone: data.timezone || "Asia/Seoul", slot_duration_minutes: Number(data.slot_duration_minutes || 30), booking_buffer_minutes: Number(data.booking_buffer_minutes || 0), max_parallel_bookings: Number(data.max_parallel_bookings || 1), accepts_online_booking: Boolean(data.accepts_online_booking), }; } function catalogPayload(form, centerId) { const data = page.formData(form); const isWork = data.item_type === "work"; return { service_center_id: centerId, item_type: data.item_type, title: data.title, category: data.category || null, description: data.description || null, work_type: isWork ? (data.category || "other") : null, product_type: isWork ? null : (data.category || "other"), brand: data.brand || null, sku: data.sku || null, unit: data.unit || (isWork ? "pcs" : "pcs"), default_quantity: page.numberOrNull(data.default_quantity) || 1, default_unit_price: page.numberOrNull(data.default_unit_price) || 0, viscosity: data.viscosity || null, specification: data.specification || null, }; } function renderHeader() { const center = activeCenter(); document.querySelector("#centerSelect").innerHTML = state.centers .map((item) => ``) .join(""); if (center) document.querySelector("#centerSelect").value = String(center.id); document.querySelector("#settingsTitle").textContent = center ? (center.display_name || center.name) : "Нет доступной СТО"; document.querySelector("#settingsHint").textContent = center ? [center.city, center.address].filter(Boolean).join(", ") || "Заполните график и каталог для команды." : "Настройки доступны владельцу или менеджеру подтвержденной СТО."; document.querySelector("#roleBadge").textContent = center ? roleLabel(center.employee_role) : "Нет доступа"; } function renderCatalog() { const root = document.querySelector("#catalogList"); const centerId = activeCenter()?.id; const items = (state.catalog?.items || []).filter((item) => item.service_center_id === centerId); root.innerHTML = items.length ? items.map((item) => `