Add service platform foundation
This commit is contained in:
@@ -220,6 +220,9 @@
|
||||
<button class="menu-row" id="openCarProfileBtn">Параметры автомобиля</button>
|
||||
<button class="menu-row" id="openSettingsBtn">Локаль и валюта</button>
|
||||
<button class="menu-row" id="openNotificationsBtn">Уведомления</button>
|
||||
<button class="menu-row" id="openConfirmationsBtn">Запросы на подтверждение</button>
|
||||
<button class="menu-row" id="openConnectedServicesBtn">Подключенные автосервисы</button>
|
||||
<button class="menu-row" id="openServicePanelBtn">Панель СТО</button>
|
||||
<button class="menu-row" id="openScanBtn">Разобрать чек</button>
|
||||
|
||||
<section class="drawer-section hidden" id="settingsSection">
|
||||
@@ -253,6 +256,54 @@
|
||||
<button type="button" class="wide-btn" id="enableNotificationsBtn">Включить уведомления</button>
|
||||
</section>
|
||||
|
||||
<section class="drawer-section hidden" id="confirmationsSection">
|
||||
<h2>Запросы на подтверждение</h2>
|
||||
<div class="tip-card">Здесь будут визиты СТО и изменения данных авто, которые ждут твоего решения.</div>
|
||||
<div id="confirmationRequests" class="stack-list"></div>
|
||||
</section>
|
||||
|
||||
<section class="drawer-section hidden" id="connectedServicesSection">
|
||||
<h2>Подключенные автосервисы</h2>
|
||||
<div class="tip-card">Автосервис видит машину только после твоего разрешения или в рамках визита.</div>
|
||||
<div id="connectedServices" class="stack-list"></div>
|
||||
</section>
|
||||
|
||||
<section class="drawer-section hidden" id="servicePanelSection">
|
||||
<h2>Панель СТО</h2>
|
||||
<form id="serviceCenterForm" class="grid-form drawer-form">
|
||||
<label>
|
||||
Название СТО
|
||||
<input name="display_name" placeholder="Smart Service" required />
|
||||
</label>
|
||||
<label>
|
||||
Юридическое название
|
||||
<input name="legal_name" placeholder="ООО Smart Service" />
|
||||
</label>
|
||||
<label>
|
||||
Страна
|
||||
<input name="country" maxlength="2" placeholder="KR" />
|
||||
</label>
|
||||
<label>
|
||||
Город
|
||||
<input name="city" placeholder="Seoul" />
|
||||
</label>
|
||||
<label>
|
||||
Адрес
|
||||
<input name="address" />
|
||||
</label>
|
||||
<label>
|
||||
Телефон
|
||||
<input name="phone" />
|
||||
</label>
|
||||
<label>
|
||||
Регистрационный номер
|
||||
<input name="business_registration_number" />
|
||||
</label>
|
||||
<button type="submit">Создать СТО</button>
|
||||
</form>
|
||||
<div id="serviceCentersList" class="stack-list"></div>
|
||||
</section>
|
||||
|
||||
<section class="drawer-section" id="carFormSection">
|
||||
<h2>Новое авто</h2>
|
||||
<form id="carForm" class="grid-form drawer-form">
|
||||
|
||||
@@ -316,6 +316,7 @@ const state = {
|
||||
latestStats: null,
|
||||
allStats: null,
|
||||
analytics: null,
|
||||
serviceCenters: [],
|
||||
receiptFile: null,
|
||||
serviceWorkerRegistration: null,
|
||||
period: {
|
||||
@@ -798,6 +799,36 @@ function openCarProfile() {
|
||||
document.querySelector("#carProfileSection").scrollIntoView({ behavior: "smooth", block: "start" });
|
||||
}
|
||||
|
||||
async function loadServiceCenters() {
|
||||
state.serviceCenters = await api("/service-centers/my");
|
||||
renderServiceCenters();
|
||||
}
|
||||
|
||||
function renderServiceCenters() {
|
||||
const root = document.querySelector("#serviceCentersList");
|
||||
if (!root) return;
|
||||
if (!state.serviceCenters.length) {
|
||||
root.innerHTML = `<div class="empty">СТО пока не создано</div>`;
|
||||
return;
|
||||
}
|
||||
root.innerHTML = state.serviceCenters
|
||||
.map(
|
||||
(center) => `
|
||||
<div class="stack-item">
|
||||
<strong>${center.display_name || center.name}</strong>
|
||||
<small>${[center.city, center.address].filter(Boolean).join(", ") || "Адрес не указан"}</small>
|
||||
<small>Статус: ${center.verification_status}</small>
|
||||
</div>
|
||||
`,
|
||||
)
|
||||
.join("");
|
||||
}
|
||||
|
||||
function renderPlaceholderList(selector, message) {
|
||||
const root = document.querySelector(selector);
|
||||
if (root) root.innerHTML = `<div class="empty">${message}</div>`;
|
||||
}
|
||||
|
||||
function renderStats(stats) {
|
||||
const root = document.querySelector("#stats");
|
||||
if (!stats) {
|
||||
@@ -1398,6 +1429,49 @@ document.querySelector("#openNotificationsBtn").addEventListener("click", () =>
|
||||
document.querySelector("#notificationsSection").scrollIntoView({ behavior: "smooth", block: "start" });
|
||||
});
|
||||
|
||||
document.querySelector("#openConfirmationsBtn").addEventListener("click", () => {
|
||||
document.querySelector("#confirmationsSection").classList.remove("hidden");
|
||||
renderPlaceholderList("#confirmationRequests", "Новых запросов нет");
|
||||
document.querySelector("#confirmationsSection").scrollIntoView({ behavior: "smooth", block: "start" });
|
||||
});
|
||||
|
||||
document.querySelector("#openConnectedServicesBtn").addEventListener("click", () => {
|
||||
document.querySelector("#connectedServicesSection").classList.remove("hidden");
|
||||
renderPlaceholderList("#connectedServices", "Подключенных автосервисов пока нет");
|
||||
document.querySelector("#connectedServicesSection").scrollIntoView({ behavior: "smooth", block: "start" });
|
||||
});
|
||||
|
||||
document.querySelector("#openServicePanelBtn").addEventListener("click", async (event) => {
|
||||
await runAction(event.currentTarget, "Загружаю СТО...", async () => {
|
||||
document.querySelector("#servicePanelSection").classList.remove("hidden");
|
||||
await loadServiceCenters();
|
||||
document.querySelector("#servicePanelSection").scrollIntoView({ behavior: "smooth", block: "start" });
|
||||
});
|
||||
});
|
||||
|
||||
document.querySelector("#serviceCenterForm").addEventListener("submit", async (event) => {
|
||||
event.preventDefault();
|
||||
const form = event.currentTarget;
|
||||
await runAction(form.querySelector('button[type="submit"]'), "Создаю СТО...", async () => {
|
||||
const data = formData(form);
|
||||
await api("/service-centers", {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
display_name: data.display_name,
|
||||
legal_name: data.legal_name || null,
|
||||
country: data.country || null,
|
||||
city: data.city || null,
|
||||
address: data.address || null,
|
||||
phone: data.phone || null,
|
||||
business_registration_number: data.business_registration_number || null,
|
||||
}),
|
||||
});
|
||||
form.reset();
|
||||
await loadServiceCenters();
|
||||
toast("СТО создано");
|
||||
});
|
||||
});
|
||||
|
||||
document.querySelector("#enableNotificationsBtn").addEventListener("click", enableNotifications);
|
||||
|
||||
document.querySelector("#openScanBtn").addEventListener("click", () => {
|
||||
|
||||
@@ -1243,6 +1243,25 @@ select {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.stack-list {
|
||||
display: grid;
|
||||
gap: 8px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.stack-item {
|
||||
display: grid;
|
||||
gap: 4px;
|
||||
padding: 10px 12px;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 8px;
|
||||
background: var(--soft);
|
||||
}
|
||||
|
||||
.stack-item small {
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
@keyframes toastIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
|
||||
Reference in New Issue
Block a user