feat: add disclaimer modal, update lake data, and improve component interactions

This commit is contained in:
David Fencl
2026-06-06 20:35:47 +02:00
parent a67a2247c3
commit 231961da19
48 changed files with 1238 additions and 133 deletions
+19 -1
View File
@@ -6782,7 +6782,25 @@
"flow": 0,
"inflow": 0,
"volume": 0,
"temperature": 19.9,
"temperature": 20.2,
"precipitation": 0.1
},
{
"timestamp": "2026-06-06T18:15:00.000Z",
"level": 463.42,
"flow": 0,
"inflow": 0,
"volume": 0,
"temperature": 20.2,
"precipitation": 0.1
},
{
"timestamp": "2026-06-06T18:30:00.000Z",
"level": 463.42,
"flow": 0,
"inflow": 0,
"volume": 0,
"temperature": 19,
"precipitation": 0
}
]
+19 -1
View File
@@ -6798,9 +6798,27 @@
"timestamp": "2026-06-06T18:00:00.000Z",
"level": 521.29,
"flow": 0.64,
"inflow": 0,
"volume": 0,
"temperature": 18.7,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:10:00.000Z",
"level": 521.29,
"flow": 0.64,
"inflow": 0,
"volume": 0,
"temperature": 18.7,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:20:00.000Z",
"level": 521.29,
"flow": 0.65,
"inflow": 0.92,
"volume": 2.44,
"temperature": 18.3,
"temperature": 17.2,
"precipitation": 0
}
]
+28 -1
View File
@@ -6799,8 +6799,35 @@
"level": 416.74,
"flow": 0,
"inflow": 0,
"volume": 0,
"temperature": 20.7,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:10:00.000Z",
"level": 416.74,
"flow": 0,
"inflow": 0,
"volume": 0,
"temperature": 20.7,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:20:00.000Z",
"level": 416.74,
"flow": 0,
"inflow": 0,
"volume": 0,
"temperature": 20.7,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:30:00.000Z",
"level": 416.74,
"flow": 0,
"inflow": 0,
"volume": 0.09,
"temperature": 20.2,
"temperature": 18.8,
"precipitation": 0
}
]
+28 -1
View File
@@ -6799,8 +6799,35 @@
"level": 448.82,
"flow": 0,
"inflow": 0,
"volume": 0,
"temperature": 20.6,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:10:00.000Z",
"level": 448.82,
"flow": 0,
"inflow": 0,
"volume": 0,
"temperature": 20.6,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:20:00.000Z",
"level": 448.82,
"flow": 0,
"inflow": 0,
"volume": 0,
"temperature": 20.6,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:30:00.000Z",
"level": 448.82,
"flow": 0,
"inflow": 0,
"volume": 0.67,
"temperature": 20.2,
"temperature": 18.8,
"precipitation": 0
}
]
+9
View File
@@ -6775,5 +6775,14 @@
"volume": 0.04,
"temperature": 19.6,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:00:00.000Z",
"level": 581.35,
"flow": 0,
"inflow": 0,
"volume": 0.04,
"temperature": 18.3,
"precipitation": 0
}
]
+19 -1
View File
@@ -6798,9 +6798,27 @@
"timestamp": "2026-06-06T18:00:00.000Z",
"level": 447.02,
"flow": 0.23,
"inflow": 0,
"volume": 0,
"temperature": 19.9,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:10:00.000Z",
"level": 447.02,
"flow": 0,
"inflow": 0,
"volume": 0,
"temperature": 19.9,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:20:00.000Z",
"level": 447.02,
"flow": 0,
"inflow": 1.08,
"volume": 1.65,
"temperature": 19.6,
"temperature": 18.5,
"precipitation": 0
}
]
+28 -1
View File
@@ -6797,10 +6797,37 @@
{
"timestamp": "2026-06-06T18:00:00.000Z",
"level": 407.64,
"flow": 0.2,
"inflow": 0,
"volume": 0,
"temperature": 19.4,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:10:00.000Z",
"level": 407.64,
"flow": 0.2,
"inflow": 0,
"volume": 0,
"temperature": 19.4,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:20:00.000Z",
"level": 407.64,
"flow": 0,
"inflow": 0,
"volume": 0,
"temperature": 19.4,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:30:00.000Z",
"level": 407.64,
"flow": 0,
"inflow": 0.42,
"volume": 0.14,
"temperature": 19.1,
"temperature": 17.9,
"precipitation": 0
}
]
+19 -1
View File
@@ -6798,9 +6798,27 @@
"timestamp": "2026-06-06T18:00:00.000Z",
"level": 292.9,
"flow": 0.02,
"inflow": 0,
"volume": 0,
"temperature": 20.8,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:10:00.000Z",
"level": 292.9,
"flow": 0.02,
"inflow": 0,
"volume": 0,
"temperature": 20.8,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:20:00.000Z",
"level": 292.9,
"flow": 0.02,
"inflow": 0.01,
"volume": 7.49,
"temperature": 20.4,
"temperature": 19.1,
"precipitation": 0
}
]
+9
View File
@@ -6775,5 +6775,14 @@
"volume": 0,
"temperature": 18.5,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:00:00.000Z",
"level": 632.77,
"flow": 0,
"inflow": 0,
"volume": 0,
"temperature": 17.8,
"precipitation": 0
}
]
+9
View File
@@ -6775,5 +6775,14 @@
"volume": 0,
"temperature": 18.8,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:00:00.000Z",
"level": 635.7,
"flow": 0,
"inflow": 0,
"volume": 0,
"temperature": 18.1,
"precipitation": 0
}
]
+19 -1
View File
@@ -6798,9 +6798,27 @@
"timestamp": "2026-06-06T18:00:00.000Z",
"level": 345,
"flow": 1.51,
"inflow": 0,
"volume": 0,
"temperature": 21,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:10:00.000Z",
"level": 345,
"flow": 1.51,
"inflow": 0,
"volume": 0,
"temperature": 21,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:20:00.000Z",
"level": 345,
"flow": 1.5,
"inflow": 1.06,
"volume": 0.66,
"temperature": 20.7,
"temperature": 20.3,
"precipitation": 0
}
]
+28 -1
View File
@@ -6798,9 +6798,36 @@
"timestamp": "2026-06-06T18:00:00.000Z",
"level": 640.67,
"flow": 0.01,
"inflow": 0,
"volume": 0,
"temperature": 18.4,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:10:00.000Z",
"level": 640.67,
"flow": 0.01,
"inflow": 0,
"volume": 0,
"temperature": 18.4,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:20:00.000Z",
"level": 640.67,
"flow": 0.01,
"inflow": 0,
"volume": 0,
"temperature": 18.4,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:30:00.000Z",
"level": 640.67,
"flow": 0.01,
"inflow": 0.02,
"volume": 0.73,
"temperature": 18.2,
"temperature": 17.8,
"precipitation": 0
}
]
+19 -1
View File
@@ -7112,10 +7112,28 @@
{
"timestamp": "2026-06-06T18:00:00.000Z",
"level": 467.75,
"flow": 0.7,
"inflow": 0,
"volume": 0,
"temperature": 20.8,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:10:00.000Z",
"level": 467.76,
"flow": 0.7,
"inflow": 0,
"volume": 0,
"temperature": 20.8,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:20:00.000Z",
"level": 467.75,
"flow": 0,
"inflow": 2.24,
"volume": 26.54,
"temperature": 20.5,
"temperature": 19.4,
"precipitation": 0
}
]
+19 -1
View File
@@ -7122,9 +7122,27 @@
"timestamp": "2026-06-06T18:00:00.000Z",
"level": 352.83,
"flow": 2.52,
"inflow": 0,
"volume": 0,
"temperature": 21,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:10:00.000Z",
"level": 352.83,
"flow": 2.52,
"inflow": 0,
"volume": 0,
"temperature": 21,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:20:00.000Z",
"level": 352.83,
"flow": 2.52,
"inflow": 1.47,
"volume": 32.28,
"temperature": 20.8,
"temperature": 20.1,
"precipitation": 0
}
]
+20 -2
View File
@@ -6797,10 +6797,28 @@
{
"timestamp": "2026-06-06T18:00:00.000Z",
"level": 530.7,
"flow": 0,
"flow": 0.49,
"inflow": 0,
"volume": 0,
"temperature": 19.4,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:10:00.000Z",
"level": 530.7,
"flow": 0.49,
"inflow": 0,
"volume": 0,
"temperature": 19.4,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:20:00.000Z",
"level": 530.7,
"flow": 0.49,
"inflow": 0.48,
"volume": 2.94,
"temperature": 19.1,
"temperature": 18.3,
"precipitation": 0
}
]
+28 -1
View File
@@ -6796,11 +6796,38 @@
},
{
"timestamp": "2026-06-06T18:00:00.000Z",
"level": 563.67,
"flow": 0.01,
"inflow": 0,
"volume": 0,
"temperature": 19.5,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:10:00.000Z",
"level": 563.67,
"flow": 0.01,
"inflow": 0,
"volume": 0,
"temperature": 19.5,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:20:00.000Z",
"level": 563.67,
"flow": 0.01,
"inflow": 0,
"volume": 0,
"temperature": 19.5,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:30:00.000Z",
"level": 0,
"flow": 0.01,
"inflow": 0.02,
"volume": 0.46,
"temperature": 19.2,
"temperature": 18.3,
"precipitation": 0
}
]
+1 -1
View File
@@ -6746,7 +6746,7 @@
"flow": 0,
"inflow": 0,
"volume": 0,
"temperature": 18.6,
"temperature": 17.6,
"precipitation": 0
}
]
+20 -2
View File
@@ -6796,11 +6796,29 @@
},
{
"timestamp": "2026-06-06T18:00:00.000Z",
"level": 0,
"level": 313.39,
"flow": 2.99,
"inflow": 0,
"volume": 0,
"temperature": 21.9,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:10:00.000Z",
"level": 313.39,
"flow": 2.99,
"inflow": 0,
"volume": 0,
"temperature": 21.9,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:20:00.000Z",
"level": 313.39,
"flow": 2.84,
"inflow": 1.27,
"volume": 2.9,
"temperature": 21.7,
"temperature": 20.9,
"precipitation": 0
}
]
+28 -1
View File
@@ -6799,8 +6799,35 @@
"level": 575.72,
"flow": 0.02,
"inflow": 0,
"volume": 0,
"temperature": 19,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:10:00.000Z",
"level": 575.72,
"flow": 0.02,
"inflow": 0,
"volume": 0,
"temperature": 19,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:20:00.000Z",
"level": 575.72,
"flow": 0.02,
"inflow": 0,
"volume": 0,
"temperature": 19,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:30:00.000Z",
"level": 575.72,
"flow": 0.02,
"inflow": 0,
"volume": 1.07,
"temperature": 18.7,
"temperature": 17.8,
"precipitation": 0
}
]
+28 -1
View File
@@ -6796,11 +6796,38 @@
},
{
"timestamp": "2026-06-06T18:00:00.000Z",
"level": 534.62,
"flow": 0.06,
"inflow": 0,
"volume": 0,
"temperature": 20.1,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:10:00.000Z",
"level": 534.62,
"flow": 0.06,
"inflow": 0,
"volume": 0,
"temperature": 20.1,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:20:00.000Z",
"level": 534.62,
"flow": 0.06,
"inflow": 0,
"volume": 0,
"temperature": 20.1,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:30:00.000Z",
"level": 0,
"flow": 0.06,
"inflow": 0.11,
"volume": 0.09,
"temperature": 19.8,
"temperature": 18.4,
"precipitation": 0
}
]
+28 -1
View File
@@ -6798,9 +6798,36 @@
"timestamp": "2026-06-06T18:00:00.000Z",
"level": 260.09,
"flow": 0.06,
"inflow": 0,
"volume": 0,
"temperature": 21.2,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:10:00.000Z",
"level": 260.09,
"flow": 0.06,
"inflow": 0,
"volume": 0,
"temperature": 21.2,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:20:00.000Z",
"level": 260.09,
"flow": 0.06,
"inflow": 0,
"volume": 0,
"temperature": 21.2,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:30:00.000Z",
"level": 260.09,
"flow": 0.06,
"inflow": 0.1,
"volume": 0.41,
"temperature": 20.8,
"temperature": 19.7,
"precipitation": 0
}
]
+27
View File
@@ -6793,5 +6793,32 @@
"volume": 0.39,
"temperature": 19.5,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:00:00.000Z",
"level": 668.4,
"flow": 0,
"inflow": 0,
"volume": 0,
"temperature": 19.5,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:10:00.000Z",
"level": 668.4,
"flow": 0,
"inflow": 0,
"volume": 0,
"temperature": 19.5,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:20:00.000Z",
"level": 668.4,
"flow": 0,
"inflow": 0,
"volume": 0.39,
"temperature": 18.5,
"precipitation": 0
}
]
+28 -1
View File
@@ -6799,8 +6799,35 @@
"level": 385.01,
"flow": 0.03,
"inflow": 0,
"volume": 0,
"temperature": 19.9,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:10:00.000Z",
"level": 385.01,
"flow": 0.03,
"inflow": 0,
"volume": 0,
"temperature": 19.9,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:20:00.000Z",
"level": 385.01,
"flow": 0.03,
"inflow": 0,
"volume": 0,
"temperature": 19.9,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:30:00.000Z",
"level": 385.01,
"flow": 0.03,
"inflow": 0,
"volume": 0.84,
"temperature": 19.5,
"temperature": 18.2,
"precipitation": 0
}
]
+27
View File
@@ -6793,5 +6793,32 @@
"volume": 0.16,
"temperature": 17,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:00:00.000Z",
"level": 678.61,
"flow": 0,
"inflow": 0,
"volume": 0,
"temperature": 17,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:10:00.000Z",
"level": 678.61,
"flow": 0,
"inflow": 0,
"volume": 0,
"temperature": 17,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:20:00.000Z",
"level": 678.61,
"flow": 0,
"inflow": 0,
"volume": 0.16,
"temperature": 15.9,
"precipitation": 0
}
]
+20 -2
View File
@@ -6796,11 +6796,29 @@
},
{
"timestamp": "2026-06-06T18:00:00.000Z",
"level": 0,
"level": 588.42,
"flow": 0.08,
"inflow": 0,
"volume": 0,
"temperature": 19.8,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:10:00.000Z",
"level": 588.42,
"flow": 0.08,
"inflow": 0,
"volume": 0,
"temperature": 19.8,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:20:00.000Z",
"level": 588.42,
"flow": 0.08,
"inflow": 0,
"volume": 0.33,
"temperature": 19.4,
"temperature": 18.2,
"precipitation": 0
}
]
+28 -1
View File
@@ -6798,9 +6798,36 @@
"timestamp": "2026-06-06T18:00:00.000Z",
"level": 505.67,
"flow": 0.22,
"inflow": 0,
"volume": 0,
"temperature": 19.6,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:10:00.000Z",
"level": 505.67,
"flow": 0.22,
"inflow": 0,
"volume": 0,
"temperature": 19.6,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:20:00.000Z",
"level": 505.67,
"flow": 0.22,
"inflow": 0,
"volume": 0,
"temperature": 19.6,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:30:00.000Z",
"level": 505.67,
"flow": 0.22,
"inflow": 0.1,
"volume": 9.32,
"temperature": 19.3,
"temperature": 18.4,
"precipitation": 0
}
]
+28 -1
View File
@@ -6796,11 +6796,38 @@
},
{
"timestamp": "2026-06-06T18:00:00.000Z",
"level": 580.54,
"flow": 0.05,
"inflow": 0,
"volume": 0,
"temperature": 18.8,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:10:00.000Z",
"level": 580.54,
"flow": 0.05,
"inflow": 0,
"volume": 0,
"temperature": 18.8,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:20:00.000Z",
"level": 580.54,
"flow": 0.05,
"inflow": 0,
"volume": 0,
"temperature": 18.8,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:30:00.000Z",
"level": 0,
"flow": 0.05,
"inflow": 0,
"volume": 0.41,
"temperature": 18.5,
"temperature": 17.6,
"precipitation": 0
}
]
+19 -1
View File
@@ -6798,9 +6798,27 @@
"timestamp": "2026-06-06T18:00:00.000Z",
"level": 412.8,
"flow": 0.33,
"inflow": 0,
"volume": 0,
"temperature": 20.2,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:10:00.000Z",
"level": 412.8,
"flow": 0.33,
"inflow": 0,
"volume": 0,
"temperature": 20.2,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:20:00.000Z",
"level": 412.8,
"flow": 0.34,
"inflow": 0.46,
"volume": 5.16,
"temperature": 19.9,
"temperature": 18.7,
"precipitation": 0
}
]
+20 -2
View File
@@ -6797,10 +6797,28 @@
{
"timestamp": "2026-06-06T18:00:00.000Z",
"level": 520.35,
"flow": 0,
"flow": 0.71,
"inflow": 0,
"volume": 0,
"temperature": 17.2,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:10:00.000Z",
"level": 520.35,
"flow": 0.71,
"inflow": 0,
"volume": 0,
"temperature": 17.2,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:20:00.000Z",
"level": 520.35,
"flow": 0.72,
"inflow": 0.68,
"volume": 15.35,
"temperature": 16.9,
"temperature": 16.5,
"precipitation": 0
}
]
+27
View File
@@ -7117,5 +7117,32 @@
"volume": 20.34,
"temperature": 20.9,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:00:00.000Z",
"level": 369.81,
"flow": 14.23,
"inflow": 0,
"volume": 0,
"temperature": 20.9,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:10:00.000Z",
"level": 369.81,
"flow": 14.21,
"inflow": 0,
"volume": 0,
"temperature": 20.9,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:20:00.000Z",
"level": 369.81,
"flow": 14.21,
"inflow": 0,
"volume": 20.32,
"temperature": 19.8,
"precipitation": 0
}
]
+19 -1
View File
@@ -6798,9 +6798,27 @@
"timestamp": "2026-06-06T18:00:00.000Z",
"level": 283.1,
"flow": 135.01,
"inflow": 0,
"volume": 0,
"temperature": 21.7,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:10:00.000Z",
"level": 282.97,
"flow": 336.52,
"inflow": 0,
"volume": 0,
"temperature": 21.7,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:20:00.000Z",
"level": 282.99,
"flow": 397.75,
"inflow": 85.78,
"volume": 10.12,
"temperature": 21.3,
"temperature": 19.8,
"precipitation": 0
}
]
+27
View File
@@ -7117,5 +7117,32 @@
"volume": 2.74,
"temperature": 20.8,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:00:00.000Z",
"level": 352.43,
"flow": 19.05,
"inflow": 0,
"volume": 0,
"temperature": 20.8,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:10:00.000Z",
"level": 352.43,
"flow": 19.05,
"inflow": 0,
"volume": 0,
"temperature": 20.8,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:20:00.000Z",
"level": 352.43,
"flow": 19.05,
"inflow": 13.43,
"volume": 2.74,
"temperature": 19.8,
"precipitation": 0
}
]
+27
View File
@@ -7117,5 +7117,32 @@
"volume": 199.67,
"temperature": 19.2,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:00:00.000Z",
"level": 723.08,
"flow": 58.51,
"inflow": 0,
"volume": 0,
"temperature": 19.2,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:10:00.000Z",
"level": 723.1,
"flow": 58.83,
"inflow": 0,
"volume": 0,
"temperature": 19.2,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:20:00.000Z",
"level": 723.1,
"flow": 45.19,
"inflow": 9.25,
"volume": 199.28,
"temperature": 17.9,
"precipitation": 0
}
]
+27
View File
@@ -7117,5 +7117,32 @@
"volume": 0.32,
"temperature": 19.8,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:00:00.000Z",
"level": 558.61,
"flow": 0,
"inflow": 0,
"volume": 0,
"temperature": 19.8,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:10:00.000Z",
"level": 558.77,
"flow": 0,
"inflow": 0,
"volume": 0,
"temperature": 19.8,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:20:00.000Z",
"level": 558.92,
"flow": 0,
"inflow": 5.37,
"volume": 0.38,
"temperature": 18.1,
"precipitation": 0
}
]
+27
View File
@@ -7117,5 +7117,32 @@
"volume": 522.92,
"temperature": 21.2,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:00:00.000Z",
"level": 345.28,
"flow": 169.04,
"inflow": 0,
"volume": 0,
"temperature": 21.2,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:10:00.000Z",
"level": 345.26,
"flow": 357.29,
"inflow": 0,
"volume": 0,
"temperature": 21.2,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:20:00.000Z",
"level": 345.25,
"flow": 459.43,
"inflow": 24.39,
"volume": 522.52,
"temperature": 20.6,
"precipitation": 0
}
]
+19 -1
View File
@@ -7122,9 +7122,27 @@
"timestamp": "2026-06-06T18:00:00.000Z",
"level": 269.86,
"flow": 189.31,
"inflow": 0,
"volume": 0,
"temperature": 21.9,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:10:00.000Z",
"level": 269.85,
"flow": 250.37,
"inflow": 0,
"volume": 0,
"temperature": 21.9,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:20:00.000Z",
"level": 269.86,
"flow": 294.34,
"inflow": 81.06,
"volume": 260.87,
"temperature": 21.4,
"temperature": 20.2,
"precipitation": 0
}
]
+19 -1
View File
@@ -7122,9 +7122,27 @@
"timestamp": "2026-06-06T18:00:00.000Z",
"level": 217.04,
"flow": 24.26,
"inflow": 0,
"volume": 0,
"temperature": 21,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:10:00.000Z",
"level": 216.99,
"flow": 101.16,
"inflow": 0,
"volume": 0,
"temperature": 21,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:20:00.000Z",
"level": 217.24,
"flow": 150.52,
"inflow": 48.25,
"volume": 8.22,
"temperature": 20.6,
"temperature": 19.5,
"precipitation": 0
}
]
+19 -1
View File
@@ -6798,9 +6798,27 @@
"timestamp": "2026-06-06T18:00:00.000Z",
"level": 199.47,
"flow": 39.53,
"inflow": 0,
"volume": 0,
"temperature": 22.1,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:10:00.000Z",
"level": 199.48,
"flow": 39.58,
"inflow": 0,
"volume": 0,
"temperature": 22.1,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:20:00.000Z",
"level": 199.5,
"flow": 39.53,
"inflow": 45,
"volume": 9.49,
"temperature": 21.6,
"temperature": 20.1,
"precipitation": 0
}
]
+19 -1
View File
@@ -6797,10 +6797,28 @@
{
"timestamp": "2026-06-06T18:00:00.000Z",
"level": 375.15,
"flow": 0.44,
"inflow": 0,
"volume": 0,
"temperature": 21.1,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:10:00.000Z",
"level": 375.15,
"flow": 0.44,
"inflow": 0,
"volume": 0,
"temperature": 21.1,
"precipitation": 0
},
{
"timestamp": "2026-06-06T18:20:00.000Z",
"level": 375.15,
"flow": 0,
"inflow": 1.87,
"volume": 240.94,
"temperature": 20.8,
"temperature": 20,
"precipitation": 0
}
]
+133 -94
View File
@@ -4,13 +4,14 @@
"name": "Lipno 1",
"river": "Vltava",
"priority": true,
"level": "723.08",
"capacity": 65.3,
"storageDiff": -1.82,
"level": "723.10",
"capacity": 65.1,
"storageDiff": -1.8,
"inflow": "9.3",
"outflow": "51.0",
"volume": 199.67,
"outflow": "45.2",
"volume": 199.28,
"maxVolume": 306,
"navigationForbidden": false,
"lat": 48.6322,
"lng": 14.2215,
"sparkline": [
@@ -19,13 +20,13 @@
723.09,
723.09,
723.09,
723.09,
723.09,
723.09,
723.08,
723.08,
723.08,
723.08
723.08,
723.08,
723.1,
723.1
]
},
{
@@ -33,19 +34,17 @@
"name": "Lipno II",
"river": "Vltava",
"priority": true,
"level": "558.45",
"capacity": 20,
"storageDiff": -4.25,
"level": "558.92",
"capacity": 23.8,
"storageDiff": -3.78,
"inflow": "5.4",
"outflow": "0.0",
"volume": 0.32,
"volume": 0.38,
"maxVolume": 1.6,
"navigationForbidden": false,
"lat": 48.625,
"lng": 14.318,
"sparkline": [
558.44,
558.43,
558.41,
558.38,
558.37,
558.33,
@@ -54,7 +53,10 @@
558.17,
558.18,
558.31,
558.45
558.45,
558.61,
558.77,
558.92
]
},
{
@@ -63,18 +65,16 @@
"river": "Vltava",
"priority": true,
"level": "369.81",
"capacity": 96.4,
"capacity": 96.3,
"storageDiff": -0.29,
"inflow": "0.0",
"outflow": "14.2",
"volume": 20.34,
"volume": 20.32,
"maxVolume": 21.1,
"navigationForbidden": false,
"lat": 49.183,
"lng": 14.444,
"sparkline": [
369.83,
369.83,
369.83,
369.83,
369.83,
369.82,
@@ -83,6 +83,9 @@
369.82,
369.82,
369.82,
369.81,
369.81,
369.81,
369.81
]
},
@@ -98,10 +101,11 @@
"outflow": "19.1",
"volume": 2.74,
"maxVolume": 2.8,
"navigationForbidden": false,
"lat": 49.255,
"lng": 14.398,
"sparkline": [
352.44,
352.43,
352.43,
352.43,
352.43,
@@ -120,19 +124,17 @@
"name": "Orlík",
"river": "Vltava",
"priority": true,
"level": "345.28",
"capacity": 73,
"storageDiff": -4.62,
"level": "345.25",
"capacity": 72.9,
"storageDiff": -4.65,
"inflow": "24.4",
"outflow": "147.1",
"volume": 522.92,
"outflow": "459.4",
"volume": 522.52,
"maxVolume": 716.5,
"navigationForbidden": false,
"lat": 49.606,
"lng": 14.17,
"sparkline": [
345.29,
345.29,
345.29,
345.29,
345.29,
345.3,
@@ -141,7 +143,10 @@
345.29,
345.29,
345.29,
345.28
345.28,
345.28,
345.26,
345.25
]
},
{
@@ -153,14 +158,13 @@
"capacity": 96.9,
"storageDiff": -0.74,
"inflow": "81.1",
"outflow": "189.3",
"outflow": "294.3",
"volume": 260.87,
"maxVolume": 269.3,
"navigationForbidden": false,
"lat": 49.822,
"lng": 14.436,
"sparkline": [
269.88,
269.88,
269.88,
269.89,
269.89,
@@ -170,6 +174,8 @@
269.88,
269.88,
269.88,
269.86,
269.85,
269.86
]
},
@@ -178,18 +184,17 @@
"name": "Štěchovice",
"river": "Vltava",
"priority": true,
"level": "217.04",
"level": "217.24",
"capacity": 73.4,
"storageDiff": -2.36,
"storageDiff": -2.16,
"inflow": "48.3",
"outflow": "24.3",
"outflow": "150.5",
"volume": 8.22,
"maxVolume": 11.2,
"navigationForbidden": false,
"lat": 49.845,
"lng": 14.412,
"sparkline": [
216.98,
216.96,
216.94,
216.95,
216.93,
@@ -199,7 +204,9 @@
217.01,
216.99,
217.02,
217.04
217.04,
216.99,
217.24
]
},
{
@@ -214,6 +221,7 @@
"outflow": "0.0",
"volume": 26.54,
"maxVolume": 33.8,
"navigationForbidden": true,
"lat": 48.847,
"lng": 14.487,
"sparkline": [
@@ -227,7 +235,7 @@
467.75,
467.75,
467.75,
467.75,
467.76,
467.75
]
},
@@ -243,11 +251,10 @@
"outflow": "2.5",
"volume": 32.28,
"maxVolume": 56.7,
"navigationForbidden": false,
"lat": 49.789,
"lng": 13.155,
"sparkline": [
352.83,
352.83,
352.84,
352.84,
352.84,
@@ -257,6 +264,8 @@
352.83,
352.83,
352.84,
352.83,
352.83,
352.83
]
},
@@ -272,6 +281,7 @@
"outflow": "0.0",
"volume": 240.94,
"maxVolume": 266.6,
"navigationForbidden": true,
"lat": 49.704,
"lng": 15.115,
"sparkline": [
@@ -294,18 +304,17 @@
"name": "Kamýk",
"river": "",
"priority": false,
"level": "283.10",
"level": "282.99",
"capacity": 79.1,
"storageDiff": -1.5,
"storageDiff": -1.61,
"inflow": "85.8",
"outflow": "135.0",
"outflow": "397.8",
"volume": 10.12,
"maxVolume": 12.8,
"navigationForbidden": false,
"lat": 49.638,
"lng": 14.258,
"sparkline": [
282.94,
282.97,
282.96,
282.97,
282.96,
@@ -315,7 +324,9 @@
283.09,
283.13,
283.12,
283.1
283.1,
282.97,
282.99
]
},
{
@@ -323,18 +334,17 @@
"name": "Vrané",
"river": "",
"priority": false,
"level": "199.47",
"level": "199.50",
"capacity": 85.5,
"storageDiff": -0.63,
"storageDiff": -0.6,
"inflow": "45.0",
"outflow": "39.5",
"volume": 9.49,
"maxVolume": 11.1,
"navigationForbidden": false,
"lat": 49.939,
"lng": 14.391,
"sparkline": [
199.79,
199.71,
199.65,
199.57,
199.51,
@@ -344,7 +354,9 @@
199.44,
199.42,
199.45,
199.47
199.47,
199.48,
199.5
]
},
{
@@ -356,16 +368,17 @@
"capacity": 42.8,
"storageDiff": -1.04,
"inflow": "0.9",
"outflow": "0.6",
"outflow": "0.7",
"volume": 2.44,
"maxVolume": 5.7,
"navigationForbidden": true,
"lat": 49.027,
"lng": 13.987,
"sparkline": [
521.28,
521.28,
521.28,
521.28,
521.29,
521.29,
521.29,
521.29,
521.29,
@@ -385,9 +398,10 @@
"capacity": 95.9,
"storageDiff": -1.2,
"inflow": "0.7",
"outflow": "0.0",
"outflow": "0.7",
"volume": 15.35,
"maxVolume": 16,
"navigationForbidden": true,
"lat": 49.261,
"lng": 13.123,
"sparkline": [
@@ -417,6 +431,7 @@
"outflow": "0.0",
"volume": 7.49,
"maxVolume": 9.3,
"navigationForbidden": true,
"lat": 50.063,
"lng": 13.931,
"sparkline": [
@@ -446,11 +461,10 @@
"outflow": "1.5",
"volume": 0.66,
"maxVolume": 1.5,
"navigationForbidden": false,
"lat": 49.754,
"lng": 13.564,
"sparkline": [
345.05,
345.04,
345.03,
345.03,
345.02,
@@ -460,6 +474,8 @@
345.01,
345.01,
345,
345,
345,
345
]
},
@@ -468,18 +484,17 @@
"name": "České Údolí",
"river": "",
"priority": false,
"level": "0.00",
"level": "313.39",
"capacity": 52.7,
"storageDiff": 0,
"storageDiff": -0.21,
"inflow": "1.3",
"outflow": "3.0",
"outflow": "2.8",
"volume": 2.9,
"maxVolume": 5.5,
"navigationForbidden": false,
"lat": 49.715,
"lng": 13.364,
"sparkline": [
313.42,
313.41,
313.41,
313.41,
313.4,
@@ -489,7 +504,9 @@
313.39,
313.39,
0,
0
313.39,
313.39,
313.39
]
},
{
@@ -504,13 +521,14 @@
"outflow": "0.3",
"volume": 5.16,
"maxVolume": 5.6,
"navigationForbidden": false,
"lat": 49.526,
"lng": 15.195,
"sparkline": [
412.8,
412.79,
412.8,
412.8,
412.79,
412.8,
412.8,
412.8,
@@ -530,14 +548,13 @@
"capacity": 86.8,
"storageDiff": -0.38,
"inflow": "1.1",
"outflow": "0.2",
"outflow": "0.0",
"volume": 1.65,
"maxVolume": 1.9,
"navigationForbidden": false,
"lat": 49.507,
"lng": 15.263,
"sparkline": [
446.99,
446.99,
447,
447.01,
447.01,
@@ -547,6 +564,8 @@
447.02,
447.02,
447.02,
447.02,
447.02,
447.02
]
},
@@ -559,9 +578,10 @@
"capacity": 100,
"storageDiff": -1.4,
"inflow": "0.5",
"outflow": "0.0",
"outflow": "0.5",
"volume": 2.94,
"maxVolume": 2.3,
"navigationForbidden": true,
"lat": 49.805,
"lng": 12.639,
"sparkline": [
@@ -591,6 +611,7 @@
"outflow": "0.2",
"volume": 9.32,
"maxVolume": 14.5,
"navigationForbidden": true,
"lat": 50.093,
"lng": 13.136,
"sparkline": [
@@ -620,6 +641,7 @@
"outflow": "0.0",
"volume": 1.3,
"maxVolume": 1.6,
"navigationForbidden": true,
"lat": 49.691,
"lng": 13.957,
"sparkline": [
@@ -649,6 +671,7 @@
"outflow": "0.0",
"volume": 0.73,
"maxVolume": 0.8,
"navigationForbidden": true,
"lat": 49.664,
"lng": 13.882,
"sparkline": [
@@ -678,6 +701,7 @@
"outflow": "0.0",
"volume": 0.46,
"maxVolume": 0.6,
"navigationForbidden": true,
"lat": 49.711,
"lng": 13.937,
"sparkline": [
@@ -685,13 +709,13 @@
563.67,
563.67,
563.67,
0,
0,
0,
0,
563.67,
563.67,
563.67,
0,
0,
0,
0,
0
]
},
@@ -700,18 +724,17 @@
"name": "Strž",
"river": "",
"priority": false,
"level": "0.00",
"level": "588.42",
"capacity": 33,
"storageDiff": 0,
"storageDiff": -0.18,
"inflow": "0.0",
"outflow": "0.1",
"volume": 0.33,
"maxVolume": 1,
"navigationForbidden": false,
"lat": 49.791,
"lng": 14.004,
"sparkline": [
588.43,
588.43,
588.43,
588.42,
588.42,
@@ -721,7 +744,9 @@
588.42,
588.42,
0,
0
588.42,
588.42,
588.42
]
},
{
@@ -736,6 +761,7 @@
"outflow": "0.0",
"volume": 0.14,
"maxVolume": 0.5,
"navigationForbidden": false,
"lat": 49.507,
"lng": 15.244,
"sparkline": [
@@ -758,17 +784,17 @@
"name": "Soběnov",
"river": "",
"priority": false,
"level": "581.37",
"level": "581.35",
"capacity": 2.9,
"storageDiff": -0.84,
"storageDiff": -0.86,
"inflow": "0.0",
"outflow": "0.0",
"volume": 0.04,
"maxVolume": 1.4,
"navigationForbidden": false,
"lat": 48.775,
"lng": 14.536,
"sparkline": [
581.49,
581.45,
581.51,
581.58,
@@ -779,7 +805,8 @@
581.39,
581.39,
581.38,
581.37
581.37,
581.35
]
},
{
@@ -794,12 +821,10 @@
"outflow": "0.1",
"volume": 0.09,
"maxVolume": 0.8,
"navigationForbidden": false,
"lat": 48.784,
"lng": 14.735,
"sparkline": [
534.6,
534.6,
534.6,
534.61,
534.61,
534.61,
@@ -808,6 +833,9 @@
534.61,
534.61,
0,
534.62,
534.62,
534.62,
0
]
},
@@ -823,6 +851,7 @@
"outflow": "0.1",
"volume": 0.41,
"maxVolume": 1.2,
"navigationForbidden": true,
"lat": 49.575,
"lng": 15.952,
"sparkline": [
@@ -833,10 +862,10 @@
580.54,
580.54,
580.54,
580.54,
580.54,
580.54,
0,
580.54,
580.54,
580.54,
0
]
},
@@ -852,6 +881,7 @@
"outflow": "0.0",
"volume": 1.07,
"maxVolume": 1.5,
"navigationForbidden": false,
"lat": 49.593,
"lng": 15.932,
"sparkline": [
@@ -881,6 +911,7 @@
"outflow": "0.1",
"volume": 0.41,
"maxVolume": 0.7,
"navigationForbidden": false,
"lat": 49.897,
"lng": 14.058,
"sparkline": [
@@ -910,12 +941,13 @@
"outflow": "0.0",
"volume": 0.67,
"maxVolume": 0.5,
"navigationForbidden": false,
"lat": 49.805,
"lng": 13.851,
"sparkline": [
448.83,
448.83,
448.83,
448.82,
448.82,
448.82,
448.82,
448.82,
448.82,
@@ -939,6 +971,7 @@
"outflow": "0.0",
"volume": 0,
"maxVolume": 0.3,
"navigationForbidden": false,
"lat": 49.167,
"lng": 14.041,
"sparkline": [
@@ -968,6 +1001,7 @@
"outflow": "0.0",
"volume": 0.39,
"maxVolume": 0.3,
"navigationForbidden": false,
"lat": 48.974,
"lng": 14.545,
"sparkline": [
@@ -997,6 +1031,7 @@
"outflow": "0.0",
"volume": 0.84,
"maxVolume": 0.4,
"navigationForbidden": false,
"lat": 49.771,
"lng": 15.176,
"sparkline": [
@@ -1026,6 +1061,7 @@
"outflow": "0.0",
"volume": 0.16,
"maxVolume": 0.2,
"navigationForbidden": true,
"lat": 49.231,
"lng": 15.312,
"sparkline": [
@@ -1055,6 +1091,7 @@
"outflow": "0.0",
"volume": 0,
"maxVolume": 0.5,
"navigationForbidden": true,
"lat": 49.664,
"lng": 13.753,
"sparkline": [
@@ -1084,6 +1121,7 @@
"outflow": "0.0",
"volume": 0,
"maxVolume": 0.7,
"navigationForbidden": true,
"lat": 49.655,
"lng": 13.761,
"sparkline": [
@@ -1113,6 +1151,7 @@
"outflow": "0.0",
"volume": 0.09,
"maxVolume": 0.1,
"navigationForbidden": false,
"lat": 49.805,
"lng": 13.855,
"sparkline": [
+1
View File
@@ -68,6 +68,7 @@ const lakes = lakesConfig.map(lake => {
outflow: currentFlow.toFixed(1),
volume: metrics.volume,
maxVolume: lake.maxVolume || 0,
navigationForbidden: lake.navigationForbidden || false,
lat: lake.coords[0],
lng: lake.coords[1],
sparkline
+2
View File
@@ -7,6 +7,7 @@ import FavoritesOverview from './components/FavoritesOverview';
import Sidebar from './components/Sidebar';
import Topbar from './components/Topbar';
import SettingsModal from './components/SettingsModal';
import { DisclaimerModal } from './components/DisclaimerModal';
import { type Language, t } from './translations';
import { lakesConfig } from '../scripts/lakesConfig';
import { slugify } from './utils/slugify';
@@ -58,6 +59,7 @@ function App() {
return (
<div className="dashboard-container">
<DisclaimerModal language={language} setLanguage={setLanguage} />
{/* Mobile overlay */}
{isMobileMenuOpen && (
<div
+127
View File
@@ -0,0 +1,127 @@
import { useState, useEffect } from 'react';
import { type Language, t } from '../translations';
import { TbSwimming, TbSailboat } from 'react-icons/tb';
interface Props {
language: Language;
setLanguage: (lang: Language) => void;
}
export const DisclaimerModal = ({ language, setLanguage }: Props) => {
const [show, setShow] = useState(false);
useEffect(() => {
const isAccepted = localStorage.getItem('hladinator_disclaimer_accepted');
if (!isAccepted) {
setShow(true);
}
}, []);
const handleAccept = () => {
localStorage.setItem('hladinator_disclaimer_accepted', 'true');
setShow(false);
};
if (!show) return null;
return (
<div style={{
position: 'fixed', top: 0, left: 0, right: 0, bottom: 0,
backgroundColor: 'rgba(0,0,0,0.8)',
display: 'flex', alignItems: 'center', justifyContent: 'center',
zIndex: 999999, padding: '1.5rem', backdropFilter: 'blur(4px)'
}}>
<div style={{
backgroundColor: 'var(--bg-card)',
borderRadius: '12px',
padding: '2rem',
maxWidth: '550px',
width: '100%',
boxShadow: '0 10px 30px rgba(0,0,0,0.5)',
display: 'flex', flexDirection: 'column', gap: '1.5rem',
border: '1px solid var(--border-color)',
color: 'var(--text-main)',
maxHeight: '90vh',
overflowY: 'auto'
}}>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: '1rem', flexWrap: 'wrap' }}>
<h2 style={{ fontSize: '1.5rem', fontWeight: 'bold', margin: 0, color: 'var(--color-cyan)' }}>
{t[language].disclaimer.title}
</h2>
<div style={{ display: 'flex', gap: '0.25rem', backgroundColor: 'rgba(0,0,0,0.2)', padding: '4px', borderRadius: '8px' }}>
<button
onClick={() => setLanguage('cs')}
style={{ background: language === 'cs' ? 'var(--color-cyan)' : 'transparent', color: language === 'cs' ? '#fff' : 'var(--text-muted)', border: 'none', padding: '4px 8px', borderRadius: '4px', cursor: 'pointer', fontWeight: 'bold', transition: '0.2s' }}
>
CS
</button>
<button
onClick={() => setLanguage('en')}
style={{ background: language === 'en' ? 'var(--color-cyan)' : 'transparent', color: language === 'en' ? '#fff' : 'var(--text-muted)', border: 'none', padding: '4px 8px', borderRadius: '4px', cursor: 'pointer', fontWeight: 'bold', transition: '0.2s' }}
>
EN
</button>
</div>
</div>
<p style={{ margin: 0, lineHeight: 1.5 }}>
{t[language].disclaimer.text1}
</p>
<p style={{ margin: 0, lineHeight: 1.5, color: 'var(--text-muted)' }}>
{t[language].disclaimer.text2}
</p>
<div style={{
marginTop: '0.5rem', padding: '1rem',
backgroundColor: 'rgba(255,255,255,0.03)',
borderRadius: '8px', display: 'flex', flexDirection: 'column', gap: '1rem'
}}>
<div style={{ display: 'flex', gap: '1rem', alignItems: 'flex-start' }}>
<div style={{ display: 'flex', gap: '0.25rem', marginTop: '0.25rem' }}>
<TbSwimming size={24} color="var(--color-green)" />
<TbSailboat size={24} color="var(--color-green)" />
</div>
<div style={{ fontSize: '0.9rem', color: 'var(--text-muted)', lineHeight: 1.4 }}>
<div style={{ color: 'var(--text-main)', fontWeight: 'bold', marginBottom: '0.2rem' }}>{language === 'cs' ? 'Zelené ikony (Povoleno)' : 'Green icons (Allowed)'}</div>
<ul style={{ margin: 0, paddingLeft: '1.2rem' }}>
<li>{t[language].disclaimer.swimDesc}</li>
<li>{t[language].disclaimer.sailDesc}</li>
</ul>
</div>
</div>
<div style={{ display: 'flex', gap: '1rem', alignItems: 'flex-start' }}>
<div style={{ display: 'flex', gap: '0.25rem', marginTop: '0.25rem' }}>
<TbSwimming size={24} color="var(--color-red)" />
<TbSailboat size={24} color="var(--color-red)" />
</div>
<div style={{ fontSize: '0.9rem', color: 'var(--text-muted)', lineHeight: 1.4 }}>
<div style={{ color: 'var(--text-main)', fontWeight: 'bold', marginBottom: '0.2rem' }}>{language === 'cs' ? 'Červené ikony (Zakázáno)' : 'Red icons (Forbidden)'}</div>
{t[language].disclaimer.forbiddenDesc}
</div>
</div>
</div>
<button
onClick={handleAccept}
style={{
marginTop: '1rem',
padding: '1rem',
backgroundColor: 'var(--color-cyan)',
color: '#fff',
border: 'none',
borderRadius: '8px',
fontSize: '1.1rem',
fontWeight: 'bold',
cursor: 'pointer',
transition: 'opacity 0.2s'
}}
onMouseOver={(e) => e.currentTarget.style.opacity = '0.9'}
onMouseOut={(e) => e.currentTarget.style.opacity = '1'}
>
{t[language].disclaimer.button}
</button>
</div>
</div>
);
};
+14 -1
View File
@@ -8,6 +8,8 @@ import { useNavigate } from 'react-router-dom';
import { slugify } from '../utils/slugify';
import { AreaChart, Area, ResponsiveContainer, YAxis } from 'recharts';
import { FiTrendingUp, FiTrendingDown } from 'react-icons/fi';
import { TbSwimming, TbSailboat } from 'react-icons/tb';
import { Tooltip } from './Tooltip';
interface Lake {
id: string;
@@ -21,6 +23,7 @@ interface Lake {
outflow: number;
volume: number;
maxVolume: number;
navigationForbidden: boolean;
sparkline: number[];
}
@@ -119,9 +122,19 @@ const FavoritesOverview = ({ language }: Props) => {
<FiStar size={18} fill="#f59e0b" />
</button>
<h3 style={{ fontSize: '1.25rem', fontWeight: 'bold', margin: 0, paddingRight: '2rem' }}>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', paddingRight: '2rem' }}>
<h3 style={{ fontSize: '1.25rem', fontWeight: 'bold', margin: 0 }}>
{lake.name} {lake.river ? `- ${lake.river}` : ''}
</h3>
<div style={{ display: 'flex', gap: '0.4rem', flexShrink: 0 }}>
<Tooltip content={lake.navigationForbidden ? (language === 'cs' ? 'Koupání zakázáno' : 'Swimming forbidden') : (language === 'cs' ? 'Koupání (bez omezení)' : 'Swimming allowed')}>
<TbSwimming size={20} color={lake.navigationForbidden ? 'var(--color-red)' : 'var(--color-green)'} style={{ opacity: lake.navigationForbidden ? 0.5 : 0.8 }} />
</Tooltip>
<Tooltip content={lake.navigationForbidden ? (language === 'cs' ? 'Plavba zakázána' : 'Navigation forbidden') : (language === 'cs' ? 'Plavba (i bezmotorová) povolena' : 'Navigation allowed')}>
<TbSailboat size={20} color={lake.navigationForbidden ? 'var(--color-red)' : 'var(--color-green)'} style={{ opacity: lake.navigationForbidden ? 0.5 : 0.8 }} />
</Tooltip>
</div>
</div>
<div style={{ display: 'flex', alignItems: 'center', gap: '1rem', marginBottom: '1rem' }}>
<CircularProgress value={lake.capacity} size={70} strokeWidth={6} />
+11
View File
@@ -8,7 +8,9 @@ import { WindChart } from './WindChart';
import { NAVIGATION_LIMITS } from '../utils/navigationLimits';
import { lakesConfig } from '../../scripts/lakesConfig';
import { FiAlertCircle, FiStar } from 'react-icons/fi';
import { TbSwimming, TbSailboat } from 'react-icons/tb';
import { useFavorites } from '../hooks/useFavorites';
import { Tooltip as IconTooltip } from './Tooltip';
interface LipnoData {
timestamp: string;
@@ -283,6 +285,15 @@ const LakeDetail = ({ language, lakeId, windUnit = 'kmh' }: Props) => {
>
<FiStar size={24} fill={isFav ? '#f59e0b' : 'none'} color={isFav ? '#f59e0b' : 'var(--text-muted)'} />
</button>
<div style={{ display: 'flex', gap: '0.5rem', marginLeft: 'auto' }}>
<IconTooltip content={(lakeInfo as any).navigationForbidden ? (language === 'cs' ? 'Koupání zakázáno' : 'Swimming forbidden') : (language === 'cs' ? 'Koupání (bez omezení)' : 'Swimming allowed')}>
<TbSwimming size={24} color={(lakeInfo as any).navigationForbidden ? 'var(--color-red)' : 'var(--color-green)'} style={{ opacity: (lakeInfo as any).navigationForbidden ? 0.5 : 0.8 }} />
</IconTooltip>
<IconTooltip content={(lakeInfo as any).navigationForbidden ? (language === 'cs' ? 'Plavba zakázána' : 'Navigation forbidden') : (language === 'cs' ? 'Plavba (i bezmotorová) povolena' : 'Navigation allowed')}>
<TbSailboat size={24} color={(lakeInfo as any).navigationForbidden ? 'var(--color-red)' : 'var(--color-green)'} style={{ opacity: (lakeInfo as any).navigationForbidden ? 0.5 : 0.8 }} />
</IconTooltip>
</div>
</div>
<p style={{ margin: 0, color: 'var(--text-muted)', fontSize: '0.95rem', lineHeight: '1.5' }}>
{t[language].seo.lakeDesc.replace('{name}', lakeInfo.name)}
+16 -1
View File
@@ -7,6 +7,8 @@ import { useNavigate } from 'react-router-dom';
import { slugify } from '../utils/slugify';
import { useFavorites } from '../hooks/useFavorites';
import { CircularProgress } from './CircularProgress';
import { Tooltip } from './Tooltip';
import { TbSwimming, TbSailboat } from 'react-icons/tb';
interface Lake {
id: string;
@@ -20,6 +22,7 @@ interface Lake {
outflow: number;
volume: number;
maxVolume: number;
navigationForbidden: boolean;
sparkline: number[];
}
@@ -72,7 +75,19 @@ const LakeCard = ({ lake, language, isFav, onToggleFav }: { lake: Lake, language
<FiStar size={18} fill={isFav ? '#f59e0b' : 'none'} />
</button>
<h3 style={{ fontSize: '1.25rem', fontWeight: 'bold', margin: 0, paddingRight: '2rem' }}>{lake.name} {lake.river ? `- ${lake.river}` : ''}</h3>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', paddingRight: '2rem' }}>
<h3 style={{ fontSize: '1.25rem', fontWeight: 'bold', margin: 0 }}>
{lake.name} {lake.river ? `- ${lake.river}` : ''}
</h3>
<div style={{ display: 'flex', gap: '0.4rem', flexShrink: 0 }}>
<Tooltip content={lake.navigationForbidden ? (language === 'cs' ? 'Koupání zakázáno' : 'Swimming forbidden') : (language === 'cs' ? 'Koupání (bez omezení)' : 'Swimming allowed')}>
<TbSwimming size={20} color={lake.navigationForbidden ? 'var(--color-red)' : 'var(--color-green)'} style={{ opacity: lake.navigationForbidden ? 0.5 : 0.8 }} />
</Tooltip>
<Tooltip content={lake.navigationForbidden ? (language === 'cs' ? 'Plavba zakázána' : 'Navigation forbidden') : (language === 'cs' ? 'Plavba (i bezmotorová) povolena' : 'Navigation allowed')}>
<TbSailboat size={20} color={lake.navigationForbidden ? 'var(--color-red)' : 'var(--color-green)'} style={{ opacity: lake.navigationForbidden ? 0.5 : 0.8 }} />
</Tooltip>
</div>
</div>
<div style={{ display: 'flex', alignItems: 'center', gap: '1rem', marginBottom: '1rem' }}>
<CircularProgress value={lake.capacity} size={70} strokeWidth={6} />
+60
View File
@@ -0,0 +1,60 @@
import { useState, useRef, useEffect, type ReactNode } from 'react';
interface Props {
content: string;
children: ReactNode;
}
export const Tooltip = ({ content, children }: Props) => {
const [show, setShow] = useState(false);
const containerRef = useRef<HTMLDivElement>(null);
useEffect(() => {
const handleClickOutside = (e: MouseEvent) => {
if (containerRef.current && !containerRef.current.contains(e.target as Node)) {
setShow(false);
}
};
document.addEventListener('mousedown', handleClickOutside);
return () => document.removeEventListener('mousedown', handleClickOutside);
}, []);
return (
<div
ref={containerRef}
style={{ position: 'relative', display: 'inline-flex' }}
onMouseEnter={() => setShow(true)}
onMouseLeave={() => setShow(false)}
onClick={(e) => {
e.stopPropagation();
setShow(!show);
}}
>
{children}
{show && (
<div style={{
position: 'absolute',
bottom: '100%',
left: '50%',
transform: 'translateX(-50%)',
marginBottom: '8px',
backgroundColor: 'var(--bg-card)',
border: '1px solid var(--border-color)',
padding: '0.5rem 0.75rem',
borderRadius: '8px',
width: 'max-content',
maxWidth: '220px',
zIndex: 9999,
boxShadow: '0 4px 12px rgba(0,0,0,0.5)',
color: 'var(--text-main)',
fontSize: '0.8rem',
lineHeight: 1.4,
textAlign: 'center',
pointerEvents: 'none'
}}>
{content}
</div>
)}
</div>
);
};
+20 -2
View File
@@ -62,6 +62,15 @@ export const t = {
contact: 'Contact',
contactPlaceholder: 'Your email address',
buyCoffee: 'Buy Me a Coffee'
},
disclaimer: {
title: 'Important Notice',
text1: 'Data in this application (water levels, flows, navigation limits, and weather) are obtained from public sources and are purely for informational purposes.',
text2: 'The application does not serve as an official source for navigation, boating, recreation, or crisis management. We bear no responsibility for inaccuracies, delays, or data outages. For binding information and verification of restrictions, always contact the relevant authorities (e.g., State Navigation Administration).',
swimDesc: 'Swimming allowed (informational). May be restricted locally by hygiene stations.',
sailDesc: 'Navigation allowed (informational). May be restricted to non-motorized vessels.',
forbiddenDesc: 'Strictly forbidden. Usually a drinking water reservoir or nature reserve.',
button: 'I understand and agree'
}
},
cs: {
@@ -123,8 +132,17 @@ export const t = {
windUnitKmh: 'km/h',
windUnitMs: 'm/s',
contact: 'Kontakt',
contactPlaceholder: 'Vaše e-mailová adresa',
buyCoffee: 'Kup mi kávu'
contactPlaceholder: 'Váš e-mail',
buyCoffee: 'Kupte mi kávu'
},
disclaimer: {
title: 'Důležité upozornění',
text1: 'Data v této aplikaci (hladiny, průtoky, limity plavby a počasí) jsou získávána z veřejných zdrojů a mají čistě informativní charakter.',
text2: 'Aplikace neslouží jako oficiální zdroj pro navigaci, plavbu, rekreaci ani krizové řízení. Za případné nepřesnosti, zpoždění nebo výpadky dat neneseme žádnou odpovědnost. Pro závazné informace a ověření omezení vždy kontaktujte příslušné úřady (např. Státní plavební správu).',
swimDesc: 'Koupání obecně povoleno. Upozorňujeme na možné lokální zákazy z důvodu zhoršené kvality vody (sinice).',
sailDesc: 'Plavba obecně povolena. Typ plavidel (např. se spalovacím motorem) může být místně omezen vyhláškou SPS.',
forbiddenDesc: 'Přísný zákaz! Jedná se o vodárenskou nádrž (zdroj pitné vody) nebo přísně chráněnou přírodní rezervaci.',
button: 'Rozumím a souhlasím'
}
}
};