Upozornění:
Veškerý zde vystavený kód je mým autorským dílem a je zveřejněn výhradně za účelem ukázky stylu mé práce.
Kód slouží pouze k nahlédnutí – jakékoliv kopírování, šíření, úpravy či jiné využití bez mého výslovného souhlasu nejsou povoleny.
Zůstává mým duševním vlastnictvím ve smyslu autorského zákona.
Děkuji za pochopení.
← Zpět na seznam
RoSaaRi (JS)
let currentCallback = null;
function aktualizujStavPalivaVHlavicce() {
const el = document.getElementById("stav_v_nadrzi_l");
const palivo = parseFloat(localStorage.getItem("stav_v_nadrzi_l"));
if (el && !isNaN(palivo)) {
el.textContent = palivo;
el.classList.toggle("palivo-nizke", palivo < 10);
}
}
window.addEventListener("DOMContentLoaded", () => {
function prepocitejStavPaliva() {
const spotreba = parseFloat(localStorage.getItem("spotreba")) || 0;
const lastTach = parseInt(localStorage.getItem("lastTach")) || 0;
const predchoziTach = parseInt(localStorage.getItem("predchoziTach")) || parseInt(localStorage.getItem("startKm")) || 0;
let puvodniStav = parseFloat(localStorage.getItem("stav_v_nadrzi_l")) || 0;
if (!spotreba || !lastTach || lastTach < predchoziTach) return;
const rozdilKm = lastTach - predchoziTach;
const spaleno = (rozdilKm * spotreba) / 100;
const zustatek = puvodniStav - spaleno;
const zaokrouhleno = Math.round(zustatek * 2) / 2;
localStorage.setItem("stav_v_nadrzi_l", zaokrouhleno);
localStorage.setItem("predchoziTach", lastTach);
aktualizujStavPalivaVHlavicce();
}
const smena = localStorage.getItem("smena") || "P";
const datum = localStorage.getItem("datum") || new Date().toLocaleDateString("cs-CZ");
const jmeno = localStorage.getItem("ridic") || "Neznámý řidič";
const modal = document.getElementById("modal");
const modalInput = document.getElementById("modal-input");
const modalInputMode = document.getElementById("modal-input-mode");
const btnNumericMode = document.getElementById("btn-numeric-mode");
const btnMicMode = document.getElementById("btn-mic-mode");
const modalTitle = document.getElementById("modal-title");
const modalOk = document.getElementById("modal-ok");
const modalCancel = document.getElementById("modal-cancel");
const flagSedacka = document.getElementById("flag-sedacka");
const flagVleze = document.getElementById("flag-vleze");
const transportFlags = document.querySelectorAll(".transport-flag");
transportFlags.forEach(flag => {
flag.addEventListener("change", () => {
if (flag.checked) {
transportFlags.forEach(other => {
if (other !== flag) {
other.checked = false;
}
});
}
const nekteryZaskrtnuty =
[...transportFlags].some(f => f.checked);
modalInput.disabled = !nekteryZaskrtnuty;
if (!nekteryZaskrtnuty) {
modalInput.value = "";
}
});
});
function nastavFlagyModalu(zobrazit) {
const box = document.getElementById("modal-flags");
const doprovod = document.getElementById("flag-doprovod");
if (!box) return;
box.style.display = zobrazit ? "block" : "none";
if (doprovod) doprovod.checked = false;
document.querySelectorAll(".transport-flag").forEach(f => {
f.checked = false;
});
modalInput.disabled = zobrazit;
}
function nastavCiselnyVstup(rezim) {
if (!modalInputMode || !btnNumericMode || !btnMicMode) return;
modalInput.removeAttribute("inputmode");
modalInput.removeAttribute("pattern");
modalInput.removeAttribute("autocomplete");
if (rezim === "rc") {
modalInputMode.classList.remove("hidden");
btnMicMode.classList.add("active");
btnNumericMode.classList.remove("active");
return;
}
if (rezim === "numeric") {
modalInputMode.classList.add("hidden");
modalInput.setAttribute("inputmode", "numeric");
modalInput.setAttribute("pattern", "[0-9]*");
modalInput.setAttribute("autocomplete", "off");
return;
}
modalInputMode.classList.add("hidden");
btnMicMode.classList.remove("active");
btnNumericMode.classList.remove("active");
}
if (btnNumericMode && btnMicMode) {
btnMicMode.onclick = () => {
modalInput.blur();
setTimeout(() => {
modalInput.removeAttribute("inputmode");
modalInput.removeAttribute("pattern");
modalInput.removeAttribute("autocomplete");
btnMicMode.classList.add("active");
btnNumericMode.classList.remove("active");
modalInput.focus();
}, 100);
};
btnNumericMode.onclick = () => {
modalInput.blur();
setTimeout(() => {
modalInput.setAttribute("inputmode", "numeric");
modalInput.setAttribute("pattern", "[0-9]*");
modalInput.setAttribute("autocomplete", "off");
btnNumericMode.classList.add("active");
btnMicMode.classList.remove("active");
modalInput.focus();
}, 100);
};
}
function showModal(title, placeholder = "", callback, zobrazitFlagy = false, rezimVstupu = "text") {
modalTitle.textContent = title;
modalInput.value = placeholder;
nastavCiselnyVstup(rezimVstupu);
nastavFlagyModalu(zobrazitFlagy);
modal.classList.remove("hidden");
modalInput.focus();
currentCallback = callback;
}
function closeModal() {
modal.classList.add("hidden");
modalInput.value = "";
currentCallback = null;
}
function ziskejFlagyPoznamky() {
const flagy = [];
if (document.getElementById("flag-dojde")?.checked) {
flagy.push("DOJDE");
}
if (document.getElementById("flag-spomoci")?.checked) {
flagy.push("S POMOCÍ");
}
if (document.getElementById("flag-sedacka")?.checked) {
flagy.push("SEDAČKA");
}
if (document.getElementById("flag-vleze")?.checked) {
flagy.push("V LEŽE");
}
if (document.getElementById("flag-doprovod")?.checked) {
flagy.push("DOPROVOD");
}
return flagy.join(" | ");
}
modalOk.onclick = () => {
const value = modalInput.value.trim();
const cb = currentCallback;
closeModal();
if (cb) setTimeout(() => cb(value), 0);
};
modalCancel.onclick = closeModal;
function zpracujKodovouPoznamku(poznamka) {
const cista = String(poznamka || "").replace(/\D/g, "");
if (cista.length < 12 || cista.length > 13) {
alert(
`Rodné číslo nebylo rozpoznáno.\n\n` +
`Zadáno: ${poznamka}\n` +
`Rozpoznané číslice: ${cista}\n` +
`Počet číslic: ${cista.length}\n\n` +
`Zadejte rodné číslo znovu.`
);
return null;
}
const rc = cista.slice(0, -3);
const pojistovna = cista.slice(-3);
if (rc.length !== 9 && rc.length !== 10) {
alert(
`Rodné číslo má špatnou délku.\n\n` +
`RČ: ${rc}\n` +
`Pojišťovna: ${pojistovna}`
);
return null;
}
return {
personal_id: rc,
pojistovna
};
}
function zobrazZaznamy() {
const vypisy = document.getElementById("vypisy");
if (!vypisy || typeof getVsechnyZaznamy !== 'function') return;
vypisy.innerHTML = "";
getVsechnyZaznamy().then(data => {
const nevylozene = data.filter(z => !z.cas_vylozeni).sort((a, b) => a.id - b.id);
nevylozene.slice(-5).forEach(z => {
const div = document.createElement("div");
div.className = "zaznam";
div.dataset.id = z.id;
div.textContent = `${z.cas_nalozeni || "-"} | ${z.mesto_nalozeni} | ${z.poznamka}`;
if (z.typ === "kodovy") {
div.textContent += z.personal_id
? ` | RČ: ${z.personal_id} / ${z.pojistovna}`
: ` | ⚠️ RČ CHYBÍ`;
}
div.onclick = () => div.classList.toggle("selected");
vypisy.appendChild(div);
});
});
}
function ziskejOznaceneZaznamy(callback) {
return getVsechnyZaznamy().then(vsechny => {
const oznaceneDivy = document.querySelectorAll(".zaznam.selected");
const ids = [...oznaceneDivy].map(div => parseInt(div.dataset.id));
return vsechny.filter(z => ids.includes(z.id));
});
}
function aktualizujTachometrVHlavicce() {
const tach = localStorage.getItem("lastTach");
const el = document.getElementById("tach-info");
if (el) {
el.textContent = tach ? `Tachometr: ${tach} km` : `Tachometr: —`;
}
}
function prevedCas(vstup) {
const cista = String(vstup || "").replace(/\D/g, "");
if (!cista) return null;
let hodiny;
let minuty;
if (cista.length <= 2) {
hodiny = parseInt(cista, 10);
minuty = 0;
} else if (cista.length === 3) {
hodiny = parseInt(cista.slice(0, 1), 10);
minuty = parseInt(cista.slice(1), 10);
} else if (cista.length === 4) {
hodiny = parseInt(cista.slice(0, 2), 10);
minuty = parseInt(cista.slice(2), 10);
} else {
return null;
}
if (
isNaN(hodiny) ||
isNaN(minuty) ||
hodiny < 0 ||
hodiny > 23 ||
minuty < 0 ||
minuty > 59
) {
return null;
}
return String(hodiny).padStart(2, "0") + ":" + String(minuty).padStart(2, "0");
}
function ziskejCas(callback) {
const now = new Date();
const hhmm = now.toTimeString().slice(0, 5);
showModal("Zadejte čas", hhmm, vstup => {
const cas = prevedCas(vstup);
if (!cas) {
alert(
"Neplatný čas.\n\n" +
"Příklady:\n" +
"709 = 07:09\n" +
"945 = 09:45\n" +
"1322 = 13:22\n" +
"7 = 07:00"
);
ziskejCas(callback);
return;
}
callback(cas);
}, false, "numeric");
}
function ziskejMesto(callback) {
if (!navigator.onLine || !navigator.geolocation) {
showModal("Zadejte město", "", callback);
return;
}
navigator.geolocation.getCurrentPosition(
pos => {
const { latitude, longitude } = pos.coords;
if (!navigator.onLine) {
showModal("Zadejte město", "", callback);
return;
}
fetch(`https://nominatim.openstreetmap.org/reverse?format=json&lat=${latitude}&lon=${longitude}&accept-language=cs`)
.then(res => res.json())
.then(data => {
const adresa = data.address || {};
const mesto =
adresa.city ||
adresa.town ||
adresa.village ||
adresa.municipality ||
"";
showModal("Potvrďte nebo upravte město", mesto, callback);
})
.catch(() => {
showModal("Zadejte město", "", callback);
});
},
() => {
showModal("Zadejte město", "", callback);
},
{
enableHighAccuracy: false,
timeout: 2500,
maximumAge: 300000
}
);
}
function ziskejPoznamku(callback) {
showModal("Zadejte poznámku", "", callback);
}
function vytvorZaznam(zaznam) {
if (typeof addZaznam === "function") {
return addZaznam(zaznam);
}
alert("Lokální databáze není připravená. Zkus znovu načíst aplikaci.");
return Promise.reject(new Error("addZaznam není dostupná"));
}
function procesPrazdny() {
ziskejPoznamku(poznamka => {
ziskejMesto(mesto => {
ziskejCas(cas => {
vytvorZaznam({
id: Date.now(),
typ: "prazdny",
kod: null,
cas_nalozeni: cas,
mesto_nalozeni: mesto,
poznamka,
cas_vylozeni: null,
mesto_vylozeni: null,
tachometr: null,
smena,
datum,
ridic: jmeno,
vozidlo: localStorage.getItem("vozidlo")
})
.then(() => {
zobrazZaznamy();
})
.catch(err => {
console.error("CHYBA PRI UKLADANI:", err);
alert(
"Jízdu se nepodařilo uložit.\n\n" +
(err?.message || err)
);
});
});
});
});
}
function procesKodovy(kod) {
getVsechnyZaznamy().then(vsechny => {
const beziPrazdny = vsechny.some(z =>
z.typ === "prazdny" && !z.cas_vylozeni
);
if (beziPrazdny) {
alert("Nejdřív vylož prázdnou jízdu. Kódový převoz nejde spustit, dokud běží prázdný.");
return;
}
spustKodovyPrevoz(kod);
});
}
function spustKodovyPrevoz(kod) {
const zaznamy = [];
function zadatRodneCislo(index) {
showModal(`Zadejte rodné číslo ${index + 1} z ${kod}`, "", val => {
const baseTime = Date.now();
// CHYBĚJÍCÍ RČ
if (!val.trim() || val.trim() === "?") {
const zaznam = {
id: baseTime + index,
typ: "kodovy",
kod,
cas_nalozeni: null,
mesto_nalozeni: null,
poznamka: ["⚠️ RČ doplnit později", ziskejFlagyPoznamky()]
.filter(Boolean)
.join(" | "),
cas_vylozeni: null,
mesto_vylozeni: null,
tachometr: null,
smena,
datum,
ridic: jmeno,
vozidlo: localStorage.getItem("vozidlo"),
personal_id: null,
pojistovna: null,
rc_doplneno: false
};
zaznamy.push(zaznam);
if (index + 1 < kod) {
zadatRodneCislo(index + 1);
} else {
ziskejMesto(mesto => {
ziskejCas(cas => {
zaznamy.forEach(z => {
z.cas_nalozeni = cas;
z.mesto_nalozeni = mesto;
});
Promise.all(
zaznamy.map(z => vytvorZaznam(z))
).then(zobrazZaznamy);
});
});
}
return;
}
// NORMÁLNÍ RČ
const vysledek = zpracujKodovouPoznamku(val);
if (!vysledek) {
zadatRodneCislo(index);
return;
}
const zaznam = {
id: baseTime + index,
typ: "kodovy",
kod,
cas_nalozeni: null,
mesto_nalozeni: null,
poznamka: ziskejFlagyPoznamky(),
cas_vylozeni: null,
mesto_vylozeni: null,
tachometr: null,
smena,
datum,
ridic: jmeno,
vozidlo: localStorage.getItem("vozidlo"),
personal_id: vysledek.personal_id,
pojistovna: vysledek.pojistovna
};
zaznamy.push(zaznam);
if (index + 1 < kod) {
zadatRodneCislo(index + 1);
} else {
ziskejMesto(mesto => {
ziskejCas(cas => {
zaznamy.forEach(z => {
z.cas_nalozeni = cas;
z.mesto_nalozeni = mesto;
});
Promise.all(
zaznamy.map(z => vytvorZaznam(z))
).then(zobrazZaznamy);
});
});
}
}, true, "rc");
}
zadatRodneCislo(0);
}
function procesVylozeni() {
const vybrane = document.querySelectorAll(".zaznam.selected");
if (!vybrane.length) {
alert("Nejprve vyber záznam.");
return;
}
const ids = [...vybrane].map(div => parseInt(div.dataset.id));
getVsechnyZaznamy().then(vsechny => {
const nevylozene = vsechny.filter(z => !z.cas_vylozeni);
const zbydePoVylozeni = nevylozene.filter(z => !ids.includes(z.id));
const jePosledni = zbydePoVylozeni.length === 0;
ziskejMesto(mesto => {
ziskejCas(cas => {
const updateZaznam = (id, tach = null, ujetoKm = null) => {
const update = {
cas_vylozeni: cas,
mesto_vylozeni: mesto
};
if (tach !== null) update.tachometr = tach;
if (ujetoKm !== null) update.ujeto_km = ujetoKm;
return window.updateZaznam(id, update);
};
const vyloz = (tach, ujetoKm = null) => {
Promise.all(ids.map(id =>
updateZaznam(
id,
tach && id === ids[ids.length - 1] ? tach : null,
ujetoKm && id === ids[ids.length - 1] ? ujetoKm : null
)
)).then(zobrazZaznamy);
};
if (jePosledni) {
const posledniTach = localStorage.getItem("lastTach") || "";
if (jePosledni) {
function zadatTachometr() {
const posledniTach = localStorage.getItem("lastTach") || "";
showModal("Zadejte stav tachometru", posledniTach, tach => {
const tachTrim = tach.trim();
const pouzeCisla = tachTrim.replace(/\D/g, "");
if (pouzeCisla.length !== 6) {
alert(
"Tachometr musí obsahovat přesně 6 číslic.\n\n" +
`Zadáno: ${tachTrim}`
);
zadatTachometr();
return;
}
let ujetoKm = null;
const predchoziTach =
parseInt(localStorage.getItem("lastTach")) || 0;
const novyTach = parseInt(pouzeCisla);
if (
!isNaN(novyTach) &&
predchoziTach &&
novyTach >= predchoziTach
) {
ujetoKm = novyTach - predchoziTach;
}
localStorage.setItem("lastTach", pouzeCisla);
aktualizujTachometrVHlavicce();
prepocitejStavPaliva();
vyloz(pouzeCisla, ujetoKm);
}, false, "numeric");
}
zadatTachometr();
} else {
vyloz(null);
}
} else {
vyloz(null);
}
});
});
});
}
function procesTankovani() {
const modal = document.getElementById("tankovani-modal");
const tachInput = document.getElementById("tank-tachometr");
tachInput.value = localStorage.getItem("lastTach") || "";
modal.classList.remove("hidden");
}
document.getElementById("btn-prazdny").onclick = procesPrazdny;
document.querySelectorAll(".kod-button").forEach(btn => {
btn.onclick = () => {
const kod = parseInt(btn.dataset.count);
procesKodovy(kod);
};
});
document.getElementById("btn-vylozit").onclick = procesVylozeni;
document.getElementById("btn-tankovani").onclick = procesTankovani;
function zavriTankovaniModal() {
document.getElementById("tankovani-modal").classList.add("hidden");
document.getElementById("tank-litry").value = "";
document.getElementById("tank-tachometr").value = "";
document.getElementById("tank-do-plna").checked = true;
}
document.getElementById("tank-zrusit").onclick = zavriTankovaniModal;
document.getElementById("tank-ulozit").onclick = () => {
const litry = parseFloat(
document.getElementById("tank-litry").value.replace(",", ".")
);
const tach = parseInt(
document.getElementById("tank-tachometr").value
);
const doPlna =
document.getElementById("tank-do-plna").checked;
if (isNaN(litry) || litry <= 0) {
alert("Zadej platné množství litrů.");
return;
}
if (isNaN(tach)) {
alert("Zadej platný tachometr.");
return;
}
const kapacita = parseFloat(localStorage.getItem("nadrz_l")) || 85;
const spotreba = parseFloat(localStorage.getItem("spotreba")) || 0;
const staryStav = parseFloat(localStorage.getItem("stav_v_nadrzi_l")) || 0;
const posledniTach =
parseInt(localStorage.getItem("predchoziTach")) ||
parseInt(localStorage.getItem("lastTach")) ||
tach;
let stavPredTankovanim = staryStav;
if (spotreba && tach >= posledniTach) {
const kmOdPoslednihoBodu = tach - posledniTach;
const spaleno = (kmOdPoslednihoBodu * spotreba) / 100;
stavPredTankovanim = staryStav - spaleno;
}
let novyStav;
if (doPlna) {
novyStav = kapacita;
} else {
novyStav = stavPredTankovanim + litry;
if (novyStav > kapacita) novyStav = kapacita;
}
novyStav = Math.round(novyStav * 2) / 2;
localStorage.setItem("stav_v_nadrzi_l", novyStav);
localStorage.setItem("predchoziTach", tach);
localStorage.setItem("tankTach", tach);
const puvodniLitry =
parseFloat(localStorage.getItem("natankovano_l")) || 0;
localStorage.setItem(
"natankovano_l",
puvodniLitry + litry
);
aktualizujStavPalivaVHlavicce();
zavriTankovaniModal();
alert(
`Tankování uloženo.\n\n` +
`Nový stav nádrže: ${novyStav} l`
);
};
zobrazZaznamy();
aktualizujTachometrVHlavicce();
prepocitejStavPaliva();
});
← Zpět na seznam