diff --git a/web/src/App.tsx b/web/src/App.tsx index 6d9a1c0..d348a12 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -11,7 +11,7 @@ import { WeatherIconStub } from './components/weatherIcons/WeatherIconStub'; import { Harmonie } from './pages/harmonie/Harmonie' import { LvgmcForecast } from './pages/lvgmc-forecast/LvgmcForecast' import { Home } from './pages/home/Home' -import { MapGraphics } from './pages/map-graphics/MapGraphics' +import { Faktiska } from './pages/map-graphics/MapGraphics' console.log("env:", import.meta.env.MODE) console.log("api host:", apiHost) @@ -24,7 +24,7 @@ const App: Component = () => { - + @@ -33,7 +33,7 @@ const App: Component = () => { const AppLayout: ParentComponent = (props) => { const pages = [ - ['/station', 'Stations'], ['/cities', 'City analysis'], ['/map-graphics', 'Map graphics'], ['/latvia', 'Latvia overview'], + ['/station', 'Stations'], ['/cities', 'City analysis'], ['/faktiska', 'Faktiskā'], ['/latvia', 'Latvia overview'], ['/database', 'Data archive'], ['/harmonie', 'HARMONIE'], ['/lvgmc-forecast', 'LVĢMC forecast'], ] return ( diff --git a/web/src/components/weatherIcons/IconInputs.tsx b/web/src/components/weatherIcons/IconInputs.tsx index e364e81..8e26902 100644 --- a/web/src/components/weatherIcons/IconInputs.tsx +++ b/web/src/components/weatherIcons/IconInputs.tsx @@ -10,8 +10,9 @@ export const IconInputs: Component<{cities: string[]; weatherIconsSignal: Signal const applyAll = () => setIcons(Object.fromEntries(props.cities.map(city => [city, selected()]))); return
-
Weather symbols

Select a font symbol, apply it to all cities, then change the exceptions.

-
{icon => }
-
{city =>
{city}
}
+
Weather symbols

Choose one symbol, apply it broadly, then update the exceptions below.

{selected()}
+
{icon => }
+
City assignmentsUse the selected symbol for each exception.
+
{city =>
{city}{icons()[city]}
}
; }; diff --git a/web/src/css/weatherIcons.css b/web/src/css/weatherIcons.css index a9ac486..0ee79d6 100644 --- a/web/src/css/weatherIcons.css +++ b/web/src/css/weatherIcons.css @@ -1,16 +1,15 @@ .weatherIconButton { font-family: 'Daira by LTV grafika'; font-size: 30px; - display: inline-block; - background-color: #ccc; - padding: 3px 4px; - margin: 0 3px; + display:inline-flex;align-items:center;justify-content:center; + width:46px;height:46px;min-height:46px; + background:#f4f6f8;border:1px solid #d9e0e8;border-radius:10px; + padding:0;margin:0; cursor: pointer; } .weatherIconButton:hover { - background-color: #333; - color: white; + background:#e9eef4;border-color:#aebccc;color:#17212d; } .weatherIconInput { @@ -23,4 +22,5 @@ font-size: 20px; color: white; } -.weatherIconButton.selected{background:var(--accent);color:#fff;box-shadow:0 0 0 2px var(--accent-pale)} +.weatherIconButton.selected{background:#17212d;border-color:#17212d;color:#fff;box-shadow:0 0 0 3px var(--accent-pale)} +.weatherIconButton:focus-visible{outline:3px solid var(--accent-soft);outline-offset:2px} diff --git a/web/src/pages/cities/result/ResultView.tsx b/web/src/pages/cities/result/ResultView.tsx index 3dc2d20..bb9f7f7 100644 --- a/web/src/pages/cities/result/ResultView.tsx +++ b/web/src/pages/cities/result/ResultView.tsx @@ -5,10 +5,11 @@ import { ResultKeyVal, resultOrder, ResultOrderKeys } from "../../../consts"; import { SelectOrder } from "../SelectOrder"; import { QueryResult } from "../helpers"; import { GridResult } from "./GridResult"; +import { MapView } from "../../../components/map/MapView"; -type ResultView = "grid" | "list"; -const resultViews: Array = ["grid", "list"]; -const viewLabels: Record = {grid:'grid',list:'list'} +type ResultView = "grid" | "list" | "map_1920x1080" | "map_1920x1080_wind" | "map_3840x1440" | "map_3840x1440_wind"; +const resultViews: Array = ["grid", "list", "map_1920x1080", "map_1920x1080_wind", "map_3840x1440", "map_3840x1440_wind"]; +const viewLabels: Record = {grid:'grid',list:'list',map_1920x1080:'map_1920x1080',map_1920x1080_wind:'map_1920x1080_wind',map_3840x1440:'map_3840x1440',map_3840x1440_wind:'map_3840x1440_wind'} export const ResultView: Component<{ result: Resource @@ -72,6 +73,10 @@ export const ResultView: Component<{ />)} + + + + ); diff --git a/web/src/pages/home/Home.tsx b/web/src/pages/home/Home.tsx index d0e4be0..8ad5511 100644 --- a/web/src/pages/home/Home.tsx +++ b/web/src/pages/home/Home.tsx @@ -3,8 +3,8 @@ import './home.css' const tools = [ ['/station','Monitor','Stations','Inspect recent measurements on a map and open detailed station charts.','◉'], - ['/cities','Analyse & export','City analysis','Compare cities, aggregate values, and prepare map graphics.','▦'], - ['/map-graphics','Produce','Map graphics','Build temperature and Faktiskā newsroom graphics with export-ready overlays.','▣'], + ['/cities','Analyse & export','City analysis','Compare cities, aggregate values, and prepare temperature maps.','▦'], + ['/faktiska','Daily production','Faktiskā','Build the actual-weather map with temperatures, weather symbols, title, and source.','▣'], ['/latvia','Summarise','Latvia overview','Review country-wide minimum, maximum, average, and total values.','⌁'], ['/database','Browse','Data archive','Find available dates and inspect individual hourly records.','▤'], ['/harmonie','Forecast model','HARMONIE','Render forecast fields from locally stored HARMONIE GRIB files.','◫'], diff --git a/web/src/pages/map-graphics/MapGraphics.tsx b/web/src/pages/map-graphics/MapGraphics.tsx index 34c14bb..2ed610a 100644 --- a/web/src/pages/map-graphics/MapGraphics.tsx +++ b/web/src/pages/map-graphics/MapGraphics.tsx @@ -9,14 +9,13 @@ import { isQueryResult, QueryResult } from "../cities/helpers"; import { LoadingSpinner } from "../../components/spinner/LoadingSpinner"; import "./mapGraphics.css"; -export function MapGraphics() { +export function Faktiska() { const now = new Date(new Date().setMinutes(30)); const [cities, setCities] = createSignal>(new Set()); const [start, setStart] = createSignal(moment(now).subtract(1, "day").toDate()); const [end, setEnd] = createSignal(now); const [field, setField] = createSignal("tempMax"); const [key, setKey] = createSignal("max"); - const [mode, setMode] = createSignal<"temperature" | "faktiska">("faktiska"); const [resolution, setResolution] = createSignal<"1920x1080" | "3840x1440">("1920x1080"); const [wind, setWind] = createSignal(false); const [trigger, setTrigger] = createSignal(0); @@ -35,18 +34,17 @@ export function MapGraphics() { const cityData = (): ResultKeyVal[] => Object.entries((result() as QueryResult).result).map(([city, value]) => [city, typeof value === "number" ? value : -99]); return
-
Newsroom production

Map graphics

Create a temperature map or Faktiskā weather map and export the finished PNG.

{cities().size} cities selected
+
Daily newsroom production

Faktiskā

Create the actual-weather map with temperatures and weather symbols.

{cities().size} cities selected
-

2. Choose graphic

-
Graphic type
+

2. Choose output

Output

3. Retrieve temperatures

Could not load map data{result.error.message}
-

4. Finish and export

+

4. Add conditions and export

Choose cities and load dataThe production controls and map preview will appear here.
diff --git a/web/src/pages/map-graphics/mapGraphics.css b/web/src/pages/map-graphics/mapGraphics.css index 8401627..de18adf 100644 --- a/web/src/pages/map-graphics/mapGraphics.css +++ b/web/src/pages/map-graphics/mapGraphics.css @@ -1 +1,2 @@ .graphicsSetup{display:grid;grid-template-columns:240px minmax(0,1fr);gap:18px;align-items:start}.graphicsMain{display:grid;gap:18px}.productionOptions,.dataOptions{padding:20px}.choiceGroup{display:grid;grid-template-columns:130px 1fr;gap:16px;align-items:start;margin-top:16px}.choiceGroup>span,.dataOptions label>span{display:block;font-size:12px;font-weight:700}.choiceGroup>div{display:flex;flex-wrap:wrap;gap:9px}.choiceGroup button{min-width:150px;text-align:left}.choiceGroup button small{display:block;margin-top:3px;color:var(--text-muted);font-family:Inter,sans-serif}.choiceGroup button.active{border-color:var(--accent);background:var(--accent-pale);color:var(--accent-strong)}.windChoice{display:flex;align-items:center;gap:7px;padding:9px 12px}.dataOptionsGrid{display:grid;grid-template-columns:minmax(250px,1.4fr) 1fr 1fr;gap:18px;align-items:end;margin-bottom:16px}.dataOptions select{width:100%;margin-top:6px}.mapProduction>h2{margin:0 0 10px}.symbolEditor{min-width:0}.symbolEditorHeading{display:flex;align-items:start;justify-content:space-between;gap:12px}.symbolPalette{display:flex;flex-wrap:wrap;gap:5px;margin:10px 0 16px}.citySymbols{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:8px}.citySymbolRow{display:grid;grid-template-columns:1fr 52px 54px;gap:6px;align-items:center;padding:7px;border:1px solid var(--border);border-radius:9px}.assignedSymbol{font-family:'Daira by LTV grafika';font-size:28px;padding:2px}.clearSymbol{padding:5px;font-size:11px}@media(max-width:900px){.graphicsSetup{grid-template-columns:1fr}.dataOptionsGrid{grid-template-columns:1fr}.choiceGroup{grid-template-columns:1fr}} +.symbolEditorHeading{gap:16px}.bulkSymbol{display:flex;align-items:center;gap:8px}.selectedPreview,.currentSymbol{display:flex;align-items:center;justify-content:center;font-family:'Daira by LTV grafika';font-size:30px}.selectedPreview{width:42px;height:42px;border-radius:9px;background:#17212d;color:#fff}.symbolPalette{display:grid;grid-template-columns:repeat(auto-fill,46px);gap:8px;margin:14px 0 22px;padding:14px;border:1px solid var(--border);border-radius:14px;background:var(--surface-soft)}.assignmentHeading{display:flex;align-items:baseline;gap:10px;margin-bottom:10px}.assignmentHeading span{color:var(--text-muted);font-size:12px}.citySymbols{grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:10px}.citySymbolRow{grid-template-columns:minmax(90px,1fr) 48px 100px 36px;gap:8px;min-height:62px;padding:8px 10px;border-radius:12px;background:#fff}.cityName{overflow:hidden;text-overflow:ellipsis;font-weight:700}.currentSymbol{width:44px;height:44px;border:1px solid #d7dfe8;border-radius:9px;background:#f6f8fa}.currentSymbol.empty{font-family:Inter,sans-serif;font-size:18px;color:#98a2b3}.assignAction{padding:7px 9px;font-size:12px}.clearSymbol{width:36px;padding:0;font-size:20px;color:var(--text-muted)}@media(max-width:900px){.symbolEditorHeading{flex-direction:column}.citySymbols{grid-template-columns:1fr}}