async function checkOnline() { if (!navigator.onLine) { console.log("Offline (no network connection)"); return false; } try { const response = await fetch( "https://www.google.com/favicon.ico?" + new Date().getTime(), { mode: "no-cors", }, ); return true; } catch (error) { console.log("Connected to network but no internet access"); return false; } } function showDashboard() { const offline = document.querySelector(".offline"); offline.remove(); document.querySelector(".dashboard").style.display = "flex"; } const btnOffline = document.querySelector("#btn-offline-add"); const divActions = document.querySelector("#actions"); let visible = true; setInterval(async () => { const isOnline = await checkOnline(); //const isOnline = false; // REMOVE!!! if (!isOnline) { if (visible) { console.log("OFFLINE!!!"); Array.from(divActions.children).forEach( (el) => (el.style.display = "none"), ); visible = false; btnOffline.style.display = "block"; document.querySelector(".hd-left").addEventListener("click", () => { showDashboard(); }); } } if (localStorage.getItem("refuelOfflineData")) { Array.from(divActions.children).forEach( (el) => (el.style.display = "none"), ); btnOffline.style.display = "block"; btnOffline.textContent = "Sync data"; btnOffline.setAttribute("disabled", "disabled"); } if (isOnline && !visible) { console.log("BACK ONLINE!!!"); visible = true; btnOffline.removeAttribute("disabled", "disabled"); // TODO: show buttons back, add sync button instead of record creation // If user is in a process of adding new offline refuel record, let him finish // Clear the local storage on each login } //}, 5000); }, 1000); window.onload = async () => { const rawData = await fetch("/api/v1/vehicles/get", { method: "GET", credentials: "include", }); const data = await rawData.json(); console.log("Fetched:", data); localStorage.setItem("vehicles", JSON.stringify(data)); console.log(JSON.parse(localStorage.getItem("vehicles"))); }; btnOffline.addEventListener("click", async (e) => { e.preventDefault(); if (btnOffline.textContent == "Sync data") { if (!visible) { alert("You're still offline. Try again later"); return; } try { let data = localStorage.getItem("refuelOfflineData"); if (!data) { console.error("No offline data found"); alert("No offline data found"); return; } data = JSON.parse(data); const formData = new FormData(); for (const key in data) { if (data.hasOwnProperty(key)) { formData.append(key, data[key]); } } const res = await fetch("/refuel/create", { method: "POST", body: formData, credentials: "include", }); if (!res.ok) { if (res.status == 400) { const html = await res.text(); document.open(); document.write(html); document.close(); localStorage.removeItem("refuelOfflineData"); return; } else { throw new Error(`Server error: ${res.statusText}`); } } localStorage.removeItem("refuelOfflineData"); location.reload(); } catch (err) { console.error(err); alert("Something went wrong"); location.reload(); } return; } document.querySelector("section.dashboard").style.display = "none"; try { vehicles = localStorage.getItem("vehicles"); if (vehicles === null) throw new Error("No data was saved locally"); vehicles = JSON.parse(vehicles); } catch (err) { console.error(err); const offline = document.createElement("div"); offline.classList.add("offline"); offline.innerHTML = `
You're Offline

No data was saved locally, please try again later

`; document.querySelector("main").appendChild(offline); // TODO: Add button to navigate back to offline dashboard return; } const offline = document.createElement("div"); offline.classList.add("offline"); offline.innerHTML = `
You're Offline

You can create an fuel record locally on your device and sync it later

Create offline record

`; document.querySelector("main").appendChild(offline); const inp_lit = document.querySelector("input#liters"); const inp_ppl = document.querySelector("input#price_per_liter"); const inp_tot = document.querySelector("input#total_price"); const rnd = (num) => Math.round((num + Number.EPSILON) * 100) / 100; function calculate() { let liters = Number(inp_lit.value); let price_per_liter = Number(inp_ppl.value); let total_price = Number(inp_tot.value); if (price_per_liter > 0 && liters > 0) { total_price = rnd(liters * price_per_liter); } if (price_per_liter > 0 && total_price > 0) { liters = rnd(total_price / price_per_liter); } if (liters > 0 && total_price > 0) { price_per_liter = rnd(total_price / liters); } inp_lit.value = liters; inp_ppl.value = price_per_liter; inp_tot.value = total_price; } [inp_lit, inp_ppl, inp_tot].forEach((inp) => { inp.addEventListener("change", () => { calculate(); }); }); const btnSubmit = document.querySelector("#btn-offline-submit"); btnSubmit.addEventListener("click", (e) => { e.preventDefault(); const formData = { vehicle: document.querySelector("form#offline_refuel_add #vehicle").value, fuel_type: document.querySelector("form#offline_refuel_add #fuel_type") .value, liters: document.querySelector("form#offline_refuel_add #liters").value, price_per_liter: document.querySelector( "form#offline_refuel_add #price_per_liter", ).value, total_price: document.querySelector( "form#offline_refuel_add #total_price", ).value, mileage: document.querySelector("form#offline_refuel_add #mileage").value, note: document.querySelector("form#offline_refuel_add #note").value, }; console.log("formData", formData); localStorage.setItem("refuelOfflineData", JSON.stringify(formData)); alert("Data was locally saved. Sync it later!"); showDashboard(); }); });