diff --git a/frontend/admin.html b/frontend/admin.html index 6ac4457..02af9fc 100644 --- a/frontend/admin.html +++ b/frontend/admin.html @@ -653,8 +653,74 @@ .adm-toggle .thumb { position: absolute; top: 3px; left: 3px; width: 18px; height: 18px; border-radius: 50%; background: #fff; box-shadow: 0 1px 4px rgba(0,0,0,.15); transition: transform .2s; } .adm-toggle input:checked ~ .track { background: var(--green, #06d6a0); } .adm-toggle input:checked ~ .thumb { transform: translateX(18px); } - .gam-xp-preset.active, .gam-coins-preset.active { background: var(--violet); color: #fff; border-color: var(--violet); } - .gam-xp-preset:hover:not(.active), .gam-coins-preset:hover:not(.active) { border-color: var(--violet); color: var(--violet); } + /* ── Gam award form ─────────────────────────────────────────────────── */ + .gam-award-grid { display: grid; grid-template-columns: 280px 1fr; gap: 28px; align-items: start; } + @media (max-width: 800px) { .gam-award-grid { grid-template-columns: 1fr; } } + + .gam-user-col { display: flex; flex-direction: column; gap: 6px; } + .gam-user-filter { + padding: 9px 12px; border: 1.5px solid var(--border-h); border-radius: 10px; + font-family: 'Manrope', sans-serif; font-size: 0.88rem; background: var(--surface); color: var(--text); + transition: border-color .15s; box-sizing: border-box; width: 100%; + } + .gam-user-filter:focus { outline: none; border-color: var(--violet); } + .gam-user-select { + border: 1.5px solid var(--border-h); border-radius: 10px; + font-family: 'Manrope', sans-serif; font-size: 0.88rem; background: var(--surface); color: var(--text); + overflow-y: auto; width: 100%; box-sizing: border-box; + transition: border-color .15s; + } + .gam-user-select:focus { outline: none; border-color: var(--violet); } + .gam-user-select option { padding: 7px 12px; } + .gam-user-select option:checked { background: rgba(155,93,229,0.1); color: var(--violet); } + + .gam-fields { display: flex; flex-direction: column; gap: 18px; } + .gam-field-row { display: flex; flex-direction: column; gap: 6px; } + .gam-field-row label { font-size: 0.72rem; font-weight: 700; color: var(--text-3); text-transform: uppercase; letter-spacing: 0.05em; } + .gam-input-row { display: flex; align-items: center; gap: 8px; } + .gam-num-input { + width: 88px; padding: 9px 12px; border: 1.5px solid var(--border-h); border-radius: 10px; + font-family: 'Unbounded', sans-serif; font-size: 1rem; font-weight: 700; text-align: center; + background: var(--surface); color: var(--text); transition: border-color .15s; + } + .gam-num-input:focus { outline: none; border-color: var(--violet); } + + .gam-presets { display: flex; gap: 5px; flex-wrap: wrap; } + .gam-preset { + padding: 6px 13px; border: 1.5px solid var(--border-h); border-radius: 8px; + background: var(--surface); color: var(--text-2); + font-family: 'Manrope', sans-serif; font-size: 0.78rem; font-weight: 700; + cursor: pointer; transition: border-color .15s, background .15s, color .15s; + } + .gam-preset:hover { border-color: var(--violet); color: var(--violet); } + .gam-preset.active { background: var(--violet); color: #fff; border-color: var(--violet); } + + .gam-reason-presets { display: flex; gap: 5px; flex-wrap: wrap; margin-bottom: 6px; } + .gam-reason-tag { + padding: 5px 12px; border: 1.5px solid var(--border-h); border-radius: 8px; + background: var(--surface); color: var(--text-3); + font-family: 'Manrope', sans-serif; font-size: 0.78rem; font-weight: 600; + cursor: pointer; transition: border-color .15s, color .15s; + } + .gam-reason-tag:hover { border-color: var(--cyan); color: var(--cyan); } + .gam-reason-input { + width: 100%; padding: 9px 12px; border: 1.5px solid var(--border-h); border-radius: 10px; + font-family: 'Manrope', sans-serif; font-size: 0.88rem; + background: var(--surface); color: var(--text); box-sizing: border-box; + transition: border-color .15s; + } + .gam-reason-input:focus { outline: none; border-color: var(--violet); } + + .gam-award-footer { display: flex; align-items: center; gap: 14px; padding-top: 20px; border-top: 1px solid var(--border); margin-top: 6px; } + .gam-award-hint { font-size: 0.78rem; color: var(--text-3); line-height: 1.4; } + + .gam-reset-grid { display: grid; grid-template-columns: 280px 1fr; gap: 28px; align-items: start; } + @media (max-width: 800px) { .gam-reset-grid { grid-template-columns: 1fr; } } + .gam-reset-warning { + background: rgba(241,91,181,0.06); border: 1.5px solid rgba(241,91,181,0.2); + border-radius: 12px; padding: 16px 18px; display: flex; flex-direction: column; gap: 12px; + } + .gam-reset-warning p { font-size: 0.84rem; color: var(--text-2); line-height: 1.5; } .adm-user-search { position: relative; } .adm-user-search .us-results { position: absolute; top: 100%; left: 0; right: 0; z-index: 50; background: #fff; border: 1.5px solid var(--border-h); border-radius: 12px; max-height: 240px; overflow-y: auto; box-shadow: 0 8px 24px rgba(15,23,42,0.12); display: none; } .adm-user-search .us-results.open { display: block; } @@ -1378,92 +1444,87 @@
Начислить XP / Монеты
-
- -
- - - +
-
- -
+ +
+ +
-
- -
- - - - - - +
+ +
+ + + + + +
- -
+ +
-
- -
- - - - +
+ +
+ + + +
- -
+ +
-
- - - - - +
+ + + + +
- +
+ + +
-
- - XP=0 или Монеты=0 → эта валюта не начисляется -
Сбросить прогресс пользователя
-
-
- - - +
-
-

Удалит весь XP, монеты, достижения и историю. Действие необратимо.

+
+

Удалит весь XP, монеты, достижения и историю начислений. Действие необратимо и не может быть отменено.

diff --git a/frontend/js/admin/sections/gam.js b/frontend/js/admin/sections/gam.js index 0e3dcdc..2ea848c 100644 --- a/frontend/js/admin/sections/gam.js +++ b/frontend/js/admin/sections/gam.js @@ -199,10 +199,9 @@ LS.toast(`Начислено ${userName}: XP +${xp} Монеты +${coins} → Уровень ${r.level}`, 'success'); // Reset form document.getElementById('gam-award-uid').value = ''; - document.getElementById('gam-award-xp').value = '0'; - document.getElementById('gam-award-coins').value = '0'; + gamSetXP(0); + gamSetCoins(0); document.getElementById('gam-award-reason').value = ''; - document.querySelectorAll('.gam-xp-preset,.gam-coins-preset').forEach(b => b.classList.remove('active')); inited = false; await load(); inited = true;