static/js/common.js (view raw)
1document.addEventListener('DOMContentLoaded', function () {
2 // navbar
3 const navObject = document.getElementsByTagName("nav")[0];
4 for (const page of navPages) {
5 const a = document.createElement("a");
6 a.innerText = page.name;
7 a.href = page.href;
8 navObject.appendChild(a)
9 }
10 // favicon
11 document.getElementsByTagName("head")[0].innerHTML += favicon;
12});
13
14// Global constants
15const navPages = [
16 { name: "Home", href: "/" },
17 { name: "Bookmakers", href: "/bookmakers" },
18 { name: "Accounts", href: "/accounts" },
19 { name: "Records", href: "/records" },
20];
21const favicon = `<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>💰</text></svg>">`;
22
23const currency = "€";
24const locale = "it-IT";
25
26const flatpickrOptions = {
27 enableTime: true,
28 time_24hr: true,
29 dateFormat: "Z",
30};
31
32// Cell formatters
33function formatValue(v) {
34 if (v === undefined) return 0;
35 return (v / 100).toFixed(2);
36}
37
38function restoreValue(v) {
39 return Number(v) * 100;
40}
41
42function formatCash(v) {
43 if (v === 0) return "-";
44 return `${v > 0 ? "+" : ""}${formatValue(v)}${currency}`;
45}
46
47function formatPercentage(v) {
48 if (v === 0) return "-";
49 return formatValue(v) + "%";
50}
51
52function formatDate(dateString) {
53 return (new Date(dateString)).toLocaleString(locale);
54}
55
56function formatBoolean(value, id) {
57 const input = document.createElement("input");
58 input.type = "checkbox";
59 if (value) input.setAttribute("checked", "");
60 input.disabled = true;
61 //input.setAttribute("data-id", id);
62 //input.onchange = undefined;
63 return input.outerHTML;
64}
65
66// Input components
67function newInputText(label, value, name) {
68 const l = document.createElement("label");
69 const input = document.createElement("input");
70 input.className = name;
71 input.type = "text";
72 input.placeholder = label;
73 input.value = value ?? "";
74 l.innerHTML += label + "<br />";
75 l.appendChild(input);
76 return l;
77}
78
79function newInputCheckbox(label, value, name) {
80 const l = document.createElement("label");
81 const input = document.createElement("input");
82 input.className = name;
83 input.type = "checkbox";
84 if (value) input.setAttribute("checked", "");
85 l.appendChild(input);
86 l.innerHTML += label;
87 return l;
88}
89
90function newInputDate(label, value, name) {
91 const l = document.createElement("label");
92 const input = document.createElement("input");
93 input.className = name;
94 input.placeholder = label;
95 input.value = value ?? "";
96 flatpickr(input, flatpickrOptions);
97 l.innerHTML += label + "<br />";
98 l.appendChild(input);
99 return l;
100}
101
102function newInputSelect(label, value, name, options) {
103 const l = document.createElement("label");
104 const input = document.createElement("select");
105 input.className = name;
106 input.placeholder = label;
107 for (const o of options) {
108 input.options.add(new Option(o.name, o.id));
109 }
110 input.value = value ?? "";
111 l.innerHTML += label + "<br />";
112 l.appendChild(input);
113 return l;
114}
115
116// Functions
117function getQueryStringID() {
118 return Number(new URLSearchParams(window.location.search).get("id") ?? 0);
119}
120
121async function myConfirm(f, id) {
122 if (confirm("Are you sure?")) return await f(id);
123 return false;
124}
125
126async function handleFetchResult(res) {
127 if (!res.ok) {
128 console.error(await res.text())
129 return
130 }
131
132 return await res.json();
133}
134
135async function myFetch(url) {
136 res = await fetch(url);
137 return await handleFetchResult(res);
138}
139
140async function myFetchPOST(url, body) {
141 const res = await fetch(url, {
142 method: 'POST',
143 headers: { 'Content-Type': 'application/json' },
144 body: body ? JSON.stringify(body) : undefined,
145 });
146 return await handleFetchResult(res);
147}
148
149async function myFetchDELETE(url) {
150 const res = await fetch(url, { method: 'DELETE' });
151 return await handleFetchResult(res);
152}
153
154// API calls
155async function getBookmakers() {
156 return await myFetch('/api/bookmakers');
157}
158
159async function getBookmaker(id) {
160 return await myFetch(`/api/bookmakers/${id}`);
161}
162
163async function saveBookmaker(payload) {
164 return await myFetchPOST("/api/bookmakers", payload);
165}
166
167async function deleteBookmaker(id) {
168 return await myFetchDELETE(`/api/bookmakers/${id}`);
169}
170
171
172async function getAccounts() {
173 return await myFetch('/api/accounts');
174}
175
176async function getAccount(id) {
177 return await myFetch(`/api/accounts/${id}`);
178}
179
180async function saveAccount(payload) {
181 return await myFetchPOST("/api/accounts", payload);
182}
183
184async function deleteAccount(id) {
185 return await myFetchDELETE(`/api/accounts/${id}`);
186}
187
188
189async function getRecords() {
190 return await myFetch('/api/records');
191}
192
193async function getRecord(id) {
194 return await myFetch(`/api/records/${id}`);
195}
196
197async function saveRecord(payload) {
198 return await myFetchPOST("/api/records", payload);
199}
200
201async function deleteRecord(id) {
202 return await myFetchDELETE(`/api/records/${id}`);
203}