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
- ? "Клиент в работе. Удалить нельзя, можно только отредактировать данные."
- : "Клиент ещё не передан в работу — можно изменить данные или удалить карточку."}
+
`);
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 @@
-
-
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+