// ==UserScript==
// ==/UserScript==
(function() {
'use strict';
// Ждём, пока интерфейс YouGile полностью загрузится
const checkUI = setInterval(() => {
if (typeof UI !== 'undefined' && document.body) {
clearInterval(checkUI);
initCalculator();
}
}, 500);
function initCalculator() {
// Создаём контейнер для плавающей кнопки
const toggleBtn = document.createElement('div');
toggleBtn.id = 'profit-calc-toggle';
toggleBtn.textContent = '🧮 Калькулятор';
toggleBtn.style.cssText = `
position: fixed; bottom: 20px; right: 20px;
background: #3b82f6; color: white;
padding: 10px 16px; border-radius: 24px;
font-family: sans-serif; font-size: 14px; font-weight: 600;
cursor: pointer; box-shadow: 0 4px 12px rgba(0,0,0,0.15);
z-index: 99999; user-select: none;
transition: background 0.2s;
`;
toggleBtn.onmouseenter = () => toggleBtn.style.background = '#2563eb';
toggleBtn.onmouseleave = () => toggleBtn.style.background = '#3b82f6';
// Создаём модальное окно (скрытое по умолчанию)
const modal = document.createElement('div');
modal.id = 'profit-calc-modal';
modal.style.cssText = `
display: none; position: fixed; top: 50%; left: 50%;
transform: translate(-50%, -50%);
width: 520px; max-width: 95vw; max-height: 90vh;
overflow-y: auto; background: #fff; border-radius: 12px;
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
z-index: 100000; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
`;
// Внутреннее содержимое модального окна — ваш калькулятор
modal.innerHTML = `
Рентабельность договора
Счета поставщиков
—
Введите стоимость договора
Доход0 ₽
Счета0 ₽
Прибыль0 ₽
Рентабельность = (Доход − Счета) / Доход × 100%
`;
// Создаём затемнённый фон
const overlay = document.createElement('div');
overlay.id = 'profit-calc-overlay';
overlay.style.cssText = `
display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%;
background: rgba(0,0,0,0.4); z-index: 99999;
`;
document.body.appendChild(toggleBtn);
document.body.appendChild(overlay);
document.body.appendChild(modal);
// --- Логика калькулятора (адаптированная) ---
const contractEl = modal.querySelector('#pc-contract');
const addonEl = modal.querySelector('#pc-addon');
const listEl = modal.querySelector('#pc-invoices');
const resEl = modal.querySelector('#pc-res');
const pctEl = modal.querySelector('#pc-pct');
const msgEl = modal.querySelector('#pc-msg');
const revEl = modal.querySelector('#pc-rev');
const costEl = modal.querySelector('#pc-cost');
const profEl = modal.querySelector('#pc-profit');
function num(v) {
if (!v) return 0;
const n = parseFloat(String(v).replace(/\s|\u00A0/g, '').replace(',', '.'));
return isNaN(n) ? 0 : n;
}
function money(n) { return n.toLocaleString('ru-RU', { maximumFractionDigits: 2 }) + ' ₽'; }
function pctFmt(p) { return p.toLocaleString('ru-RU', { minimumFractionDigits: 1, maximumFractionDigits: 1 }) + '%'; }
function addRow(focus) {
const row = document.createElement('div');
row.className = 'pc-row';
row.innerHTML = '
';
listEl.appendChild(row);
row.querySelector('.pc-del').addEventListener('click', () => { row.remove(); calc(); });
row.querySelectorAll('input').forEach(inp => {
inp.addEventListener('input', calc);
});
if (focus) row.querySelector('.pc-name').focus();
return row;
}
function calc() {
const revenue = num(contractEl.value) + num(addonEl.value);
let costs = 0;
listEl.querySelectorAll('.pc-amount').forEach(i => costs += num(i.value));
const profit = revenue - costs;
const pct = revenue > 0 ? (profit / revenue) * 100 : null;
revEl.textContent = money(revenue);
costEl.textContent = money(costs);
profEl.textContent = money(profit);
profEl.className = profit < 0 ? 'pc-neg' : '';
resEl.className = 'pc-res';
if (pct === null) {
resEl.classList.add('pc-neutral');
pctEl.textContent = '—';
msgEl.textContent = 'Введите стоимость договора';
return;
}
pctEl.textContent = pctFmt(pct);
if (pct < 0) {
resEl.classList.add('pc-bad');
msgEl.textContent = 'Убыток! Срочно ищем, где накосячили';
} else if (pct < 35) {
resEl.classList.add('pc-bad');
msgEl.textContent = 'Плохо — где-то накосячили';
} else if (pct < 40) {
resEl.classList.add('pc-warn');
msgEl.textContent = 'Молодец, но мы можем лучше';
} else {
resEl.classList.add('pc-good');
msgEl.textContent = 'Отлично! 🎉';
}
}
contractEl.addEventListener('input', calc);
addonEl.addEventListener('input', calc);
modal.querySelector('#pc-addBtn').addEventListener('click', () => addRow(true));
// Стартовые строки
addRow(); addRow(); addRow();
calc();
// --- Управление окном ---
function openModal() { overlay.style.display = 'block'; modal.style.display = 'block'; }
function closeModal() { overlay.style.display = 'none'; modal.style.display = 'none'; }
toggleBtn.addEventListener('click', openModal);
overlay.addEventListener('click', closeModal);
modal.querySelector('#profit-calc-close').addEventListener('click', closeModal);
// Закрытие по Esc
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && modal.style.display === 'block') closeModal();
});
}
})();