all repos — piggy @ 0.0.2

Dead simple finance manager in Go, HTML and JS.

static/js/common.js (view raw)

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