Files
foodlinkk-command-center/cockpit/static/js/beurs.js
T

101 lines
3.2 KiB
JavaScript
Raw Normal View History

window.beursHub = function () {
return {
tab: new URLSearchParams(location.search).get('tab') || 'beurs',
busy: false,
lastRefresh: '',
listed: [],
unlisted: [],
summary: {},
trends: { halal_meat_trends: [], top_dishes: [], market_trends: [] },
concepts: [],
events: [],
platformStats: {},
eventFilter: '',
pollTimer: null,
indicatorStyle: { left: '0%', width: '25%' },
init() {
this.updateIndicator();
this.refreshAll();
this.pollTimer = setInterval(() => {
if (this.tab === 'events') this.loadEvents(false);
}, 5000);
},
setTab(t) {
this.tab = t;
const url = new URL(location.href);
url.searchParams.set('tab', t);
history.replaceState({}, '', url);
this.updateIndicator();
if (t === 'trends' && !this.trends.halal_meat_trends?.length) this.loadTrends();
if (t === 'concepten' && !this.concepts.length) this.loadConcepts();
if (t === 'events') this.loadEvents();
},
updateIndicator() {
const tabs = ['beurs', 'trends', 'concepten', 'events'];
const i = tabs.indexOf(this.tab);
const w = 100 / tabs.length;
this.indicatorStyle = { left: (i * w) + '%', width: w + '%' };
},
sparkPoints(arr) {
if (!arr || !arr.length) return '';
const min = Math.min.apply(null, arr);
const max = Math.max.apply(null, arr);
const range = max - min || 1;
return arr.map(function (v, idx) {
var x = (idx / (arr.length - 1 || 1)) * 100;
var y = 28 - ((v - min) / range) * 24;
return x.toFixed(1) + ',' + y.toFixed(1);
}).join(' ');
},
async refreshAll() {
this.busy = true;
try {
await Promise.all([
this.loadMarket(),
this.loadTrends(),
this.loadConcepts(),
this.loadEvents(false),
]);
this.lastRefresh = new Date().toLocaleString('nl-NL');
if (typeof Cockpit !== 'undefined') Cockpit.toast('Beurs data bijgewerkt', 'success');
} catch (e) {
if (typeof Cockpit !== 'undefined') Cockpit.toast(e.message, 'error');
}
this.busy = false;
},
async loadMarket() {
const d = await fetch('/api/retail/market/supermarkets').then(function (r) { return r.json(); });
this.listed = d.listed || [];
this.unlisted = d.unlisted_nl || [];
this.summary = d.summary || {};
},
async loadTrends() {
const d = await fetch('/api/retail/market/food-trends').then(function (r) { return r.json(); });
this.trends = d;
},
async loadConcepts() {
const d = await fetch('/api/retail/market/concepts?limit=6').then(function (r) { return r.json(); });
this.concepts = d.concepts || [];
},
async loadEvents(toast) {
var q = this.eventFilter ? '?limit=80&agent=' + encodeURIComponent(this.eventFilter) : '?limit=80';
try {
var r = await fetch('/api/live/platform' + q).then(function (x) { return x.json(); });
this.events = r.events || [];
this.platformStats = r.stats || {};
} catch (e) {
if (toast !== false && typeof Cockpit !== 'undefined') Cockpit.toast(e.message, 'error');
}
},
};
};