diff --git a/miniapp/assets/clients.js b/miniapp/assets/clients.js index fdb21c6..4e1b706 100644 --- a/miniapp/assets/clients.js +++ b/miniapp/assets/clients.js @@ -416,6 +416,9 @@ const Clients = (function () { `)); + // Управление карточкой — кнопки прямо под шапкой + root.appendChild(renderClientManagement(client)); + // Быстрые действия для менеджера const actionsRow = el(`
@@ -482,28 +485,48 @@ const Clients = (function () { // Детальные списки внизу (свёрнуты) detailsPlaceholder.replaceWith(renderClientDetails(client, myMeasurements)); - // Управление карточкой клиента — редактировать + (условно) удалить - root.appendChild(renderClientManagement(client)); + // (управление перенесено наверх — сразу под шапку) } /* ===================== Управление карточкой (edit / delete) ===================== */ + // Кастомные SVG-иконки в брендовом монолинейном стиле (stroke-width 1.7) + const ICON_EDIT_SVG = ` + `; + const ICON_TRASH_SVG = ` + `; + function renderClientManagement(client) { const inWork = !!client.in_work; const wrap = el(` -
-
⚙️ Управление карточкой
-
- ${inWork - ? "Клиент в работе. Удалить нельзя, можно только отредактировать данные." - : "Клиент ещё не передан в работу — можно изменить данные или удалить карточку."} +
+ + ${inWork ? "" : ` + `} +
${inWork + ? "В работе — данные можно править" + : "Не в работе — можно править или удалить"}
-
- - ${inWork ? "" : ``} -
-
-
+
+
`); wrap.querySelector("#editClient")?.addEventListener("click", () => { @@ -515,8 +538,10 @@ const Clients = (function () { const confirmed = await confirmDialog(`Удалить клиента ${client.client_name}? Это нельзя отменить из бота.`); if (!confirmed) return; const btn = wrap.querySelector("#deleteClient"); + const labelEl = btn.querySelector(".ct-label"); const result = wrap.querySelector("#manageResult"); - btn.disabled = true; btn.textContent = "Удаляем..."; + btn.disabled = true; + if (labelEl) labelEl.textContent = "Удаляем…"; try { const res = await fetch(`${BACKEND_URL}/api/client_delete`, { method: "POST", @@ -529,17 +554,19 @@ const Clients = (function () { const data = await res.json(); if (data.error) { const msg = data.msg || data.error; - result.innerHTML = `${escHtml(msg)}`; - btn.disabled = false; btn.textContent = "🗑 Удалить клиента"; + result.innerHTML = `${escHtml(msg)}`; + btn.disabled = false; + if (labelEl) labelEl.textContent = "Удалить"; return; } haptic && haptic("success"); clientsCache = null; - result.innerHTML = `Архивировано ${data.archived} записей. Возвращаемся в список...`; + result.innerHTML = `Архивировано ${data.archived} записей. Возвращаемся в список…`; setTimeout(() => { location.hash = "#/clients"; window.location.reload(); }, 1200); } catch (e) { - result.innerHTML = `Сеть: ${escHtml(e.message)}`; - btn.disabled = false; btn.textContent = "🗑 Удалить клиента"; + result.innerHTML = `Сеть: ${escHtml(e.message)}`; + btn.disabled = false; + if (labelEl) labelEl.textContent = "Удалить"; } }); @@ -729,8 +756,11 @@ const Clients = (function () { events.sort((a, b) => (b.ts || "").localeCompare(a.ts || "")); const section = el(` -
-
🕒 Хронология · ${events.length}
+
+ + 🕒 Хронология · ${events.length} + + ${events.length === 0 ? `
Пока нет событий
` : `
${events.map(ev => ` @@ -743,7 +773,7 @@ const Clients = (function () {
`).join("")}`} -
+ `); return section; } diff --git a/miniapp/assets/podbor.css b/miniapp/assets/podbor.css index 5b00ecb..73d7b7d 100644 --- a/miniapp/assets/podbor.css +++ b/miniapp/assets/podbor.css @@ -3052,6 +3052,143 @@ flex-shrink: 0; } +/* ===== Тулбар управления карточкой клиента — объёмные кнопки ===== */ +.client-toolbar { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 10px; + margin: 12px 0 4px; + align-items: stretch; +} +.client-toolbar.is-locked { + grid-template-columns: 1fr; /* только «Редактировать», когда в работе */ +} + +.ct-btn { + position: relative; + display: inline-flex; + align-items: center; + justify-content: center; + gap: 9px; + min-height: 46px; + padding: 0 16px; + border: none; + border-radius: 13px; + font-family: var(--font-ui, "Inter", system-ui, sans-serif); + font-size: 14px; + font-weight: 600; + letter-spacing: 0.01em; + color: #FBF7F0; + cursor: pointer; + text-transform: none; + user-select: none; + -webkit-tap-highlight-color: transparent; + transition: transform 0.12s ease, box-shadow 0.12s ease, filter 0.12s ease; +} +.ct-btn .ct-icon { + width: 18px; + height: 18px; + stroke-width: 1.7; + flex-shrink: 0; + filter: drop-shadow(0 1px 0 rgba(0,0,0,0.18)); +} + +/* Edit — глубокий орех */ +.ct-edit { + background: + linear-gradient(180deg, + rgba(255,255,255,0.10) 0%, + rgba(255,255,255,0.00) 36%, + rgba(0,0,0,0.00) 64%, + rgba(0,0,0,0.16) 100%), + linear-gradient(180deg, #8A6541 0%, #6B4A2B 55%, #523620 100%); + box-shadow: + inset 0 1px 0 rgba(255,255,255,0.22), + inset 0 -1px 0 rgba(0,0,0,0.18), + 0 3px 8px rgba(82, 54, 32, 0.32), + 0 1px 2px rgba(0, 0, 0, 0.12); +} +.ct-edit:hover { filter: brightness(1.04); } +.ct-edit:active { + transform: translateY(1px); + box-shadow: + inset 0 1px 0 rgba(255,255,255,0.10), + inset 0 2px 4px rgba(0,0,0,0.22), + 0 1px 2px rgba(0,0,0,0.10); +} + +/* Delete — благородный кирпично-красный, не «алярм» */ +.ct-delete { + background: + linear-gradient(180deg, + rgba(255,255,255,0.10) 0%, + rgba(255,255,255,0.00) 36%, + rgba(0,0,0,0.00) 64%, + rgba(0,0,0,0.18) 100%), + linear-gradient(180deg, #C95A4A 0%, #A6382A 55%, #832418 100%); + box-shadow: + inset 0 1px 0 rgba(255,255,255,0.22), + inset 0 -1px 0 rgba(0,0,0,0.20), + 0 3px 8px rgba(131, 36, 24, 0.30), + 0 1px 2px rgba(0, 0, 0, 0.12); +} +.ct-delete:hover { filter: brightness(1.05); } +.ct-delete:active { + transform: translateY(1px); + box-shadow: + inset 0 1px 0 rgba(255,255,255,0.10), + inset 0 2px 4px rgba(0,0,0,0.22), + 0 1px 2px rgba(0,0,0,0.10); +} + +.ct-btn:disabled { + opacity: 0.55; + cursor: wait; + filter: saturate(0.7); + transform: none; +} + +.ct-hint { + grid-column: 1 / -1; + font-size: 11.5px; + color: var(--muted, #998877); + text-align: center; + letter-spacing: 0.01em; + margin-top: 2px; + line-height: 1.3; +} +.ct-result { grid-column: 1 / -1; min-height: 0; font-size: 12.5px; } +.ct-result:empty { display: none; } +.ct-ok { color: #4A8016; font-weight: 500; } +.ct-err { color: #A6382A; font-weight: 500; } + +/* ===== Сворачиваемые блоки (хронология и т.п.) ===== */ +.client-collapse { + /* убираем дефолтный маркер */ +} +.client-collapse > summary { + list-style: none; + cursor: pointer; + padding: 12px 6px; + user-select: none; +} +.client-collapse > summary::-webkit-details-marker { display: none; } +.client-collapse > summary.collapse-head { + display: flex; + align-items: center; + justify-content: space-between; + gap: 10px; +} +.client-collapse .collapse-chev { + display: inline-block; + color: var(--muted, #998877); + font-size: 22px; + line-height: 1; + transform: rotate(90deg); + transition: transform 0.2s ease; +} +.client-collapse[open] .collapse-chev { transform: rotate(-90deg); } + /* ===== Сборки (Phase 4) ===== */ .assembly-list { display: flex; diff --git a/miniapp/index.html b/miniapp/index.html index 64385fe..ddef96d 100644 --- a/miniapp/index.html +++ b/miniapp/index.html @@ -12,14 +12,14 @@ - - + +
- +
- - - - - - - - - - + + + + + + + + + +