451 lines
20 KiB
JavaScript
451 lines
20 KiB
JavaScript
// Дашборд по продажам — статика, состояние в localStorage.
|
||
var DATA = {
|
||
months: ["Янв", "Фев", "Мар", "Апр", "Май", "Июн", "Июл", "Авг", "Сен"],
|
||
monthsFull: ["Январь", "Февраль", "Март", "Апрель", "Май", "Июнь", "Июль", "Август", "Сентябрь"],
|
||
cats: [
|
||
{ id: "internet", name: "Интернет" },
|
||
{ id: "tv", name: "Телевидение" },
|
||
{ id: "mobile", name: "Мобильные услуги" },
|
||
{ id: "corporate", name: "Корпоративные услуги" },
|
||
{ id: "digital", name: "Цифровые сервисы" }
|
||
],
|
||
unit: "млн тг",
|
||
// 5 категорий × 9 месяцев (факт 2026 и сравнение 2025), млн тг
|
||
v: {
|
||
internet: [3520, 3580, 3610, 3590, 3720, 3800, 3890, 3940, 4010],
|
||
tv: [1810, 1830, 1850, 1840, 1870, 1890, 1910, 1920, 1950],
|
||
mobile: [2950, 2990, 3020, 3060, 3040, 3110, 3180, 3260, 3310],
|
||
corporate: [1620, 1650, 1660, 1720, 1740, 1770, 1810, 1840, 1900],
|
||
digital: [940, 1010, 1080, 1160, 1280, 1410, 1560, 1710, 1880]
|
||
},
|
||
pv: {
|
||
internet: [3310, 3350, 3380, 3360, 3420, 3470, 3520, 3550, 3590],
|
||
tv: [1860, 1850, 1840, 1830, 1820, 1810, 1800, 1790, 1780],
|
||
mobile: [2720, 2760, 2800, 2810, 2790, 2840, 2890, 2950, 3010],
|
||
corporate: [1520, 1540, 1550, 1580, 1600, 1620, 1650, 1670, 1700],
|
||
digital: [690, 740, 800, 870, 960, 1050, 1170, 1280, 1400]
|
||
}
|
||
};
|
||
|
||
var PERIODS = [
|
||
{ id: "m1_9", label: "Янв – Сен", from: 0, to: 8 },
|
||
{ id: "q1", label: "I квартал", from: 0, to: 2 },
|
||
{ id: "q2", label: "II квартал", from: 3, to: 5 },
|
||
{ id: "q3", label: "III квартал", from: 6, to: 8 }
|
||
];
|
||
|
||
var PALETTE = ["--kt-ai-chart-blue", "--kt-ai-chart-green", "--kt-ai-chart-orange", "--kt-ai-chart-salmon", "--kt-ai-chart-pink"];
|
||
var LS_KEY = "dash-sales-v1";
|
||
var state = load();
|
||
|
||
function load() {
|
||
try {
|
||
var raw = localStorage.getItem(LS_KEY);
|
||
if (raw) {
|
||
var s = JSON.parse(raw);
|
||
if (s && typeof s === "object") return { screen: s.screen || "overview", period: s.period || "m1_9", cat: s.cat || "all" };
|
||
}
|
||
} catch (e) {}
|
||
return { screen: "overview", period: "m1_9", cat: "all" };
|
||
}
|
||
function save() {
|
||
try { localStorage.setItem(LS_KEY, JSON.stringify(state)); } catch (e) {}
|
||
}
|
||
|
||
// ---------- данные ----------
|
||
function period() {
|
||
for (var i = 0; i < PERIODS.length; i++) if (PERIODS[i].id === state.period) return PERIODS[i];
|
||
return PERIODS[0];
|
||
}
|
||
function monthRange() {
|
||
var p = period();
|
||
var r = [];
|
||
for (var i = p.from; i <= p.to; i++) r.push(i);
|
||
return r;
|
||
}
|
||
function seriesOf(catId, monthIdx) {
|
||
var y = DATA.v[catId] || [], p = DATA.pv[catId] || [];
|
||
return { cur: y[monthIdx] || 0, prev: p[monthIdx] || 0 };
|
||
}
|
||
function sumSeries(catId) {
|
||
var r = monthRange(), cur = 0, prev = 0;
|
||
for (var i = 0; i < r.length; i++) {
|
||
var s = seriesOf(catId, r[i]);
|
||
cur += s.cur; prev += s.prev;
|
||
}
|
||
return { cur: cur, prev: prev };
|
||
}
|
||
function activeCats() {
|
||
if (state.cat === "all") return DATA.cats.slice();
|
||
for (var i = 0; i < DATA.cats.length; i++) if (DATA.cats[i].id === state.cat) return [DATA.cats[i]];
|
||
return DATA.cats.slice();
|
||
}
|
||
function totals() {
|
||
var cur = 0, prev = 0, cats = activeCats();
|
||
for (var i = 0; i < cats.length; i++) {
|
||
var t = sumSeries(cats[i].id);
|
||
cur += t.cur; prev += t.prev;
|
||
}
|
||
return { cur: cur, prev: prev };
|
||
}
|
||
function deltaPct(cur, prev) {
|
||
if (!prev) return null;
|
||
return (cur - prev) / prev * 100;
|
||
}
|
||
|
||
// ---------- форматирование ----------
|
||
function fmtInt(n) {
|
||
var s = String(Math.round(n));
|
||
var out = "", c = 0;
|
||
for (var i = s.length - 1; i >= 0; i--) {
|
||
out = s.charAt(i) + out;
|
||
c++;
|
||
if (c % 3 === 0 && i > 0) out = " " + out;
|
||
}
|
||
return out;
|
||
}
|
||
function fmtMoney(v) { return fmtInt(v) + " " + DATA.unit; }
|
||
function fmtPct(n) {
|
||
var sign = n >= 0 ? "+" : "−";
|
||
return sign + Math.abs(n).toFixed(1).replace(".", ",") + "%";
|
||
}
|
||
|
||
// ---------- рендер: сводка ----------
|
||
function kpiCard(label, value, hint, dataLong) {
|
||
var hl = dataLong ? ' data-long="true"' : "";
|
||
return '<div class="kt-ai-kpi"><span class="value"' + hl + '>' + value +
|
||
'</span><span class="label">' + label + '</span><span class="hint">' + hint + '</span></div>';
|
||
}
|
||
|
||
function barChart() {
|
||
var r = monthRange(), cats = activeCats();
|
||
var max = 0;
|
||
var sums = [];
|
||
for (var i = 0; i < r.length; i++) {
|
||
var m = 0;
|
||
for (var c = 0; c < cats.length; c++) m += (DATA.v[cats[c].id] || [])[r[i]] || 0;
|
||
sums.push(m);
|
||
if (m > max) max = m;
|
||
}
|
||
var bars = "";
|
||
var axis = "";
|
||
for (var i = 0; i < r.length; i++) {
|
||
var h = max ? Math.max(2, Math.round((sums[i] / max) * 100)) : 2;
|
||
var tip = JSON.stringify(DATA.monthsFull[r[i]] + " " + (state.cat === "all" ? "— все категории" : DATA.cats[state.cat] ? DATA.cats[state.cat].name : "") + ": " + fmtMoney(sums[i]));
|
||
bars += '<div class="cc-bar" tabindex="0" data-kt-tip="' + tip.replace(/"/g, """) + '"><i style="height:' + h + '%"></i></div>';
|
||
axis += '<span>' + DATA.months[r[i]] + '</span>';
|
||
}
|
||
var p = period();
|
||
var label = (state.cat === "all" ? "Все категории" : catName()) + ", " + p.label.toLowerCase() + " 2026";
|
||
return '<section class="kt-ai-chart-card"><div class="cc-head"><div><div class="cc-title">Выручка по месяцам, ' + label + '</div></div>' +
|
||
'<div class="cc-total"><span class="num">' + fmtInt(Math.max.apply(null, sums.concat([1]))) + '</span><span class="unit">' + DATA.unit + "</span></div></div>" +
|
||
'<div class="cc-bars">' + bars + '</div><div class="cc-axis">' + axis + "</div></section>";
|
||
}
|
||
|
||
function catName() {
|
||
for (var i = 0; i < DATA.cats.length; i++) if (DATA.cats[i].id === state.cat) return DATA.cats[i].name;
|
||
return "";
|
||
}
|
||
|
||
function donut() {
|
||
var cats = DATA.cats, vals = [], total = 0;
|
||
for (var i = 0; i < cats.length; i++) {
|
||
var t = sumSeries(cats[i].id);
|
||
vals.push(t.cur);
|
||
total += t.cur;
|
||
}
|
||
if (!total) return "";
|
||
var segs = "", off = 25;
|
||
for (var i = 0; i < cats.length; i++) {
|
||
var share = (vals[i] / total) * 100;
|
||
var c = "var(" + PALETTE[i % PALETTE.length] + ")";
|
||
segs += '<circle r="15.9155" cx="21" cy="21" fill="none" stroke="' + c + '" stroke-width="5.5" stroke-dasharray="' +
|
||
share.toFixed(2) + " " + (100 - share).toFixed(2) + '" stroke-dashoffset="' + off.toFixed(2) + '" tabindex="0" ' +
|
||
'data-kt-tip="' + cats[i].name + ": " + fmtInt(vals[i]) + " " + DATA.unit + " (" + Math.round(share) + "%)"></circle>";
|
||
off -= share;
|
||
}
|
||
var rows = "";
|
||
for (var i = 0; i < cats.length; i++) {
|
||
var c = "var(" + PALETTE[i % PALETTE.length] + ")";
|
||
var dim = (state.cat !== "all" && cats[i].id !== state.cat) ? ' style="opacity:.4"' : "";
|
||
rows += '<div class="ds-donut-row"' + dim + '><span class="sw" style="background:' + c + '"></span>' +
|
||
'<span class="lbl">' + cats[i].name + '</span>' +
|
||
'<span class="val">' + fmtInt(vals[i]) + '</span>' +
|
||
'<span class="pc">' + Math.round((vals[i] / total) * 100) + "%</span></div>";
|
||
}
|
||
return '<div class="ds-donut"><svg viewBox="0 0 42 42" role="img" aria-label="Структура по категориям">' + segs +
|
||
'<text x="21" y="21.5" text-anchor="middle" dominant-baseline="middle" font-size="5.6" font-weight="600" fill="var(--kt-ai-fg)">' +
|
||
"∑</text></svg><div class='ds-donut-list'>" + rows + "</div></div>";
|
||
}
|
||
|
||
function yoyChart() {
|
||
var cats = DATA.cats;
|
||
var max = 0, rows = [];
|
||
for (var i = 0; i < cats.length; i++) {
|
||
var t = sumSeries(cats[i].id);
|
||
if (t.cur > max) max = t.cur;
|
||
rows.push({ cat: cats[i], t: t });
|
||
}
|
||
if (!max) return "";
|
||
var body = "";
|
||
for (var i = 0; i < rows.length; i++) {
|
||
var rr = rows[i];
|
||
var w = Math.max(2, Math.round((rr.t.cur / max) * 100));
|
||
var c = "var(" + PALETTE[i % PALETTE.length] + ")";
|
||
var dim = (state.cat !== "all" && rr.cat.id !== state.cat) ? ' style="opacity:.4"' : "";
|
||
body += '<div' + dim + ' style="display:grid;grid-template-columns:minmax(90px,32%) 1fr 64px;gap:var(--kt-ai-space-3);align-items:center;padding:4px 0;font-size:var(--kt-ai-text-xs)">' +
|
||
'<span style="line-height:1.3">' + rr.cat.name + "</span>" +
|
||
'<span style="height:8px;border-radius:4px;background:var(--kt-ai-bg-soft);overflow:hidden;display:block">' +
|
||
'<span style="display:block;height:100%;border-radius:4px;width:' + w + "%;background:" + c + '"></span></span>' +
|
||
'<span class="kt-ai-num" style="text-align:right;font-weight:600">' + fmtInt(rr.t.cur) + '</span></div>';
|
||
}
|
||
return '<section class="kt-ai-chart-card"><div class="cc-head"><div><div class="cc-title">Структура по категориям, ' + period().label.toLowerCase() + " 2026</div></div>" +
|
||
'<div class="cc-total"><span class="num">' + fmtInt(max) + '</span><span class="unit">' + DATA.unit + "</span></div></div>" +
|
||
body + "</section>";
|
||
}
|
||
|
||
function summaryText() {
|
||
var t = totals(), cats = DATA.cats;
|
||
var best = null, worst = null;
|
||
for (var i = 0; i < cats.length; i++) {
|
||
var tt = sumSeries(cats[i].id);
|
||
var d = deltaPct(tt.cur, tt.prev);
|
||
if (d === null) continue;
|
||
if (best === null || d > best.d) best = { c: cats[i], d: d, t: tt };
|
||
if (worst === null || d < worst.d) worst = { c: cats[i], d: d, t: tt };
|
||
}
|
||
var p = period();
|
||
var h = '<section class="kt-ai-conclusion"><span class="title">Что показывают эти числа</span>';
|
||
h += '<span class="text">Выручка за ' + p.label.toLowerCase() + " 2026 — " + fmtMoney(t.cur) +
|
||
(deltaPct(t.cur, t.prev) !== null ? ", к прошлому году " + fmtPct(deltaPct(t.cur, t.prev)) : "") +
|
||
(state.cat === "all" ? " по всем категориям." : " в категории «" + catName() + "».") + "</span>";
|
||
if (best && worst && best.c.id !== worst.c.id) {
|
||
h += '<span class="text">Быстрее всего растёт «' + best.c.name + "» (" + fmtPct(best.d) +
|
||
"), а отстает «" + worst.c.name + "» (" + fmtPct(worst.d) + ")." + "</span>";
|
||
} else if (best) {
|
||
h += '<span class="text">Лучший результат по динамике — «' + best.c.name + "» (" + fmtPct(best.d) + ")." + "</span>";
|
||
}
|
||
return h + "</section>";
|
||
}
|
||
|
||
function renderOverview() {
|
||
var t = totals(), d = deltaPct(t.cur, t.prev);
|
||
var h = '<div class="kt-ai-kpi-strip" data-cards="true">';
|
||
h += kpiCard("Выручка", fmtMoney(t.cur), period().label + " 2026", true);
|
||
h += kpiCard("К прошлому году", d !== null ? fmtPct(d) : "—", period().label + " 2025", false);
|
||
var cats = DATA.cats, maxT = 0, lead = null;
|
||
for (var i = 0; i < cats.length; i++) {
|
||
var tt = sumSeries(cats[i].id);
|
||
if (tt.cur > maxT) { maxT = tt.cur; lead = cats[i]; }
|
||
}
|
||
var shareLead = maxT && t.cur ? Math.round(maxT / t.cur * 100) : 0;
|
||
h += kpiCard("Ведущая категория", lead ? lead.name : "—", shareLead + "% от выручки", true);
|
||
h += kpiCard("Средний месяц", fmtMoney(Math.round(t.cur / monthRange().length)), "за " + monthRange().length + " мес.", true);
|
||
h += "</div>";
|
||
h += '<div class="ds-grid-2">' + barChart() + yoyChart() + "</div>";
|
||
if (state.cat === "all") {
|
||
h += '<div class="ds-h3">Структура выручки по категориям</div>' +
|
||
'<section class="kt-ai-chart-card">' + donut() + "</section>";
|
||
}
|
||
h += summaryText();
|
||
return h;
|
||
}
|
||
|
||
// ---------- рендер: детали ----------
|
||
function detailsToolbar() {
|
||
var pOpts = "";
|
||
for (var i = 0; i < PERIODS.length; i++) {
|
||
pOpts += '<option value="' + PERIODS[i].id + '"' + (PERIODS[i].id === state.period ? " selected" : "") + ">" + PERIODS[i].label + "</option>";
|
||
}
|
||
var cOpts = '<option value="all"' + (state.cat === "all" ? " selected" : "") + ">Все категории</option>";
|
||
for (var i = 0; i < DATA.cats.length; i++) {
|
||
cOpts += '<option value="' + DATA.cats[i].id + '"' + (DATA.cats[i].id === state.cat ? " selected" : "") + ">" + DATA.cats[i].name + "</option>";
|
||
}
|
||
return '<div class="ds-filters">' +
|
||
'<select class="kt-ai-select" id="fPeriod" aria-label="Период">' + pOpts + "</select>" +
|
||
'<select class="kt-ai-select" id="fCat" aria-label="Категория">' + cOpts + "</select>" +
|
||
'<button class="kt-ai-btn ds-reset" data-variant="ghost" id="fReset">Сбросить</button></div>';
|
||
}
|
||
|
||
function detailsKpis() {
|
||
var t = totals();
|
||
var curCat = activeCats().length === 1 ? activeCats()[0] : null;
|
||
var h = '<div class="kt-ai-kpi-strip" data-cards="true">';
|
||
h += kpiCard(curCat ? curCat.name : "Все категории", fmtMoney(t.cur), period().label + " 2026", true);
|
||
var d = deltaPct(t.cur, t.prev);
|
||
h += kpiCard("К прошлому году", d !== null ? fmtPct(d) : "—", period().label + " 2025", false);
|
||
h += kpiCard("Средний месяц", fmtMoney(Math.round(t.cur / monthRange().length)), "за " + monthRange().length + " мес.", true);
|
||
if (state.cat === "all") {
|
||
var lead = null, maxT2 = 0;
|
||
for (var i = 0; i < DATA.cats.length; i++) {
|
||
var tt = sumSeries(DATA.cats[i].id);
|
||
if (tt.cur > maxT2) { maxT2 = tt.cur; lead = DATA.cats[i]; }
|
||
}
|
||
h += kpiCard("Ведущая категория", lead ? lead.name : "—", Math.round(maxT2 / (t.cur || 1) * 100) + "% от выручки", true);
|
||
} else {
|
||
var totalAll = 0;
|
||
for (var j = 0; j < DATA.cats.length; j++) totalAll += sumSeries(DATA.cats[j].id).cur;
|
||
h += kpiCard("Доля в выручке", Math.round(t.cur / (totalAll || 1) * 100) + "%", "за период", false);
|
||
}
|
||
return h + "</div>";
|
||
}
|
||
|
||
function detailsTable() {
|
||
var r = monthRange();
|
||
var cats = activeCats();
|
||
var totalCur = 0, totalPrev = 0, totalDelta = 0;
|
||
var rows = "";
|
||
for (var i = 0; i < r.length; i++) {
|
||
var mi = r[i];
|
||
var mCur = 0, mPrev = 0;
|
||
for (var c = 0; c < cats.length; c++) {
|
||
var s = seriesOf(cats[c].id, mi);
|
||
mCur += s.cur; mPrev += s.prev;
|
||
}
|
||
totalCur += mCur; totalPrev += mPrev; totalDelta += mCur - mPrev;
|
||
rows += '<tr><td>' + DATA.monthsFull[mi] + '</td>' +
|
||
'<td class="num">' + fmtMoney(mCur) + "</td>" +
|
||
'<td class="num">' + fmtMoney(mPrev) + "</td>" +
|
||
'<td class="num">' + (mCur - mPrev >= 0 ? "+" : "−") + fmtInt(Math.abs(mCur - mPrev)) + "</td>" +
|
||
'<td class="num">' + (mPrev ? fmtPct((mCur - mPrev) / mPrev * 100) : "—") + "</td></tr>";
|
||
}
|
||
var footDelta = totalDelta;
|
||
return '<div class="kt-ai-table-wrap"><table class="kt-ai-table">' +
|
||
"<thead><tr><th>Месяц</th>" +
|
||
'<th class="num">Выручка 2026</th><th class="num">' + period().label + " 2025</th>" +
|
||
'<th class="num">Δ, млн тг</th><th class="num">Δ, %</th></tr></thead>' +
|
||
"<tbody>" + rows +
|
||
'<tr style="border-top:1px solid var(--kt-ai-border-strong)"><td>Итого</td>' +
|
||
'<td class="num" style="font-weight:600">' + fmtMoney(totalCur) + "</td>" +
|
||
'<td class="num">' + fmtMoney(totalPrev) + "</td>" +
|
||
'<td class="num">' + (footDelta >= 0 ? "+" : "−") + fmtInt(Math.abs(footDelta)) + "</td>" +
|
||
'<td class="num">' + (totalPrev ? fmtPct((totalCur - totalPrev) / totalPrev * 100) : "—") + "</td></tr>" +
|
||
"</tbody></table></div>";
|
||
}
|
||
|
||
function renderDetails() {
|
||
var h = detailsToolbar();
|
||
h += detailsKpis();
|
||
h += '<div class="ds-h3">По месяцам, ' + period().label.toLowerCase();
|
||
h += state.cat === "all" ? " — все категории" : " — " + catName();
|
||
h += "</div>";
|
||
h += '<div class="kt-ai-chart-card"><div class="cc-bars" style="height:170px">' + detailsBars() + "</div>" +
|
||
'<div class="cc-axis">' + detailsAxis() + "</div></div>";
|
||
h += detailsTable();
|
||
if (state.cat === "all") {
|
||
h += '<div class="ds-h3">Разбивка по категориям</div>' + categoryBreakdown();
|
||
}
|
||
return h;
|
||
}
|
||
|
||
function detailsBars() {
|
||
var r = monthRange(), cats = activeCats();
|
||
var max = 0, sums = [];
|
||
for (var i = 0; i < r.length; i++) {
|
||
var m = 0;
|
||
for (var c = 0; c < cats.length; c++) m += (DATA.v[cats[c].id] || [])[r[i]] || 0;
|
||
sums.push(m);
|
||
if (m > max) max = m;
|
||
}
|
||
var h = "";
|
||
for (var i = 0; i < r.length; i++) {
|
||
var pct = max ? Math.max(2, Math.round((sums[i] / max) * 100)) : 2;
|
||
var tip = JSON.stringify(DATA.monthsFull[r[i]] + ": " + fmtMoney(sums[i]));
|
||
h += '<div class="cc-bar" tabindex="0" data-kt-tip="' + tip.replace(/"/g, """) + '"><i style="height:' + pct + '%"></i></div>';
|
||
}
|
||
return h;
|
||
}
|
||
function detailsAxis() {
|
||
var r = monthRange(), h = "";
|
||
for (var i = 0; i < r.length; i++) h += '<span>' + DATA.months[r[i]] + "</span>";
|
||
return h;
|
||
}
|
||
|
||
function categoryBreakdown() {
|
||
var totalAll = 0;
|
||
var sums = [];
|
||
for (var i = 0; i < DATA.cats.length; i++) {
|
||
var t = sumSeries(DATA.cats[i].id);
|
||
sums.push(t);
|
||
totalAll += t.cur;
|
||
}
|
||
var rows = "";
|
||
for (var i = 0; i < DATA.cats.length; i++) {
|
||
var t = sums[i];
|
||
var d = deltaPct(t.cur, t.prev);
|
||
var tone = d === null ? "gray" : (d >= 0 ? "green" : "red");
|
||
rows += '<tr><td>' + DATA.cats[i].name + "</td>" +
|
||
'<td class="num">' + fmtMoney(t.cur) + "</td><td class=\"num\">" + fmtMoney(t.prev) + "</td>" +
|
||
'<td class="num">' + Math.round((t.cur / (totalAll || 1)) * 100) + "%</td>" +
|
||
'<td class="num">' + (d !== null ? fmtPct(d) : "—") + "</td></tr>";
|
||
}
|
||
return '<div class="kt-ai-table-wrap"><table class="kt-ai-table">' +
|
||
"<thead><tr><th>Категория</th><th class='num'>2026, " + period().label + '</th><th class="num">2025, ' + period().label +
|
||
"</th><th class='num'>Доля</th><th class='num'>Δ, %</th></tr></thead><tbody>" + rows + "</tbody></table></div>";
|
||
}
|
||
|
||
// ---------- главный рендер ----------
|
||
function render() {
|
||
var view = document.getElementById("view");
|
||
if (!view) return;
|
||
var p = period();
|
||
var title = document.getElementById("pageTitle");
|
||
var sub = document.getElementById("pageSub");
|
||
if (title) title.textContent = state.screen === "overview" ? "Сводка" : "Детали";
|
||
if (sub) sub.textContent = p.label + " · " + (state.cat === "all" ? "все категории" : catName());
|
||
view.innerHTML = '<div class="ds-screen" data-screen="overview"' + (state.screen === "overview" ? ' data-active="true"' : "") + ">" + renderOverview() + "</div>" +
|
||
'<div class="ds-screen" data-screen="details"' + (state.screen === "details" ? ' data-active="true"' : "") + ">" + renderDetails() + "</div>";
|
||
bindDetails();
|
||
bindNav();
|
||
}
|
||
|
||
function bindNav() {
|
||
var items = document.querySelectorAll(".ds-nav .kt-ai-nav-item");
|
||
for (var i = 0; i < items.length; i++) {
|
||
items[i].setAttribute("data-active", String(items[i].getAttribute("data-screen") === state.screen));
|
||
}
|
||
}
|
||
|
||
function go(screen) {
|
||
if (state.screen === screen) return;
|
||
state.screen = screen;
|
||
save();
|
||
render();
|
||
var view = document.getElementById("view");
|
||
if (view) view.scrollTop = 0;
|
||
window.scrollTo(0, 0);
|
||
}
|
||
|
||
function bindDetails() {
|
||
var fp = document.getElementById("fPeriod");
|
||
var fc = document.getElementById("fCat");
|
||
var fr = document.getElementById("fReset");
|
||
if (fp) fp.addEventListener("change", function () {
|
||
state.period = fp.value; save(); render();
|
||
});
|
||
if (fc) fc.addEventListener("change", function () {
|
||
state.cat = fc.value; save(); render();
|
||
});
|
||
if (fr) fr.addEventListener("click", function () {
|
||
state.period = "m1_9"; state.cat = "all"; save(); render();
|
||
});
|
||
}
|
||
|
||
document.addEventListener("DOMContentLoaded", function () {
|
||
render();
|
||
var nav = document.querySelectorAll(".ds-nav .kt-ai-nav-item");
|
||
for (var i = 0; i < nav.length; i++) {
|
||
(function (el) {
|
||
el.addEventListener("click", function () {
|
||
var s = el.getAttribute("data-screen");
|
||
if (s) go(s);
|
||
});
|
||
})(nav[i]);
|
||
}
|
||
var burger = document.querySelector(".ds-burger");
|
||
if (burger) burger.addEventListener("click", function () {
|
||
var sb = document.getElementById("sidebar");
|
||
if (sb) sb.toggleAttribute("data-open");
|
||
});
|
||
});
|