{% extends "admin/base.html" %} {% block title %}{{ target_user.username }} — Админ-панель{% endblock %} {% block nav_users %}active{% endblock %} {% block page_title %} 👤 {{ target_user.username }} {% if target_user.is_admin %}Админ{% endif %} {% if target_user.is_banned %}Забанен{% endif %} {% endblock %} {% block top_actions %} ← Назад {% endblock %} {% block content %}
Баланс
{{ "%.0f"|format(target_user.balance) }} ₽
Предметов
{{ inventory|length }}
Открытий кейсов
{{ total_openings }}
Контрактов
{{ total_contracts }}
🎲 РПУ (Режим Персонального Угнетения)
--
Уровень
--
Множитель
--
Потрачено
--
Открыто
--
Авто
🔧 Действия
{% if target_user.id != user.id %} {% endif %}
🎒 Инвентарь (последние 50)
{% for item in inventory %} {% endfor %}
IDНазваниеРедкостьFloat
{{ item.id }} {{ item.market_hash_name[:35] }}{{'…' if item.market_hash_name|length > 35}} {{ item.rarity }} {{ "%.4f"|format(item.float_value) }}
{% endblock %} {% block modals %}
💰 Изменить баланс

Текущий: {{ "%.2f"|format(target_user.balance) }} ₽

🎁 Выдать предмет
⚙️ Настройка РПУ
{% endblock %} {% block extra_styles %} {% endblock %} {% block scripts %} // ====== BALANCE ====== function openBalanceModal() { openModal('balanceModal'); } async function updateBalance() { const fd = new FormData(); fd.append('amount', document.getElementById('balanceAmount').value); fd.append('operation', document.getElementById('balanceOperation').value); const res = await fetch(`/admin/api/user/${userId}/balance`, { method:'POST', body:fd }); const d = await res.json(); if (d.success) { Notify.success(d.message); window.location.reload(); } else Notify.error(d.error); } // ====== GIVE ITEM ====== function openGiveItemModal() { openModal('giveItemModal'); searchItems(); } async function searchItems() { const q = document.getElementById('itemSearchInput').value; const res = await fetch(`/admin/api/items/search?q=${encodeURIComponent(q)}`); const items = await res.json(); document.getElementById('itemSearchResults').innerHTML = items.map(item => `
${item.name}
${item.rarity} • ${item.price_rub || 0} ₽
`).join(''); } async function giveItem(itemId) { const fd = new FormData(); fd.append('item_id', itemId); const res = await fetch(`/admin/api/user/${userId}/give-item`, { method:'POST', body:fd }); const d = await res.json(); if (d.success) { Notify.success(d.message); closeModal('giveItemModal'); window.location.reload(); } else Notify.error(d.error); } // ====== DELETE ITEM ====== async function deleteItem(invId) { Notify.confirm('Удалить предмет?', 'Подтверждение', async function(ok) { if (!ok) return; const res = await fetch(`/admin/api/user/${userId}/delete-item/${invId}`, { method:'POST' }); const d = await res.json(); if (d.success) window.location.reload(); else Notify.error(d.error); }); } // ====== TOGGLE ADMIN / BAN ====== async function toggleAdmin() { Notify.confirm('Изменить статус админа?', 'Подтверждение', async function(ok) { if (!ok) return; const res = await fetch(`/admin/api/user/${userId}/toggle-admin`, { method:'POST' }); const d = await res.json(); if (d.success) window.location.reload(); else Notify.error(d.error); }); } async function toggleBan() { Notify.confirm('{{ "Забанить" if not target_user.is_banned else "Разбанить" }}?', 'Подтверждение', async function(ok) { if (!ok) return; const res = await fetch(`/admin/api/user/${userId}/toggle-ban`, { method:'POST' }); const d = await res.json(); if (d.success) window.location.reload(); else Notify.error(d.error); }); } // ====== RPU ====== async function loadRPU() { try { const res = await fetch(`/admin/api/user/${userId}/rpu`); const d = await res.json(); currentRPU = d; const lv = Math.round(d.rpu_level); document.getElementById('rpuLevel').textContent = lv + '%'; document.getElementById('rpuLevel').style.color = lv < 40 ? '#22c55e' : lv > 60 ? '#ef4444' : '#f59e0b'; document.getElementById('rpuLuck').textContent = d.luck_multiplier.toFixed(2) + 'x'; document.getElementById('rpuSpent').textContent = Math.round(d.stats.total_spent).toLocaleString() + ' ₽'; document.getElementById('rpuOpened').textContent = d.stats.total_opened.toLocaleString(); document.getElementById('rpuAutoStatus').textContent = d.auto_adjust ? '✅' : '❌'; } catch(_) {} } function openRPUModal() { const sliders = document.getElementById('rpuSliders'); const rarities = [ ['consumer','Consumer Grade'],['industrial','Industrial Grade'], ['mil_spec','Mil-Spec'],['restricted','Restricted'], ['classified','Classified'],['covert','Covert'],['rare_special','Rare Special'] ]; let html = ''; rarities.forEach(([k,l]) => { const v = currentRPU?.multipliers[k] || 1.0; html += `
`; }); const lv = currentRPU?.luck_multiplier || 1.0; html += `
`; sliders.innerHTML = html; document.getElementById('rpuAutoAdjust').checked = currentRPU?.auto_adjust || false; openModal('rpuModal'); } async function saveRPU() { const fd = new FormData(); ['consumer','industrial','mil_spec','restricted','classified','covert','rare_special'].forEach(k => fd.append(k, document.getElementById('rp_'+k).value)); fd.append('luck', document.getElementById('rp_luck').value); fd.append('auto_adjust', document.getElementById('rpuAutoAdjust').checked); const res = await fetch(`/admin/api/user/${userId}/rpu/update`, { method:'POST', body:fd }); const d = await res.json(); if (d.success) { Notify.success(d.message); closeModal('rpuModal'); loadRPU(); } else Notify.error(d.error); } async function setRPUPreset(preset) { const names = { lucky:'🍀 Везучий', normal:'📊 Обычный', unlucky:'🌧️ Невезучий', very_unlucky:'💀 Проклятый' }; Notify.confirm('Применить "'+names[preset]+'"?', 'Подтверждение', async function(ok) { if (!ok) return; const fd = new FormData(); fd.append('preset', preset); const res = await fetch(`/admin/api/user/${userId}/rpu/preset`, { method:'POST', body:fd }); const d = await res.json(); if (d.success) { Notify.success(d.message); loadRPU(); } else Notify.error(d.error); }); } document.addEventListener('DOMContentLoaded', loadRPU); {% endblock %}