Improve CEO cockpit clarity and Revenue visuals, with Hermes briefing.

Tighten overview KPIs/pipeline height, add selectable Revenue views and a resizable sidebar, and keep supporting Hermes/Wereldexport updates.
This commit is contained in:
Aissa
2026-07-30 11:53:43 +00:00
parent 5dd69a1138
commit 62239f0a4e
14 changed files with 1876 additions and 647 deletions
+38 -8
View File
@@ -2,8 +2,8 @@
var WIDGET_META = {
kpis: { title: 'CEO KPI\'s', icon: '📊' },
executive: { title: 'Alles op een rij', icon: '📋' },
briefing: { title: 'Herman briefing', icon: '📝' },
retail: { title: 'Retail operatie', icon: '🏪' },
briefing: { title: 'Focus & trends', icon: '🎯' },
news: { title: 'Laatste nieuws', icon: '📰' },
analytics: { title: 'Data & analytics', icon: '📈' },
approvals: { title: 'Agent goedkeuringen', icon: '✓' },
feed: { title: 'Agent feed', icon: '⚡' },
@@ -26,10 +26,16 @@
nas_docs: { label: 'NAS documenten', sub: 'geanalyseerd', icon: '📊', color: '#818cf8', link: '/documents' },
promo_campaigns: { label: 'Promo campagnes', sub: 'actief', icon: '📁', color: '#c084fc', link: '/marketing?tab=reclame' },
market_best: { label: 'Aandeel top', sub: 'retail markt', icon: '📈', color: '#34d399', link: '/analytics' },
margin_month: { label: 'Marge / mnd', sub: 'Revenue Cockpit', icon: '💶', color: '#fbbf24', link: '/revenue-cockpit' },
margin_year: { label: 'Marge / jr', sub: 'Revenue Cockpit', icon: '📅', color: '#38bdf8', link: '/revenue-cockpit' },
open_steps: { label: 'Open stappen', sub: 'opvolging nodig', icon: '🎯', color: '#f472b6', link: '/revenue-cockpit' },
revenue_deals: { label: 'Actieve deals', sub: 'met marge', icon: '💼', color: '#4ade80', link: '/revenue-cockpit' },
};
var DEFAULT_LAYOUT = Object.keys(WIDGET_META);
var DEFAULT_KPIS = ['pipeline', 'clients_active', 'crm_partnerships', 'supermarkets', 'trending_food', 'pending_approvals'];
var DEFAULT_LAYOUT = ['kpis', 'executive', 'analytics', 'briefing', 'news', 'approvals', 'feed'];
var CEO_LAYOUT = ['kpis', 'executive', 'analytics', 'briefing', 'news'];
var DEFAULT_KPIS = ['margin_month', 'margin_year', 'open_steps', 'revenue_deals', 'crm_partnerships', 'supermarkets'];
var CEO_KPIS = ['margin_month', 'margin_year', 'open_steps', 'revenue_deals', 'crm_partnerships', 'supermarkets'];
function loadPrefs() {
return fetch('/api/preferences/ui').then(function (r) { return r.json(); }).catch(function () {
@@ -73,21 +79,42 @@
return savePrefs(patch);
}
function ceoKpis(prefs) {
var k = (prefs && prefs.dashboard_kpis) || [];
if (!k.length || k.indexOf('margin_month') < 0) return CEO_KPIS.slice();
// ensure core revenue KPIs present without dropping user extras
var need = ['margin_month', 'open_steps', 'revenue_deals'];
need.forEach(function (id) {
if (k.indexOf(id) < 0) k = [id].concat(k);
});
return k.slice(0, 6);
}
function visibleLayout(prefs) {
var layout = prefs.dashboard_layout || DEFAULT_LAYOUT.slice();
var widgets = prefs.dashboard_widgets || defaultWidgets();
return layout.filter(function (id) { return widgets[id] !== false; });
var rest = (prefs.dashboard_layout || DEFAULT_LAYOUT.slice()).filter(function (id) {
return CEO_LAYOUT.indexOf(id) < 0 && widgets[id] !== false;
});
var top = CEO_LAYOUT.filter(function (id) { return widgets[id] !== false; });
return top.concat(rest);
}
function applyOrder(container, order) {
if (!container) return;
var map = {};
var leftovers = [];
Array.from(container.children).forEach(function (el) {
if (el.dataset && el.dataset.widget) map[el.dataset.widget] = el;
else leftovers.push(el);
});
order.forEach(function (id) {
if (map[id]) container.appendChild(map[id]);
var seen = {};
(order || []).forEach(function (id) {
if (map[id]) { container.appendChild(map[id]); seen[id] = true; }
});
Object.keys(map).forEach(function (id) {
if (!seen[id]) container.appendChild(map[id]);
});
leftovers.forEach(function (el) { container.appendChild(el); });
}
function applyVisibility(container, widgets) {
@@ -257,12 +284,15 @@
WIDGET_META: WIDGET_META,
KPI_META: KPI_META,
DEFAULT_KPIS: DEFAULT_KPIS,
CEO_KPIS: CEO_KPIS,
ceoKpis: ceoKpis,
loadPrefs: loadPrefs,
saveLayout: saveLayout,
saveViz: saveViz,
savePrefs: savePrefs,
saveDashboardConfig: saveDashboardConfig,
visibleLayout: visibleLayout,
CEO_LAYOUT: CEO_LAYOUT,
applyOrder: applyOrder,
applyVisibility: applyVisibility,
initDrag: initDrag,