From 6395df1992e424f9f9f547cc915d0e6bfa5918a4 Mon Sep 17 00:00:00 2001 From: David Fencl Date: Sat, 6 Jun 2026 17:24:30 +0200 Subject: [PATCH] feat: implement multilingual SEO support and enhance map UI with data synchronization updates --- compare_data.ts | 63 +++++++ index.html | 7 +- package-lock.json | 49 ++++- package.json | 1 + public/data/MARI.json | 243 +++++++++++++++++++++++- public/data/MZHR.json | 250 ++++++++++++++++++++++++ public/data/VLHN.json | 250 ++++++++++++++++++++++++ public/data/VLKO.json | 250 ++++++++++++++++++++++++ public/data/VLL1.json | 250 ++++++++++++++++++++++++ public/data/VLL2.json | 254 ++++++++++++++++++++++++- public/data/VLOR.json | 250 ++++++++++++++++++++++++ public/data/VLSL.json | 250 ++++++++++++++++++++++++ public/data/VLST.json | 250 ++++++++++++++++++++++++ public/data/lakes_index.json | 244 ++++++++++++------------ public/robots.txt | 4 + scripts/scrapeLakes.ts | 89 +++------ src/App.tsx | 17 +- src/components/FavoritesOverview.tsx | 17 +- src/components/KpiCards.tsx | 4 +- src/components/LakeDetail.tsx | 82 +++++++- src/components/LakeMap.tsx | 22 ++- src/components/LakesOverview.tsx | 46 ++--- src/components/SettingsModal.tsx | 45 ++++- src/components/Sidebar.tsx | 43 +++-- src/components/WeatherWidget.tsx | 13 +- src/components/WindChart.tsx | 273 +++++++++++++++++++++++++++ src/index.css | 9 +- src/main.tsx | 13 +- src/translations.ts | 26 +++ src/utils/navigationLimits.ts | 2 +- 30 files changed, 3036 insertions(+), 280 deletions(-) create mode 100644 compare_data.ts create mode 100644 public/robots.txt create mode 100644 src/components/WindChart.tsx diff --git a/compare_data.ts b/compare_data.ts new file mode 100644 index 0000000..a584518 --- /dev/null +++ b/compare_data.ts @@ -0,0 +1,63 @@ +import axios from 'axios'; +import * as cheerio from 'cheerio'; +import fs from 'fs'; +import https from 'https'; + +async function compare() { + const URL = 'https://www.pvl.cz/portal/nadrze/cz/pc/Mereni.aspx?oid=1&id=VLL1'; + const agent = new https.Agent({ rejectUnauthorized: false }); + const response = await axios.get(URL, { httpsAgent: agent }); + const $ = cheerio.load(response.data); + + let tblFound = null; + $('table').each((i, tbl) => { + if ($(tbl).text().includes('Datum') && $(tbl).text().includes('Odtok')) { + tblFound = $(tbl); + } + }); + + const pvlRows = []; + if (tblFound) { + tblFound.find('tr').each((i, row) => { + if (i === 0) return; + const cols = $(row).find('td'); + if (cols.length >= 3) { + const rawDate = $(cols[0]).text().trim(); + const levelStr = $(cols[1]).text().trim().replace(',', '.'); + let flowStr = $(cols[2]).text().trim().replace(',', '.'); + if (flowStr === '' && cols.length >= 4) { + flowStr = $(cols[3]).text().trim().replace(',', '.'); + } + pvlRows.push({ + date: rawDate, + level: parseFloat(levelStr), + flow: parseFloat(flowStr) + }); + } + }); + } + + const localData = JSON.parse(fs.readFileSync('public/data/VLL1.json', 'utf-8')); + // Sort local data descending (newest first) to match PVL which is newest first + const sortedLocal = localData.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()); + + console.log('--- POROVNÁNÍ DAT: LIPNO 1 ---'); + console.log(String('PVL.CZ').padEnd(40) + ' | ' + 'NAŠE LOKÁLNÍ DATABÁZE'); + console.log('-'.repeat(85)); + + for (let i = 0; i < Math.min(10, pvlRows.length); i++) { + const p = pvlRows[i]; + const l = sortedLocal[i]; + + // Format our local UTC timestamp back to something readable + const d = new Date(l.timestamp); + const localDateStr = `${d.getDate().toString().padStart(2, '0')}.${(d.getMonth()+1).toString().padStart(2, '0')}.${d.getFullYear()} ${d.getHours().toString().padStart(2, '0')}:${d.getMinutes().toString().padStart(2, '0')}`; + + const pvlStr = `[${p.date}] H: ${p.level} m, O: ${p.flow} m3/s`.padEnd(40); + const locStr = `[${localDateStr}] H: ${l.level} m, O: ${l.flow} m3/s, P: ${l.inflow} m3/s`; + + console.log(`${pvlStr} | ${locStr}`); + } +} + +compare().catch(console.error); diff --git a/index.html b/index.html index 2fae9ad..f4d2855 100644 --- a/index.html +++ b/index.html @@ -4,7 +4,12 @@ - Davis Fencl + Hladinátor - Aktuální stav přehrad a nádrží + + + + +
diff --git a/package-lock.json b/package-lock.json index b51e268..94f95a6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "leaflet": "^1.9.4", "react": "^19.2.0", "react-dom": "^19.2.0", + "react-helmet-async": "^3.0.0", "react-icons": "^5.5.0", "react-leaflet": "^5.0.0", "react-router-dom": "^7.9.6", @@ -3936,6 +3937,15 @@ "node": ">=12" } }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -4016,7 +4026,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true, "license": "MIT" }, "node_modules/js-yaml": { @@ -4219,6 +4228,18 @@ "dev": true, "license": "MIT" }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -4688,6 +4709,26 @@ "react": "^19.2.0" } }, + "node_modules/react-fast-compare": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", + "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==", + "license": "MIT" + }, + "node_modules/react-helmet-async": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-3.0.0.tgz", + "integrity": "sha512-nA3IEZfXiclgrz4KLxAhqJqIfFDuvzQwlKwpdmzZIuC1KNSghDEIXmyU0TKtbM+NafnkICcwx8CECFrZ/sL/1w==", + "license": "Apache-2.0", + "dependencies": { + "invariant": "^2.2.4", + "react-fast-compare": "^3.2.2", + "shallowequal": "^1.1.0" + }, + "peerDependencies": { + "react": "^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/react-icons": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz", @@ -4957,6 +4998,12 @@ "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", "license": "MIT" }, + "node_modules/shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==", + "license": "MIT" + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", diff --git a/package.json b/package.json index 32c5c90..bfaf6ba 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "leaflet": "^1.9.4", "react": "^19.2.0", "react-dom": "^19.2.0", + "react-helmet-async": "^3.0.0", "react-icons": "^5.5.0", "react-leaflet": "^5.0.0", "react-router-dom": "^7.9.6", diff --git a/public/data/MARI.json b/public/data/MARI.json index 20c9286..58d1d96 100644 --- a/public/data/MARI.json +++ b/public/data/MARI.json @@ -226,8 +226,249 @@ { "timestamp": "2026-06-06T10:30:00.000Z", "level": 467.74, - "flow": 0, + "flow": 0.7, "inflow": 0, "volume": 0 + }, + { + "timestamp": "2026-06-06T10:40:00.000Z", + "level": 467.74, + "flow": 0.7, + "inflow": 0, + "volume": 0 + }, + { + "timestamp": "2026-06-06T10:50:00.000Z", + "level": 467.74, + "flow": 0, + "inflow": 2.24, + "volume": 26.53, + "temperature": 20.5, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:00:00.000Z", + "level": 467.74, + "flow": 0.7, + "inflow": 0, + "volume": 0, + "temperature": 20.5, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:10:00.000Z", + "level": 467.74, + "flow": 0.7, + "inflow": 0, + "volume": 0, + "temperature": 20.5, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:20:00.000Z", + "level": 467.74, + "flow": 0.7, + "inflow": 0, + "volume": 0, + "temperature": 20.5, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:30:00.000Z", + "level": 467.74, + "flow": 0.7, + "inflow": 0, + "volume": 0, + "temperature": 20.5, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:40:00.000Z", + "level": 467.75, + "flow": 0.7, + "inflow": 0, + "volume": 0, + "temperature": 20.5, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:50:00.000Z", + "level": 467.74, + "flow": 0, + "inflow": 2.24, + "volume": 26.54, + "temperature": 21.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:00:00.000Z", + "level": 467.75, + "flow": 0.7, + "inflow": 0, + "volume": 0, + "temperature": 21.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:10:00.000Z", + "level": 467.75, + "flow": 0.7, + "inflow": 0, + "volume": 0, + "temperature": 21.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:20:00.000Z", + "level": 467.75, + "flow": 0.7, + "inflow": 0, + "volume": 0, + "temperature": 21.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:30:00.000Z", + "level": 467.75, + "flow": 0.7, + "inflow": 0, + "volume": 0, + "temperature": 21.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:40:00.000Z", + "level": 467.75, + "flow": 0.7, + "inflow": 0, + "volume": 0, + "temperature": 21.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:50:00.000Z", + "level": 467.75, + "flow": 0, + "inflow": 2.24, + "volume": 26.54, + "temperature": 21.8, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:00:00.000Z", + "level": 467.75, + "flow": 0.7, + "inflow": 0, + "volume": 0, + "temperature": 21.8, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:10:00.000Z", + "level": 467.75, + "flow": 0.7, + "inflow": 0, + "volume": 0, + "temperature": 21.8, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:20:00.000Z", + "level": 467.75, + "flow": 0.7, + "inflow": 0, + "volume": 0, + "temperature": 21.8, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:30:00.000Z", + "level": 467.75, + "flow": 0.7, + "inflow": 0, + "volume": 0, + "temperature": 21.8, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:40:00.000Z", + "level": 467.75, + "flow": 0, + "inflow": 2.24, + "volume": 26.54, + "temperature": 22.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:00:00.000Z", + "level": 467.75, + "flow": 0.7, + "inflow": 0, + "volume": 0, + "temperature": 22.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:10:00.000Z", + "level": 467.75, + "flow": 0.7, + "inflow": 0, + "volume": 0, + "temperature": 22.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:20:00.000Z", + "level": 467.75, + "flow": 0.7, + "inflow": 0, + "volume": 0, + "temperature": 22.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:30:00.000Z", + "level": 467.75, + "flow": 0.7, + "inflow": 0, + "volume": 0, + "temperature": 22.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:40:00.000Z", + "level": 467.75, + "flow": 0.7, + "inflow": 0, + "volume": 0, + "temperature": 22.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:50:00.000Z", + "level": 467.75, + "flow": 0, + "inflow": 2.24, + "volume": 26.54, + "temperature": 22.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T15:00:00.000Z", + "level": 467.75, + "flow": 0.7, + "inflow": 0, + "volume": 0, + "temperature": 22.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T15:10:00.000Z", + "level": 467.75, + "flow": 0, + "inflow": 2.24, + "volume": 26.54, + "temperature": 22, + "precipitation": 0 } ] \ No newline at end of file diff --git a/public/data/MZHR.json b/public/data/MZHR.json index 6783f62..4673920 100644 --- a/public/data/MZHR.json +++ b/public/data/MZHR.json @@ -229,5 +229,255 @@ "flow": 2.52, "inflow": 0, "volume": 0 + }, + { + "timestamp": "2026-06-06T10:40:00.000Z", + "level": 352.84, + "flow": 2.52, + "inflow": 0, + "volume": 0 + }, + { + "timestamp": "2026-06-06T10:50:00.000Z", + "level": 352.84, + "flow": 0, + "inflow": 1.47, + "volume": 32.3, + "temperature": 20.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:00:00.000Z", + "level": 352.84, + "flow": 2.52, + "inflow": 0, + "volume": 0, + "temperature": 20.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:10:00.000Z", + "level": 352.84, + "flow": 2.52, + "inflow": 0, + "volume": 0, + "temperature": 20.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:20:00.000Z", + "level": 352.84, + "flow": 2.52, + "inflow": 0, + "volume": 0, + "temperature": 20.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:30:00.000Z", + "level": 352.84, + "flow": 2.52, + "inflow": 0, + "volume": 0, + "temperature": 20.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:40:00.000Z", + "level": 352.84, + "flow": 2.52, + "inflow": 0, + "volume": 0, + "temperature": 20.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:50:00.000Z", + "level": 352.84, + "flow": 2.52, + "inflow": 1.47, + "volume": 32.31, + "temperature": 21.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:00:00.000Z", + "level": 352.83, + "flow": 2.52, + "inflow": 0, + "volume": 0, + "temperature": 21.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:10:00.000Z", + "level": 352.84, + "flow": 2.52, + "inflow": 0, + "volume": 0, + "temperature": 21.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:20:00.000Z", + "level": 352.84, + "flow": 2.53, + "inflow": 0, + "volume": 0, + "temperature": 21.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:30:00.000Z", + "level": 352.84, + "flow": 2.52, + "inflow": 0, + "volume": 0, + "temperature": 21.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:40:00.000Z", + "level": 352.84, + "flow": 2.52, + "inflow": 0, + "volume": 0, + "temperature": 21.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:50:00.000Z", + "level": 352.84, + "flow": 0, + "inflow": 1.47, + "volume": 32.28, + "temperature": 22.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:00:00.000Z", + "level": 352.84, + "flow": 2.52, + "inflow": 0, + "volume": 0, + "temperature": 22.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:10:00.000Z", + "level": 352.84, + "flow": 2.53, + "inflow": 0, + "volume": 0, + "temperature": 22.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:20:00.000Z", + "level": 352.84, + "flow": 2.53, + "inflow": 0, + "volume": 0, + "temperature": 22.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:30:00.000Z", + "level": 352.84, + "flow": 2.53, + "inflow": 0, + "volume": 0, + "temperature": 22.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:40:00.000Z", + "level": 352.83, + "flow": 2.52, + "inflow": 0, + "volume": 0, + "temperature": 22.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:50:00.000Z", + "level": 352.84, + "flow": 0, + "inflow": 1.47, + "volume": 32.3, + "temperature": 22.7, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:00:00.000Z", + "level": 352.84, + "flow": 2.52, + "inflow": 0, + "volume": 0, + "temperature": 22.7, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:10:00.000Z", + "level": 352.84, + "flow": 2.52, + "inflow": 0, + "volume": 0, + "temperature": 22.7, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:20:00.000Z", + "level": 352.84, + "flow": 2.52, + "inflow": 0, + "volume": 0, + "temperature": 22.7, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:30:00.000Z", + "level": 352.83, + "flow": 2.52, + "inflow": 0, + "volume": 0, + "temperature": 22.7, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:40:00.000Z", + "level": 352.84, + "flow": 2.52, + "inflow": 0, + "volume": 0, + "temperature": 22.7, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:50:00.000Z", + "level": 352.84, + "flow": 2.52, + "inflow": 1.47, + "volume": 32.29, + "temperature": 22.9, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T15:00:00.000Z", + "level": 352.84, + "flow": 2.52, + "inflow": 0, + "volume": 0, + "temperature": 22.9, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T15:10:00.000Z", + "level": 352.83, + "flow": 2.52, + "inflow": 1.47, + "volume": 32.31, + "temperature": 22.7, + "precipitation": 0 } ] \ No newline at end of file diff --git a/public/data/VLHN.json b/public/data/VLHN.json index 5d0b0dd..b197b0b 100644 --- a/public/data/VLHN.json +++ b/public/data/VLHN.json @@ -229,5 +229,255 @@ "flow": 2.5, "inflow": 0, "volume": 0 + }, + { + "timestamp": "2026-06-06T10:40:00.000Z", + "level": 369.84, + "flow": 2.5, + "inflow": 0, + "volume": 0 + }, + { + "timestamp": "2026-06-06T10:50:00.000Z", + "level": 369.84, + "flow": 2.5, + "inflow": 0, + "volume": 20.4, + "temperature": 20.8, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:00:00.000Z", + "level": 369.84, + "flow": 2.5, + "inflow": 0, + "volume": 0, + "temperature": 20.8, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:10:00.000Z", + "level": 369.84, + "flow": 2.5, + "inflow": 0, + "volume": 0, + "temperature": 20.8, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:20:00.000Z", + "level": 369.84, + "flow": 2.5, + "inflow": 0, + "volume": 0, + "temperature": 20.8, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:30:00.000Z", + "level": 369.84, + "flow": 2.5, + "inflow": 0, + "volume": 0, + "temperature": 20.8, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:40:00.000Z", + "level": 369.84, + "flow": 2.5, + "inflow": 0, + "volume": 0, + "temperature": 20.8, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:50:00.000Z", + "level": 369.84, + "flow": 2.5, + "inflow": 0, + "volume": 20.4, + "temperature": 21.9, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:00:00.000Z", + "level": 369.84, + "flow": 2.5, + "inflow": 0, + "volume": 0, + "temperature": 21.9, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:10:00.000Z", + "level": 369.84, + "flow": 8.79, + "inflow": 0, + "volume": 0, + "temperature": 21.9, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:20:00.000Z", + "level": 369.84, + "flow": 14.24, + "inflow": 0, + "volume": 0, + "temperature": 21.9, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:30:00.000Z", + "level": 369.84, + "flow": 14.24, + "inflow": 0, + "volume": 0, + "temperature": 21.9, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:40:00.000Z", + "level": 369.84, + "flow": 14.24, + "inflow": 0, + "volume": 0, + "temperature": 21.9, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:50:00.000Z", + "level": 369.84, + "flow": 14.24, + "inflow": 0, + "volume": 20.4, + "temperature": 22.6, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:00:00.000Z", + "level": 369.84, + "flow": 14.24, + "inflow": 0, + "volume": 0, + "temperature": 22.6, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:10:00.000Z", + "level": 369.84, + "flow": 14.24, + "inflow": 0, + "volume": 0, + "temperature": 22.6, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:20:00.000Z", + "level": 369.84, + "flow": 14.24, + "inflow": 0, + "volume": 0, + "temperature": 22.6, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:30:00.000Z", + "level": 369.84, + "flow": 14.24, + "inflow": 0, + "volume": 0, + "temperature": 22.6, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:40:00.000Z", + "level": 369.84, + "flow": 14.24, + "inflow": 0, + "volume": 0, + "temperature": 22.6, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:50:00.000Z", + "level": 369.83, + "flow": 14.22, + "inflow": 0, + "volume": 20.4, + "temperature": 22.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:00:00.000Z", + "level": 369.83, + "flow": 14.22, + "inflow": 0, + "volume": 0, + "temperature": 22.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:10:00.000Z", + "level": 369.83, + "flow": 14.22, + "inflow": 0, + "volume": 0, + "temperature": 22.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:20:00.000Z", + "level": 369.83, + "flow": 14.22, + "inflow": 0, + "volume": 0, + "temperature": 22.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:30:00.000Z", + "level": 369.83, + "flow": 14.22, + "inflow": 0, + "volume": 0, + "temperature": 22.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:40:00.000Z", + "level": 369.83, + "flow": 14.22, + "inflow": 0, + "volume": 0, + "temperature": 22.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:50:00.000Z", + "level": 369.83, + "flow": 14.22, + "inflow": 0, + "volume": 20.37, + "temperature": 22.5, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T15:00:00.000Z", + "level": 369.83, + "flow": 14.23, + "inflow": 0, + "volume": 0, + "temperature": 22.5, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T15:10:00.000Z", + "level": 369.83, + "flow": 14.23, + "inflow": 0, + "volume": 20.37, + "temperature": 22.6, + "precipitation": 0 } ] \ No newline at end of file diff --git a/public/data/VLKO.json b/public/data/VLKO.json index 300c6dc..38aa456 100644 --- a/public/data/VLKO.json +++ b/public/data/VLKO.json @@ -229,5 +229,255 @@ "flow": 19.05, "inflow": 0, "volume": 0 + }, + { + "timestamp": "2026-06-06T10:40:00.000Z", + "level": 352.5, + "flow": 19.05, + "inflow": 0, + "volume": 0 + }, + { + "timestamp": "2026-06-06T10:50:00.000Z", + "level": 352.49, + "flow": 19.05, + "inflow": 13.43, + "volume": 2.77, + "temperature": 20.5, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:00:00.000Z", + "level": 352.48, + "flow": 19.05, + "inflow": 0, + "volume": 0, + "temperature": 20.5, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:10:00.000Z", + "level": 352.48, + "flow": 19.05, + "inflow": 0, + "volume": 0, + "temperature": 20.5, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:20:00.000Z", + "level": 352.47, + "flow": 19.05, + "inflow": 0, + "volume": 0, + "temperature": 20.5, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:30:00.000Z", + "level": 352.47, + "flow": 19.05, + "inflow": 0, + "volume": 0, + "temperature": 20.5, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:40:00.000Z", + "level": 352.47, + "flow": 19.05, + "inflow": 0, + "volume": 0, + "temperature": 20.5, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:50:00.000Z", + "level": 352.46, + "flow": 19.05, + "inflow": 13.43, + "volume": 2.76, + "temperature": 21.6, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:00:00.000Z", + "level": 352.46, + "flow": 19.05, + "inflow": 0, + "volume": 0, + "temperature": 21.6, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:10:00.000Z", + "level": 352.45, + "flow": 19.05, + "inflow": 0, + "volume": 0, + "temperature": 21.6, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:20:00.000Z", + "level": 352.45, + "flow": 19.05, + "inflow": 0, + "volume": 0, + "temperature": 21.6, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:30:00.000Z", + "level": 352.44, + "flow": 19.05, + "inflow": 0, + "volume": 0, + "temperature": 21.6, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:40:00.000Z", + "level": 352.44, + "flow": 19.05, + "inflow": 0, + "volume": 0, + "temperature": 21.6, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:50:00.000Z", + "level": 352.44, + "flow": 19.05, + "inflow": 13.43, + "volume": 2.75, + "temperature": 22, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:00:00.000Z", + "level": 352.44, + "flow": 19.05, + "inflow": 0, + "volume": 0, + "temperature": 22, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:10:00.000Z", + "level": 352.44, + "flow": 19.05, + "inflow": 0, + "volume": 0, + "temperature": 22, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:20:00.000Z", + "level": 352.44, + "flow": 19.05, + "inflow": 0, + "volume": 0, + "temperature": 22, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:30:00.000Z", + "level": 352.43, + "flow": 19.05, + "inflow": 0, + "volume": 0, + "temperature": 22, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:40:00.000Z", + "level": 352.43, + "flow": 19.05, + "inflow": 0, + "volume": 0, + "temperature": 22, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:50:00.000Z", + "level": 352.44, + "flow": 19.05, + "inflow": 13.43, + "volume": 2.74, + "temperature": 22.1, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:00:00.000Z", + "level": 352.44, + "flow": 19.05, + "inflow": 0, + "volume": 0, + "temperature": 22.1, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:10:00.000Z", + "level": 352.44, + "flow": 19.05, + "inflow": 0, + "volume": 0, + "temperature": 22.1, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:20:00.000Z", + "level": 352.44, + "flow": 19.05, + "inflow": 0, + "volume": 0, + "temperature": 22.1, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:30:00.000Z", + "level": 352.43, + "flow": 19.05, + "inflow": 0, + "volume": 0, + "temperature": 22.1, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:40:00.000Z", + "level": 352.43, + "flow": 19.05, + "inflow": 0, + "volume": 0, + "temperature": 22.1, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:50:00.000Z", + "level": 352.44, + "flow": 19.05, + "inflow": 13.43, + "volume": 2.74, + "temperature": 21.9, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T15:00:00.000Z", + "level": 352.44, + "flow": 19.05, + "inflow": 0, + "volume": 0, + "temperature": 21.9, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T15:10:00.000Z", + "level": 352.43, + "flow": 19.05, + "inflow": 13.43, + "volume": 2.74, + "temperature": 21.9, + "precipitation": 0 } ] \ No newline at end of file diff --git a/public/data/VLL1.json b/public/data/VLL1.json index 7ac7177..f35ac81 100644 --- a/public/data/VLL1.json +++ b/public/data/VLL1.json @@ -229,5 +229,255 @@ "flow": 1.51, "inflow": 0, "volume": 0 + }, + { + "timestamp": "2026-06-06T10:40:00.000Z", + "level": 723.09, + "flow": 1.51, + "inflow": 0, + "volume": 0 + }, + { + "timestamp": "2026-06-06T10:50:00.000Z", + "level": 723.09, + "flow": 0, + "inflow": 9.25, + "volume": 199.67, + "temperature": 19.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:00:00.000Z", + "level": 723.09, + "flow": 1.51, + "inflow": 0, + "volume": 0, + "temperature": 19.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:10:00.000Z", + "level": 723.09, + "flow": 1.51, + "inflow": 0, + "volume": 0, + "temperature": 19.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:20:00.000Z", + "level": 723.09, + "flow": 1.51, + "inflow": 0, + "volume": 0, + "temperature": 19.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:30:00.000Z", + "level": 723.09, + "flow": 1.51, + "inflow": 0, + "volume": 0, + "temperature": 19.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:40:00.000Z", + "level": 723.09, + "flow": 1.51, + "inflow": 0, + "volume": 0, + "temperature": 19.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:50:00.000Z", + "level": 723.09, + "flow": 1.51, + "inflow": 9.25, + "volume": 199.67, + "temperature": 20, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:00:00.000Z", + "level": 723.09, + "flow": 1.51, + "inflow": 0, + "volume": 0, + "temperature": 20, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:10:00.000Z", + "level": 723.09, + "flow": 1.51, + "inflow": 0, + "volume": 0, + "temperature": 20, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:20:00.000Z", + "level": 723.09, + "flow": 1.51, + "inflow": 0, + "volume": 0, + "temperature": 20, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:30:00.000Z", + "level": 723.09, + "flow": 1.51, + "inflow": 0, + "volume": 0, + "temperature": 20, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:40:00.000Z", + "level": 723.09, + "flow": 1.51, + "inflow": 0, + "volume": 0, + "temperature": 20, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:50:00.000Z", + "level": 723.09, + "flow": 0, + "inflow": 9.25, + "volume": 199.67, + "temperature": 20.5, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:00:00.000Z", + "level": 723.09, + "flow": 1.51, + "inflow": 0, + "volume": 0, + "temperature": 20.5, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:10:00.000Z", + "level": 723.09, + "flow": 1.51, + "inflow": 0, + "volume": 0, + "temperature": 20.5, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:20:00.000Z", + "level": 723.09, + "flow": 1.51, + "inflow": 0, + "volume": 0, + "temperature": 20.5, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:30:00.000Z", + "level": 723.09, + "flow": 1.51, + "inflow": 0, + "volume": 0, + "temperature": 20.5, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:40:00.000Z", + "level": 723.09, + "flow": 1.51, + "inflow": 0, + "volume": 0, + "temperature": 20.5, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:50:00.000Z", + "level": 723.09, + "flow": 1.51, + "inflow": 9.25, + "volume": 199.67, + "temperature": 20.8, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:00:00.000Z", + "level": 723.09, + "flow": 1.51, + "inflow": 0, + "volume": 0, + "temperature": 20.8, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:10:00.000Z", + "level": 723.09, + "flow": 1.51, + "inflow": 0, + "volume": 0, + "temperature": 20.8, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:20:00.000Z", + "level": 723.09, + "flow": 1.51, + "inflow": 0, + "volume": 0, + "temperature": 20.8, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:30:00.000Z", + "level": 723.09, + "flow": 1.51, + "inflow": 0, + "volume": 0, + "temperature": 20.8, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:40:00.000Z", + "level": 723.09, + "flow": 1.51, + "inflow": 0, + "volume": 0, + "temperature": 20.8, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:50:00.000Z", + "level": 723.09, + "flow": 0, + "inflow": 9.25, + "volume": 199.67, + "temperature": 20.8, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T15:00:00.000Z", + "level": 723.09, + "flow": 1.51, + "inflow": 0, + "volume": 0, + "temperature": 20.8, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T15:10:00.000Z", + "level": 723.09, + "flow": 0, + "inflow": 9.25, + "volume": 199.67, + "temperature": 20.7, + "precipitation": 0 } ] \ No newline at end of file diff --git a/public/data/VLL2.json b/public/data/VLL2.json index 22493ad..7be54d7 100644 --- a/public/data/VLL2.json +++ b/public/data/VLL2.json @@ -212,14 +212,14 @@ { "timestamp": "2026-06-06T10:10:00.000Z", "level": 558.94, - "flow": 0, + "flow": 7.18, "inflow": 0, "volume": 0 }, { "timestamp": "2026-06-06T10:20:00.000Z", "level": 558.93, - "flow": 0, + "flow": 7.18, "inflow": 0, "volume": 0 }, @@ -229,5 +229,255 @@ "flow": 0, "inflow": 0, "volume": 0 + }, + { + "timestamp": "2026-06-06T10:40:00.000Z", + "level": 558.9, + "flow": 0, + "inflow": 0, + "volume": 0 + }, + { + "timestamp": "2026-06-06T10:50:00.000Z", + "level": 558.88, + "flow": 0, + "inflow": 5.37, + "volume": 0.45, + "temperature": 20.6, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:00:00.000Z", + "level": 558.87, + "flow": 7.22, + "inflow": 0, + "volume": 0, + "temperature": 20.6, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:10:00.000Z", + "level": 558.86, + "flow": 7.24, + "inflow": 0, + "volume": 0, + "temperature": 20.6, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:20:00.000Z", + "level": 558.84, + "flow": 7.27, + "inflow": 0, + "volume": 0, + "temperature": 20.6, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:30:00.000Z", + "level": 558.82, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 20.6, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:40:00.000Z", + "level": 558.81, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 20.6, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:50:00.000Z", + "level": 558.79, + "flow": 0, + "inflow": 5.37, + "volume": 0.43, + "temperature": 21.3, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:00:00.000Z", + "level": 558.77, + "flow": 7.51, + "inflow": 0, + "volume": 0, + "temperature": 21.3, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:10:00.000Z", + "level": 558.75, + "flow": 7.51, + "inflow": 0, + "volume": 0, + "temperature": 21.3, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:20:00.000Z", + "level": 558.74, + "flow": 7.51, + "inflow": 0, + "volume": 0, + "temperature": 21.3, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:30:00.000Z", + "level": 558.72, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 21.3, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:40:00.000Z", + "level": 558.71, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 21.3, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:50:00.000Z", + "level": 558.68, + "flow": 0, + "inflow": 5.37, + "volume": 0.41, + "temperature": 21.7, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:00:00.000Z", + "level": 558.67, + "flow": 7.53, + "inflow": 0, + "volume": 0, + "temperature": 21.7, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:10:00.000Z", + "level": 558.65, + "flow": 7.51, + "inflow": 0, + "volume": 0, + "temperature": 21.7, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:20:00.000Z", + "level": 558.63, + "flow": 7.51, + "inflow": 0, + "volume": 0, + "temperature": 21.7, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:30:00.000Z", + "level": 558.62, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 21.7, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:40:00.000Z", + "level": 558.6, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 21.7, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:50:00.000Z", + "level": 558.58, + "flow": 0, + "inflow": 5.37, + "volume": 0.39, + "temperature": 21.9, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:00:00.000Z", + "level": 558.56, + "flow": 7.51, + "inflow": 0, + "volume": 0, + "temperature": 21.9, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:10:00.000Z", + "level": 558.54, + "flow": 7.51, + "inflow": 0, + "volume": 0, + "temperature": 21.9, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:20:00.000Z", + "level": 558.52, + "flow": 7.51, + "inflow": 0, + "volume": 0, + "temperature": 21.9, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:30:00.000Z", + "level": 558.5, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 21.9, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:40:00.000Z", + "level": 558.49, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 21.9, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:50:00.000Z", + "level": 558.47, + "flow": 0, + "inflow": 5.37, + "volume": 0.37, + "temperature": 21.8, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T15:00:00.000Z", + "level": 558.44, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 21.8, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T15:10:00.000Z", + "level": 558.43, + "flow": 0, + "inflow": 5.37, + "volume": 0.35, + "temperature": 21.7, + "precipitation": 0 } ] \ No newline at end of file diff --git a/public/data/VLOR.json b/public/data/VLOR.json index 9908cf6..4857002 100644 --- a/public/data/VLOR.json +++ b/public/data/VLOR.json @@ -229,5 +229,255 @@ "flow": 0, "inflow": 0, "volume": 0 + }, + { + "timestamp": "2026-06-06T10:40:00.000Z", + "level": 345.27, + "flow": 0, + "inflow": 0, + "volume": 0 + }, + { + "timestamp": "2026-06-06T10:50:00.000Z", + "level": 345.27, + "flow": 0, + "inflow": 24.39, + "volume": 522.32, + "temperature": 21, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:00:00.000Z", + "level": 345.28, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 21, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:10:00.000Z", + "level": 345.28, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 21, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:20:00.000Z", + "level": 345.28, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 21, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:30:00.000Z", + "level": 345.28, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 21, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:40:00.000Z", + "level": 345.28, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 21, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:50:00.000Z", + "level": 345.28, + "flow": 0, + "inflow": 24.39, + "volume": 522.52, + "temperature": 22, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:00:00.000Z", + "level": 345.28, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 22, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:10:00.000Z", + "level": 345.28, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 22, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:20:00.000Z", + "level": 345.28, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 22, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:30:00.000Z", + "level": 345.28, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 22, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:40:00.000Z", + "level": 345.28, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 22, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:50:00.000Z", + "level": 345.28, + "flow": 0, + "inflow": 24.39, + "volume": 522.52, + "temperature": 22.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:00:00.000Z", + "level": 345.28, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 22.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:10:00.000Z", + "level": 345.28, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 22.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:20:00.000Z", + "level": 345.29, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 22.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:30:00.000Z", + "level": 345.29, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 22.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:40:00.000Z", + "level": 345.29, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 22.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:50:00.000Z", + "level": 345.29, + "flow": 0, + "inflow": 24.39, + "volume": 522.52, + "temperature": 22.1, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:00:00.000Z", + "level": 345.29, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 22.1, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:10:00.000Z", + "level": 345.29, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 22.1, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:20:00.000Z", + "level": 345.29, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 22.1, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:30:00.000Z", + "level": 345.29, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 22.1, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:40:00.000Z", + "level": 345.29, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 22.1, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:50:00.000Z", + "level": 345.29, + "flow": 0, + "inflow": 24.39, + "volume": 522.72, + "temperature": 22.6, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T15:00:00.000Z", + "level": 345.29, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 22.6, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T15:10:00.000Z", + "level": 345.29, + "flow": 0, + "inflow": 24.39, + "volume": 522.72, + "temperature": 22.6, + "precipitation": 0 } ] \ No newline at end of file diff --git a/public/data/VLSL.json b/public/data/VLSL.json index 32a38b1..f80c887 100644 --- a/public/data/VLSL.json +++ b/public/data/VLSL.json @@ -229,5 +229,255 @@ "flow": 0, "inflow": 0, "volume": 0 + }, + { + "timestamp": "2026-06-06T10:40:00.000Z", + "level": 269.88, + "flow": 0, + "inflow": 0, + "volume": 0 + }, + { + "timestamp": "2026-06-06T10:50:00.000Z", + "level": 269.88, + "flow": 0, + "inflow": 81.06, + "volume": 261.23, + "temperature": 21.6, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:00:00.000Z", + "level": 269.87, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 21.6, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:10:00.000Z", + "level": 269.88, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 21.6, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:20:00.000Z", + "level": 269.88, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 21.6, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:30:00.000Z", + "level": 269.88, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 21.6, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:40:00.000Z", + "level": 269.88, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 21.6, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:50:00.000Z", + "level": 269.89, + "flow": 0, + "inflow": 81.06, + "volume": 261.01, + "temperature": 22.7, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:00:00.000Z", + "level": 269.89, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 22.7, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:10:00.000Z", + "level": 269.89, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 22.7, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:20:00.000Z", + "level": 269.88, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 22.7, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:30:00.000Z", + "level": 269.88, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 22.7, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:40:00.000Z", + "level": 269.88, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 22.7, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:50:00.000Z", + "level": 269.88, + "flow": 0, + "inflow": 81.06, + "volume": 261.17, + "temperature": 22.9, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:00:00.000Z", + "level": 269.88, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 22.9, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:10:00.000Z", + "level": 269.88, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 22.9, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:20:00.000Z", + "level": 269.88, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 22.9, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:30:00.000Z", + "level": 269.89, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 22.9, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:40:00.000Z", + "level": 269.89, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 22.9, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:50:00.000Z", + "level": 269.89, + "flow": 0, + "inflow": 81.06, + "volume": 261.08, + "temperature": 23.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:00:00.000Z", + "level": 269.88, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 23.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:10:00.000Z", + "level": 269.88, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 23.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:20:00.000Z", + "level": 269.88, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 23.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:30:00.000Z", + "level": 269.88, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 23.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:40:00.000Z", + "level": 269.88, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 23.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:50:00.000Z", + "level": 269.88, + "flow": 0, + "inflow": 81.06, + "volume": 261.14, + "temperature": 23.5, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T15:00:00.000Z", + "level": 269.88, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 23.5, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T15:10:00.000Z", + "level": 269.88, + "flow": 0, + "inflow": 81.06, + "volume": 261.1, + "temperature": 23.5, + "precipitation": 0 } ] \ No newline at end of file diff --git a/public/data/VLST.json b/public/data/VLST.json index f674309..cbb28e3 100644 --- a/public/data/VLST.json +++ b/public/data/VLST.json @@ -229,5 +229,255 @@ "flow": 0, "inflow": 0, "volume": 0 + }, + { + "timestamp": "2026-06-06T10:40:00.000Z", + "level": 217.04, + "flow": 0, + "inflow": 0, + "volume": 0 + }, + { + "timestamp": "2026-06-06T10:50:00.000Z", + "level": 217.05, + "flow": 0, + "inflow": 48.25, + "volume": 8.23, + "temperature": 21.4, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:00:00.000Z", + "level": 217.01, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 21.4, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:10:00.000Z", + "level": 217.02, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 21.4, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:20:00.000Z", + "level": 217.03, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 21.4, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:30:00.000Z", + "level": 217.01, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 21.4, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:40:00.000Z", + "level": 217.01, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 21.4, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T11:50:00.000Z", + "level": 217.02, + "flow": 0, + "inflow": 48.25, + "volume": 8.19, + "temperature": 22.6, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:00:00.000Z", + "level": 217.01, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 22.6, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:10:00.000Z", + "level": 217, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 22.6, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:20:00.000Z", + "level": 217.01, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 22.6, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:30:00.000Z", + "level": 216.98, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 22.6, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:40:00.000Z", + "level": 216.99, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 22.6, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T12:50:00.000Z", + "level": 217, + "flow": 0, + "inflow": 48.25, + "volume": 8.19, + "temperature": 22.5, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:00:00.000Z", + "level": 216.96, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 22.5, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:10:00.000Z", + "level": 216.98, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 22.5, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:20:00.000Z", + "level": 217, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 22.5, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:30:00.000Z", + "level": 216.97, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 22.5, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:40:00.000Z", + "level": 216.99, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 22.5, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T13:50:00.000Z", + "level": 216.98, + "flow": 0, + "inflow": 48.25, + "volume": 8.14, + "temperature": 23, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:00:00.000Z", + "level": 216.95, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 23, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:10:00.000Z", + "level": 216.98, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 23, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:20:00.000Z", + "level": 216.97, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 23, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:30:00.000Z", + "level": 216.94, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 23, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:40:00.000Z", + "level": 216.98, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 23, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T14:50:00.000Z", + "level": 216.97, + "flow": 0, + "inflow": 48.25, + "volume": 8.14, + "temperature": 23.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T15:00:00.000Z", + "level": 216.95, + "flow": 0, + "inflow": 0, + "volume": 0, + "temperature": 23.2, + "precipitation": 0 + }, + { + "timestamp": "2026-06-06T15:10:00.000Z", + "level": 216.98, + "flow": 0, + "inflow": 48.25, + "volume": 8.14, + "temperature": 23.2, + "precipitation": 0 } ] \ No newline at end of file diff --git a/public/data/lakes_index.json b/public/data/lakes_index.json index ae6a06e..413904f 100644 --- a/public/data/lakes_index.json +++ b/public/data/lakes_index.json @@ -5,11 +5,11 @@ "river": "Vltava", "priority": true, "level": "723.09", - "capacity": 76.3, + "capacity": 65.3, "storageDiff": -1.81, - "inflow": "0.0", - "outflow": "1.5", - "volume": 233.5, + "inflow": "9.3", + "outflow": "0.0", + "volume": 199.67, "maxVolume": 306, "lat": 48.6322, "lng": 14.2215, @@ -33,28 +33,28 @@ "name": "Lipno II", "river": "Vltava", "priority": true, - "level": "558.92", - "capacity": 34.9, - "storageDiff": -1.58, - "inflow": "0.0", + "level": "558.43", + "capacity": 23.3, + "storageDiff": -2.07, + "inflow": "5.4", "outflow": "0.0", - "volume": 0.5, + "volume": 0.35, "maxVolume": 1.5, "lat": 48.625, "lng": 14.318, "sparkline": [ - 559.59, - 559.52, - 559.44, - 559.37, - 559.29, - 559.21, - 559.13, - 559.05, - 558.96, - 558.94, - 558.93, - 558.92 + 558.63, + 558.62, + 558.6, + 558.58, + 558.56, + 558.54, + 558.52, + 558.5, + 558.49, + 558.47, + 558.44, + 558.43 ] }, { @@ -62,28 +62,28 @@ "name": "Hněvkovice", "river": "Vltava", "priority": true, - "level": "369.84", - "capacity": 88, - "storageDiff": -0.26, + "level": "369.83", + "capacity": 96.5, + "storageDiff": -0.27, "inflow": "0.0", - "outflow": "2.5", - "volume": 18.6, + "outflow": "14.2", + "volume": 20.37, "maxVolume": 21.1, "lat": 49.183, "lng": 14.444, "sparkline": [ + 369.84, + 369.84, + 369.84, 369.83, - 369.84, - 369.85, - 369.84, - 369.84, - 369.84, - 369.81, 369.83, - 369.84, - 369.84, - 369.84, - 369.84 + 369.83, + 369.83, + 369.83, + 369.83, + 369.83, + 369.83, + 369.83 ] }, { @@ -91,28 +91,28 @@ "name": "Kořensko", "river": "Vltava", "priority": true, - "level": "352.50", - "capacity": 33.3, - "storageDiff": -0.1, - "inflow": "0.0", + "level": "352.43", + "capacity": 97.9, + "storageDiff": -0.17, + "inflow": "13.4", "outflow": "19.1", - "volume": 0.9, + "volume": 2.74, "maxVolume": 2.8, "lat": 49.255, "lng": 14.398, "sparkline": [ - 352.47, - 352.48, - 352.49, - 352.52, - 352.56, - 352.57, - 352.56, - 352.55, - 352.52, - 352.51, - 352.51, - 352.5 + 352.44, + 352.43, + 352.43, + 352.44, + 352.44, + 352.44, + 352.44, + 352.43, + 352.43, + 352.44, + 352.44, + 352.43 ] }, { @@ -120,28 +120,28 @@ "name": "Orlík", "river": "Vltava", "priority": true, - "level": "345.27", - "capacity": 63.6, - "storageDiff": -4.63, - "inflow": "0.0", + "level": "345.29", + "capacity": 73, + "storageDiff": -4.61, + "inflow": "24.4", "outflow": "0.0", - "volume": 455.7, + "volume": 522.72, "maxVolume": 716.5, "lat": 49.606, "lng": 14.17, "sparkline": [ - 345.25, - 345.26, - 345.26, - 345.25, - 345.26, - 345.26, - 345.26, - 345.27, - 345.27, - 345.27, - 345.27, - 345.27 + 345.29, + 345.29, + 345.29, + 345.29, + 345.29, + 345.29, + 345.29, + 345.29, + 345.29, + 345.29, + 345.29, + 345.29 ] }, { @@ -150,25 +150,25 @@ "river": "Vltava", "priority": true, "level": "269.88", - "capacity": 78.2, + "capacity": 97, "storageDiff": -0.72, - "inflow": "0.0", + "inflow": "81.1", "outflow": "0.0", - "volume": 210.6, + "volume": 261.1, "maxVolume": 269.3, "lat": 49.822, "lng": 14.436, "sparkline": [ - 269.87, - 269.86, - 269.89, - 269.86, - 269.89, - 269.88, - 269.89, 269.88, 269.89, 269.89, + 269.89, + 269.88, + 269.88, + 269.88, + 269.88, + 269.88, + 269.88, 269.88, 269.88 ] @@ -178,28 +178,28 @@ "name": "Štěchovice", "river": "Vltava", "priority": true, - "level": "217.04", - "capacity": 1.6, - "storageDiff": -2.36, - "inflow": "0.0", + "level": "216.98", + "capacity": 72.7, + "storageDiff": -2.42, + "inflow": "48.3", "outflow": "0.0", - "volume": 0.2, + "volume": 8.14, "maxVolume": 11.2, "lat": 49.845, "lng": 14.412, "sparkline": [ - 218.33, - 218.25, - 218.1, - 217.82, - 217.57, - 217.32, - 217.19, - 217.1, - 217.05, - 217.04, - 217.06, - 217.04 + 217, + 216.97, + 216.99, + 216.98, + 216.95, + 216.98, + 216.97, + 216.94, + 216.98, + 216.97, + 216.95, + 216.98 ] }, { @@ -207,28 +207,28 @@ "name": "Římov", "river": "Malše", "priority": true, - "level": "467.74", - "capacity": 74.9, - "storageDiff": -2.91, - "inflow": "0.0", + "level": "467.75", + "capacity": 78.5, + "storageDiff": -2.9, + "inflow": "2.2", "outflow": "0.0", - "volume": 25.3, + "volume": 26.54, "maxVolume": 33.8, "lat": 48.847, "lng": 14.487, "sparkline": [ - 467.73, - 467.73, - 467.73, - 467.73, - 467.73, - 467.73, - 467.74, - 467.74, - 467.74, - 467.74, - 467.74, - 467.74 + 467.75, + 467.75, + 467.75, + 467.75, + 467.75, + 467.75, + 467.75, + 467.75, + 467.75, + 467.75, + 467.75, + 467.75 ] }, { @@ -236,28 +236,28 @@ "name": "Hracholusky", "river": "Mže", "priority": true, - "level": "352.84", - "capacity": 11.4, - "storageDiff": -16.66, - "inflow": "0.0", + "level": "352.83", + "capacity": 57, + "storageDiff": -16.67, + "inflow": "1.5", "outflow": "2.5", - "volume": 6.5, + "volume": 32.31, "maxVolume": 56.7, "lat": 49.789, "lng": 13.155, "sparkline": [ 352.84, 352.84, + 352.83, 352.84, 352.84, 352.84, 352.84, + 352.83, 352.84, 352.84, 352.84, - 352.84, - 352.84, - 352.84 + 352.83 ] } ] \ No newline at end of file diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..dc62289 --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,4 @@ +User-agent: * +Allow: / + +Sitemap: https://hladinator.cz/sitemap.xml diff --git a/scripts/scrapeLakes.ts b/scripts/scrapeLakes.ts index 3076a58..2820f77 100644 --- a/scripts/scrapeLakes.ts +++ b/scripts/scrapeLakes.ts @@ -78,70 +78,37 @@ async function scrapeLake(lakeId: string, oid: string, internalId: string) { }); const records: DataRecord[] = []; + let dataTable = null; + $('table').each((i, tbl) => { + if ($(tbl).text().includes('Datum') && $(tbl).text().includes('Odtok')) { + dataTable = $(tbl); + } + }); - const parseTable = (htmlContent: string) => { - const _$ = cheerio.load(htmlContent); - let dataTable = null; - _$('table').each((i, tbl) => { - if (_$(tbl).text().includes('Datum') && _$(tbl).text().includes('Odtok')) { - dataTable = _$(tbl); + if (dataTable) { + dataTable.find('tr').each((i, row) => { + if (i === 0) return; // skip header + const cols = $(row).find('td'); + if (cols.length >= 3) { + const rawDate = $(cols[0]).text().trim(); + const levelStr = $(cols[1]).text().trim().replace(',', '.'); + let flowStr = $(cols[2]).text().trim().replace(',', '.'); + if (flowStr === '' && cols.length >= 4) { + flowStr = $(cols[3]).text().trim().replace(',', '.'); + } + + const parsedDateStr = parseDateString(rawDate); + if (parsedDateStr) { + records.push({ + timestamp: parsedDateStr, + level: parseFloat(levelStr) || 0, + flow: parseFloat(flowStr) || 0, + inflow: 0, + volume: 0 + }); + } } }); - - if (dataTable) { - dataTable.find('tr').each((i, row) => { - if (i === 0) return; // skip header - const cols = _$(row).find('td'); - if (cols.length >= 3) { - const rawDate = _$(cols[0]).text().trim(); - const levelStr = _$(cols[1]).text().trim().replace(',', '.'); - let flowStr = _$(cols[2]).text().trim().replace(',', '.'); - if (flowStr === '' && cols.length >= 4) { - flowStr = _$(cols[3]).text().trim().replace(',', '.'); - } - - const parsedDateStr = parseDateString(rawDate); - if (parsedDateStr) { - records.push({ - timestamp: parsedDateStr, - level: parseFloat(levelStr) || 0, - flow: parseFloat(flowStr) || 0, - inflow: 0, - volume: 0 - }); - } - } - }); - } - }; - - // 1. Zpracování týdenních dat (GET) - parseTable(response.data); - - // 2. Získání a zpracování měsíčních dat (POST) - try { - const viewstate = $('#__VIEWSTATE').val(); - const viewstategenerator = $('#__VIEWSTATEGENERATOR').val(); - const eventvalidation = $('#__EVENTVALIDATION').val(); - - if (viewstate && viewstategenerator && eventvalidation) { - const postData = new URLSearchParams(); - postData.append('__EVENTTARGET', 'ctl00$ObsahCPH$PrechodNaBilancniData'); - postData.append('__EVENTARGUMENT', ''); - postData.append('__VIEWSTATE', viewstate as string); - postData.append('__VIEWSTATEGENERATOR', viewstategenerator as string); - postData.append('__EVENTVALIDATION', eventvalidation as string); - - const postRes = await axios.post(URL, postData.toString(), { - httpsAgent: agent, - headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, - timeout: 10000 - }); - - parseTable(postRes.data); - } - } catch (err: any) { - console.warn(`Failed to fetch monthly data for ${internalId}:`, err.message); } if (records.length > 0) { diff --git a/src/App.tsx b/src/App.tsx index bbb0995..d18b697 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -12,13 +12,13 @@ import { lakesConfig } from '../scripts/lakesConfig'; import { slugify } from './utils/slugify'; import './App.css'; -const LakeDetailWrapper = ({ language }: { language: Language }) => { +const LakeDetailWrapper = ({ language, windUnit }: { language: Language, windUnit: 'kmh' | 'ms' }) => { const { slug } = useParams(); const lake = lakesConfig.find(l => slugify(l.text) === slug); if (!lake) return ; - return ; + return ; }; function App() { @@ -28,6 +28,9 @@ function App() { const [theme, setTheme] = useState<'dark' | 'light'>(() => { return (localStorage.getItem('hladinator_theme') as 'dark' | 'light') || 'dark'; }); + const [windUnit, setWindUnit] = useState<'kmh' | 'ms'>(() => { + return (localStorage.getItem('hladinator_windUnit') as 'kmh' | 'ms') || 'kmh'; + }); const [isSettingsOpen, setIsSettingsOpen] = useState(false); const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false); @@ -49,6 +52,10 @@ function App() { localStorage.setItem('hladinator_lang', language); }, [language]); + useEffect(() => { + localStorage.setItem('hladinator_windUnit', windUnit); + }, [windUnit]); + return (
{/* Mobile overlay */} @@ -73,7 +80,7 @@ function App() { } /> } /> } /> - } /> + } />
- Zdroje dat: pvl.cz, open-meteo.com + {t[language].chart.dataSources} pvl.cz, open-meteo.com {t[language].chart.createdIn}
@@ -96,6 +103,8 @@ function App() { setLanguage={setLanguage} theme={theme} setTheme={setTheme} + windUnit={windUnit} + setWindUnit={setWindUnit} onClose={() => setIsSettingsOpen(false)} /> )} diff --git a/src/components/FavoritesOverview.tsx b/src/components/FavoritesOverview.tsx index f336de1..8143c12 100644 --- a/src/components/FavoritesOverview.tsx +++ b/src/components/FavoritesOverview.tsx @@ -1,7 +1,8 @@ import { useState, useEffect } from 'react'; import { FiStar } from 'react-icons/fi'; -import { type Language } from '../translations'; +import { type Language, t } from '../translations'; import { useFavorites } from '../hooks/useFavorites'; +import { Helmet } from 'react-helmet-async'; import { CircularProgress } from './CircularProgress'; import { useNavigate } from 'react-router-dom'; import { slugify } from '../utils/slugify'; @@ -42,6 +43,12 @@ const FavoritesOverview = ({ language }: Props) => { return (
+ + {t[language].seo.favoritesTitle} + + + +

@@ -84,7 +91,7 @@ const FavoritesOverview = ({ language }: Props) => { {/* Unpin button */} +

+

+ {t[language].seo.lakeDesc.replace('{name}', lakeInfo.name)} +

+
+ + )} +
{topbarDict.updated} {new Date().toLocaleDateString(language === 'cs' ? 'cs-CZ' : 'en-GB', { day: '2-digit', month: '2-digit', year: 'numeric' })}, {new Date().toLocaleTimeString(language === 'cs' ? 'cs-CZ' : 'en-GB', { hour: '2-digit', minute: '2-digit' })} UTC
- - - {lakeInfo && lakeInfo.lat && lakeInfo.lng && ( - - )} +
+ + + {lakeInfo && lakeInfo.lat && lakeInfo.lng && ( + + )} +
{limits && limits.map((limit, idx) => { const diff = latestData.level - limit.level; @@ -279,7 +332,7 @@ const LakeDetail = ({ language, lakeId }: Props) => { - v.toFixed(2)} /> + v.toFixed(2)} /> Math.max(dataMax, 1)]} stroke="var(--text-muted)" tick={{fill: 'var(--text-muted)', fontSize: 12}} /> @@ -289,6 +342,12 @@ const LakeDetail = ({ language, lakeId }: Props) => { {limits && limits.map((limit, idx) => ( ))} + {staticConfig && staticConfig.maxLevel && ( + + )} + {staticConfig && staticConfig.storageLevel && ( + + )} @@ -329,6 +388,11 @@ const LakeDetail = ({ language, lakeId }: Props) => {
{language === 'cs' ? 'Srážky' : 'Precipitation'} [mm]
+ {/* Wind Chart placed inside the main card below the weather graph */} + {lakeInfo && lakeInfo.lat && lakeInfo.lng && ( + + )} + {/* Smoothed Toggle Control */}
{dict.view} diff --git a/src/components/LakeMap.tsx b/src/components/LakeMap.tsx index a584f12..280a54e 100644 --- a/src/components/LakeMap.tsx +++ b/src/components/LakeMap.tsx @@ -6,6 +6,7 @@ import { FiX, FiSearch, FiDroplet } from 'react-icons/fi'; import { type Language, t } from '../translations'; import { slugify } from '../utils/slugify'; import { useNavigate } from 'react-router-dom'; +import { Helmet } from 'react-helmet-async'; interface LakeData { id: string; @@ -61,6 +62,13 @@ const LakeMap = ({ language }: Props) => { return (
+ + {t[language].seo.mapTitle} + + + + + {/* Leaflet Map */} {
-

Seznam Jezer (Lakes List)

+

{language === 'cs' ? 'Seznam jezer a nádrží' : 'Lakes and Reservoirs List'}

setIsPanelVisible(false)} />
- Nalezeno: {filteredLakes.length} Jezer + {language === 'cs' ? `Nalezeno: ${filteredLakes.length} záznamů` : `Found: ${filteredLakes.length} records`}
setSearchTerm(e.target.value)} style={{ width: '100%', background: 'transparent', border: 'none', color: 'white', outline: 'none' }} @@ -117,14 +125,14 @@ const LakeMap = ({ language }: Props) => {
{filteredLakes.map((lake, index) => (
navigate(`/${slugify(lake.name)}`)}> -
{index + 1}. Jezero {lake.name}
+
{index + 1}. {lake.name}
- Area + {language === 'cs' ? 'Rozloha' : 'Area'} {(Math.random() * 50 + 10).toFixed(1)} km²
- Depth + {language === 'cs' ? 'Hloubka' : 'Depth'} {(Math.random() * 30 + 5).toFixed(1)}m
@@ -139,7 +147,7 @@ const LakeMap = ({ language }: Props) => { style={{ position: 'absolute', top: 10, right: 10, zIndex: 1000, background: 'var(--bg-card)', border: '1px solid var(--border-color)', color: 'white', padding: '0.5rem 1rem', borderRadius: '8px', cursor: 'pointer' }} onClick={() => setIsPanelVisible(true)} > - Show List + {language === 'cs' ? 'Zobrazit seznam' : 'Show List'} )}
diff --git a/src/components/LakesOverview.tsx b/src/components/LakesOverview.tsx index df17319..3356480 100644 --- a/src/components/LakesOverview.tsx +++ b/src/components/LakesOverview.tsx @@ -1,4 +1,5 @@ import { useState, useEffect } from 'react'; +import { Helmet } from 'react-helmet-async'; import { FiTrendingUp, FiTrendingDown, FiStar } from 'react-icons/fi'; import { type Language, t } from '../translations'; import { AreaChart, Area, ResponsiveContainer, YAxis } from 'recharts'; @@ -45,7 +46,7 @@ const LakeCard = ({ lake, language, isFav, onToggleFav }: { lake: Lake, language {/* Star / Favorite button */} | - | - | - -
+ + {t[language].seo.homeTitle} + + + + + +
+

{t[language].sidebar.lakes} ({lakes.length})

+

+ {t[language].seo.homeDesc} +

{/* Favorites section */} {favoriteLakes.length > 0 && (

- Oblíbená ({favoriteLakes.length}) + {language === 'cs' ? 'Oblíbená' : 'Favorites'} ({favoriteLakes.length})

void; theme: 'dark' | 'light'; setTheme: (theme: 'dark' | 'light') => void; + windUnit: 'kmh' | 'ms'; + setWindUnit: (unit: 'kmh' | 'ms') => void; onClose: () => void; } -const SettingsModal = ({ language, setLanguage, theme, setTheme, onClose }: Props) => { +const SettingsModal = ({ language, setLanguage, theme, setTheme, windUnit, setWindUnit, onClose }: Props) => { const dict = t[language].settings; return ( @@ -96,7 +98,7 @@ const SettingsModal = ({ language, setLanguage, theme, setTheme, onClose }: Prop cursor: 'pointer', transition: 'all 0.2s' }} > - {dict.english} + 🇬🇧 {dict.english} +
+
+ + {/* Wind Units Setting */} +
+ +
+ +
diff --git a/src/components/Sidebar.tsx b/src/components/Sidebar.tsx index cee6009..ccb6783 100644 --- a/src/components/Sidebar.tsx +++ b/src/components/Sidebar.tsx @@ -53,26 +53,31 @@ const Sidebar = ({ language, onOpenSettings, isMobileMenuOpen, onCloseMobileMenu
{/* Favourites */}
handleNavigate('/favorites')} style={{ position: 'relative' }}> - 0 ? '#f59e0b' : 'none'} color={favorites.length > 0 ? '#f59e0b' : 'currentColor'} /> +
+ 0 ? '#f59e0b' : 'none'} color={favorites.length > 0 ? '#f59e0b' : 'currentColor'} /> + {favorites.length > 0 && ( + + {favorites.length} + + )} +
{dict.favorites} - {favorites.length > 0 && ( - - {favorites.length} - - )}
{/* Lakes & Reservoirs */} diff --git a/src/components/WeatherWidget.tsx b/src/components/WeatherWidget.tsx index e43bca3..380d65a 100644 --- a/src/components/WeatherWidget.tsx +++ b/src/components/WeatherWidget.tsx @@ -6,6 +6,7 @@ interface WeatherProps { lng: number; language: 'cs' | 'en'; sensorTemp?: number; + windUnit?: 'kmh' | 'ms'; } interface WeatherData { @@ -31,7 +32,7 @@ const formatTime = (isoString: string) => { return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); }; -export const WeatherWidget = ({ lat, lng, language, sensorTemp }: WeatherProps) => { +export const WeatherWidget = ({ lat, lng, language, sensorTemp, windUnit = 'kmh' }: WeatherProps) => { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(false); @@ -46,7 +47,7 @@ export const WeatherWidget = ({ lat, lng, language, sensorTemp }: WeatherProps) const fetchWeather = async () => { try { setLoading(true); - const res = await fetch(`https://api.open-meteo.com/v1/forecast?latitude=${lat}&longitude=${lng}¤t=temperature_2m,wind_speed_10m,wind_direction_10m,wind_gusts_10m&daily=sunrise,sunset&timezone=auto&wind_speed_unit=ms`); + const res = await fetch(`https://api.open-meteo.com/v1/forecast?latitude=${lat}&longitude=${lng}¤t=temperature_2m,wind_speed_10m,wind_direction_10m,wind_gusts_10m&daily=sunrise,sunset&timezone=auto&wind_speed_unit=${windUnit}`); if (!res.ok) throw new Error('Failed to fetch weather'); const json = await res.json(); @@ -98,7 +99,7 @@ export const WeatherWidget = ({ lat, lng, language, sensorTemp }: WeatherProps)

{dict.title}

-
+
{/* Left Column: Wind */}
@@ -113,16 +114,16 @@ export const WeatherWidget = ({ lat, lng, language, sensorTemp }: WeatherProps)
- {data.windSpeed.toFixed(1)} m/s + {data.windSpeed.toFixed(1)} {windUnit === 'kmh' ? 'km/h' : 'm/s'}
- {getCompassDirection(data.windDir, language)} • {dict.gusts}: 10 ? 'var(--color-red)' : 'var(--text-main)' }}>{data.windGusts.toFixed(1)} m/s + {getCompassDirection(data.windDir, language)} • {dict.gusts}: (windUnit === 'kmh' ? 50 : 13.8) ? 'var(--color-red)' : 'var(--text-main)' }}>{data.windGusts.toFixed(1)} {windUnit === 'kmh' ? 'km/h' : 'm/s'}
{/* Right Column: Other Info */} -
+
{sensorTemp !== undefined ? sensorTemp.toFixed(1) : data.temp.toFixed(1)} °C diff --git a/src/components/WindChart.tsx b/src/components/WindChart.tsx new file mode 100644 index 0000000..c338df1 --- /dev/null +++ b/src/components/WindChart.tsx @@ -0,0 +1,273 @@ +import { useState, useEffect } from 'react'; +import { AreaChart, Area, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Line, ComposedChart } from 'recharts'; +import { FiWind } from 'react-icons/fi'; +import { type Language } from '../translations'; + +interface WindChartProps { + lat: number; + lng: number; + language: Language; + timeRange?: '24h' | '7d' | '30d' | '1y' | 'all'; + windUnit?: 'kmh' | 'ms'; +} + +interface WindDataPoint { + time: string; + speed: number; + gusts: number; + dir: number; + dirStr: string; +} + +const getCompassDirection = (degrees: number, language: 'cs' | 'en') => { + const directionsEn = ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW']; + const directionsCs = ['S', 'SV', 'V', 'JV', 'J', 'JZ', 'Z', 'SZ']; + const directions = language === 'cs' ? directionsCs : directionsEn; + const index = Math.round(((degrees %= 360) < 0 ? degrees + 360 : degrees) / 45) % 8; + return directions[index]; +}; + +const CustomWindTooltip = ({ active, payload, label, language, windUnit = 'kmh' }: any) => { + if (active && payload && payload.length) { + const data = payload[0].payload; + const date = new Date(label); + const dateStr = date.toLocaleDateString(language === 'cs' ? 'cs-CZ' : 'en-GB', { day: '2-digit', month: '2-digit', year: 'numeric' }); + const timeStr = date.toLocaleTimeString(language === 'cs' ? 'cs-CZ' : 'en-GB', { hour: '2-digit', minute: '2-digit' }); + + return ( +
+
+ {dateStr} {timeStr} +
+
+
+ + {language === 'cs' ? 'Rychlost větru' : 'Wind Speed'}: {data.speed} {windUnit === 'kmh' ? 'km/h' : 'm/s'} +
+
+ + {language === 'cs' ? 'Nárazy větru' : 'Wind Gusts'}: {data.gusts} {windUnit === 'kmh' ? 'km/h' : 'm/s'} +
+
+ + {language === 'cs' ? 'Směr' : 'Direction'}: {data.dirStr} ({data.dir}°) +
+
+
+ ); + } + return null; +}; + +const CustomWindDot = (props: any) => { + const { cx, cy, payload } = props; + + if (!cx || !cy || payload.dir === undefined) return null; + + return ( + + + + ); +}; + +export const WindChart = ({ lat, lng, language, timeRange = '7d', windUnit = 'kmh' }: WindChartProps) => { + const [data, setData] = useState([]); + const [loading, setLoading] = useState(true); + const [currentSpeed, setCurrentSpeed] = useState(0); + const [maxGust, setMaxGust] = useState(0); + + useEffect(() => { + const fetchWind = async () => { + try { + setLoading(true); + let url = ''; + let isDaily = false; + + if (timeRange === '1y' || timeRange === 'all') { + isDaily = true; + const end = new Date(); + end.setDate(end.getDate() - 1); + const endStr = end.toISOString().split('T')[0]; + + const start = new Date(); + if (timeRange === '1y') { + start.setDate(start.getDate() - 365); + } else { + start.setFullYear(2020); + } + const startStr = start.toISOString().split('T')[0]; + + url = `https://archive-api.open-meteo.com/v1/archive?latitude=${lat}&longitude=${lng}&start_date=${startStr}&end_date=${endStr}&daily=wind_speed_10m_max,wind_gusts_10m_max,wind_direction_10m_dominant&wind_speed_unit=${windUnit}&timezone=auto`; + } else { + let pastDays = 7; + if (timeRange === '24h') pastDays = 1; + if (timeRange === '30d') pastDays = 30; + url = `https://api.open-meteo.com/v1/forecast?latitude=${lat}&longitude=${lng}&hourly=wind_speed_10m,wind_gusts_10m,wind_direction_10m&past_days=${pastDays}&forecast_days=1&wind_speed_unit=${windUnit}&timezone=auto`; + } + + const res = await fetch(url); + if (!res.ok) throw new Error('Failed to fetch wind data'); + const json = await res.json(); + + const times = isDaily ? json.daily.time : json.hourly.time; + const speeds = isDaily ? json.daily.wind_speed_10m_max : json.hourly.wind_speed_10m; + const gusts = isDaily ? json.daily.wind_gusts_10m_max : json.hourly.wind_gusts_10m; + const dirs = isDaily ? json.daily.wind_direction_10m_dominant : json.hourly.wind_direction_10m; + + const chartData: WindDataPoint[] = []; + let maxG = 0; + + const now = new Date(); + let closestIdx = 0; + let minDiff = Infinity; + + for (let i = 0; i < times.length; i++) { + const t = new Date(times[i]); + const diff = Math.abs(t.getTime() - now.getTime()); + if (diff < minDiff) { + minDiff = diff; + closestIdx = i; + } + + if (t.getTime() <= now.getTime() || isDaily) { + if (gusts[i] > maxG) maxG = gusts[i]; + chartData.push({ + time: times[i], + speed: speeds[i] || 0, + gusts: gusts[i] || 0, + dir: dirs[i] || 0, + dirStr: getCompassDirection(dirs[i] || 0, language) + }); + } + } + + let downsampleFactor = 1; + if (timeRange === '7d') downsampleFactor = 3; + if (timeRange === '30d') downsampleFactor = 12; + if (timeRange === '1y') downsampleFactor = 3; + if (timeRange === 'all') downsampleFactor = 14; + + const downsampled = chartData.filter((_, i) => i % downsampleFactor === 0 || i === chartData.length - 1); + + setData(downsampled); + setMaxGust(maxG); + setCurrentSpeed(speeds[closestIdx] || speeds[speeds.length - 1] || 0); + + } catch (err) { + console.error(err); + } finally { + setLoading(false); + } + }; + + if (lat && lng) { + fetchWind(); + } + }, [lat, lng, language, timeRange]); + + if (loading) { + return ( +
+ {language === 'cs' ? 'Načítám data o větru...' : 'Loading wind data...'} +
+ ); + } + + if (data.length === 0) return null; + + return ( +
+
+

+ + {language === 'cs' ? `Aktivita větru (${timeRange === '1y' || timeRange === 'all' ? 'denní maxima' : timeRange})` : `Wind Activity (${timeRange === '1y' || timeRange === 'all' ? 'daily max' : timeRange})`} +

+ +
+
+ {language === 'cs' ? 'Aktuální rychlost' : 'Current Speed'} +
+ {currentSpeed.toFixed(1)} + {windUnit === 'kmh' ? 'km/h' : 'm/s'} +
+
+ +
+ {language === 'cs' ? 'Max. nárazy' : 'Peak Gusts'} +
+ {maxGust.toFixed(1)} + {windUnit === 'kmh' ? 'km/h' : 'm/s'} +
+
+
+
+ +
+ + + + + + + + + { + const d = new Date(v); + return `${d.getDate()}.${d.getMonth()+1}.`; + }} + /> + + + } /> + + } + activeDot={{ r: 6, fill: 'var(--color-cyan)', stroke: '#1e293b', strokeWidth: 2 }} + /> + + + +
+ +
+
+ + {language === 'cs' ? 'Rychlost větru' : 'Wind Speed'} +
+
+ + {language === 'cs' ? 'Nárazy větru' : 'Wind Gusts'} +
+
+
+ ); +}; diff --git a/src/index.css b/src/index.css index 64b5ced..02d17fe 100644 --- a/src/index.css +++ b/src/index.css @@ -10,10 +10,11 @@ --color-green: #22c55e; /* Přítok / Positive trend */ --color-red: #ef4444; /* Odtok / Negative trend */ --color-orange: #f97316; /* Odtok line chart color */ + --color-purple: #a855f7; /* Wind gusts line color */ .kpi-grid-container { display: grid; - grid-template-columns: repeat(3, 1fr); + grid-template-columns: repeat(4, 1fr); gap: 1.5rem; width: 100%; } @@ -161,6 +162,12 @@ border-top: 8px solid white; } +@media (max-width: 1024px) { + .kpi-grid-container { + grid-template-columns: repeat(2, 1fr); + } +} + @media (max-width: 768px) { .map-overlay-panel { top: auto; diff --git a/src/main.tsx b/src/main.tsx index a7c6abd..867aa64 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -2,15 +2,18 @@ import { StrictMode } from 'react' import { createRoot } from 'react-dom/client' import { BrowserRouter } from 'react-router-dom' import { FavoritesProvider } from './hooks/useFavorites' +import { HelmetProvider } from 'react-helmet-async' import './index.css' import App from './App.tsx' createRoot(document.getElementById('root')!).render( - - - - - + + + + + + + , ) diff --git a/src/translations.ts b/src/translations.ts index 1e99ae8..6f05d5b 100644 --- a/src/translations.ts +++ b/src/translations.ts @@ -12,6 +12,16 @@ export const t = { search: 'Search river or reservoir (e.g. Lipno)...', updated: 'Last updated:' }, + seo: { + homeTitle: 'Hladinátor - Water levels and flow rates of reservoirs', + homeDesc: 'Track current water levels, flow rates, inflow, and weather development on major Czech dams and reservoirs in real time. Data sourced from official river basin authorities.', + lakeTitle: '{name} - Water level and flow | Hladinátor', + lakeDesc: 'Current water level and statistics for the {name} reservoir. Track water level, flow rate, wind strength, and storage capacity in real time.', + favoritesTitle: 'Favorites | Hladinátor', + favoritesDesc: 'Your pinned lakes and reservoirs. Track water level, flow rate, and weather development on major Czech dams and reservoirs.', + mapTitle: 'Map | Hladinátor', + mapDesc: 'Interactive map of all monitored lakes and reservoirs in the Czech Republic.' + }, kpi: { level: 'WATER LEVEL', flow: 'FLOW RATE', @@ -46,6 +56,9 @@ export const t = { language: 'Language', english: 'English', czech: 'Čeština', + windUnits: 'Wind units', + windUnitKmh: 'km/h', + windUnitMs: 'm/s', contact: 'Contact', contactPlaceholder: 'Your email address', buyCoffee: 'Buy Me a Coffee' @@ -62,6 +75,16 @@ export const t = { search: 'Hledat tok nebo nádrž (např. Lipno)...', updated: 'Aktualizováno:' }, + seo: { + homeTitle: 'Hladinátor - Aktuální stav přehrad a nádrží', + homeDesc: 'Sledujte aktuální vodní stav, průtok, přítok a vývoj počasí na nejvýznamnějších českých přehradách v reálném čase. Oficiální data z povodí.', + lakeTitle: '{name} - Stav hladiny a průtok | Hladinátor', + lakeDesc: 'Aktuální vodní stav a statistiky pro vodní dílo {name}. Sledujte vývoj hladiny, sílu větru a kapacitu zásobního prostoru v reálném čase.', + favoritesTitle: 'Oblíbené | Hladinátor', + favoritesDesc: 'Vaše připnuté přehrady a nádrže. Sledujte aktuální vodní stav, průtok a vývoj počasí na vybraných českých přehradách.', + mapTitle: 'Mapa | Hladinátor', + mapDesc: 'Interaktivní mapa všech sledovaných přehrad a nádrží v České republice.' + }, kpi: { level: 'HLADINA', flow: 'PRŮTOK', @@ -96,6 +119,9 @@ export const t = { language: 'Jazyk', english: 'English', czech: 'Čeština', + windUnits: 'Jednotky větru', + windUnitKmh: 'km/h', + windUnitMs: 'm/s', contact: 'Kontakt', contactPlaceholder: 'Vaše e-mailová adresa', buyCoffee: 'Kup mi kávu' diff --git a/src/utils/navigationLimits.ts b/src/utils/navigationLimits.ts index 0caabdd..c0cade1 100644 --- a/src/utils/navigationLimits.ts +++ b/src/utils/navigationLimits.ts @@ -7,7 +7,7 @@ export interface NavigationLimit { export const NAVIGATION_LIMITS: Record = { // Orlík - 'VLOR|1': [ + 'VLOR|2': [ { level: 342.50, labelCs: 'Minimální hladina pro lodní výtah Orlík',