import { createEffect, createResource, createSignal, For, Show } from "solid-js"; import { MapView } from "../../components/map/MapView"; import { apiHost, ResultKeyVal } from "../../consts"; import { LoadingSpinner } from "../../components/spinner/LoadingSpinner"; import { faktiskaExport, faktiskaStations, FaktiskaStation } from "./faktiskaConfig"; import type { FaktiskaTemplate } from "./faktiskaTemplates"; import "./mapGraphics.css"; type LatestTemperature = { city: FaktiskaStation; observedAt: string; value: number | null }; const emptyValues = (): Record => Object.fromEntries(faktiskaStations.map(city => [city, ""])) as Record; export function Faktiska() { const [values, setValues] = createSignal(emptyValues()); const [overrides, setOverrides] = createSignal>(new Set()); const [template, setTemplate] = createSignal(faktiskaExport.defaultTemplate); const productionSize = () => template() === "faktiska_1920x1080" ? { width: 1920, height: 1080 } : { width: 3840, height: 1440 }; const fetchLatest = async (): Promise => { const response = await fetch(`${apiHost}/api/query/latest-temperatures/${faktiskaStations.join(",")}`); if (!response.ok) throw new Error(`Latest observations failed (${response.status})`); return response.json(); }; const [latest, { refetch }] = createResource(fetchLatest); createEffect(() => { const observations = latest(); if (!observations) return; const next = emptyValues(); observations.forEach(observation => { next[observation.city] = observation.value == null ? "" : observation.value.toString(); }); setValues(next); setOverrides(new Set()); }); const observationsByCity = () => new Map((latest() ?? []).map(item => [item.city, item])); const newestTimestamp = () => { const timestamps = (latest() ?? []).map(item => Date.parse(item.observedAt)).filter(Number.isFinite); return timestamps.length ? new Date(Math.max(...timestamps)) : undefined; }; const isStale = (city: FaktiskaStation) => { const newest = newestTimestamp(); const observed = observationsByCity().get(city)?.observedAt; return Boolean(newest && observed && newest.getTime() - Date.parse(observed) > 90 * 60 * 1000); }; const cityData = (): ResultKeyVal[] => faktiskaStations.flatMap(city => { const value = Number(values()[city].replace(",", ".")); return values()[city].trim() && Number.isFinite(value) ? [[city, value] as ResultKeyVal] : []; }); const updateValue = (city: FaktiskaStation, value: string) => { setValues(current => ({ ...current, [city]: value })); setOverrides(current => new Set(current).add(city)); }; const resetValue = (city: FaktiskaStation) => { const observation = observationsByCity().get(city); setValues(current => ({ ...current, [city]: observation?.value == null ? "" : observation.value.toString() })); setOverrides(current => { const next = new Set(current); next.delete(city); return next; }); }; return
Daily newsroom production

Faktiskā

Current temperatures with manually prepared weather symbols and wind.

{productionSize().width} × {productionSize().height} PNG
1. Latest temperatures{newestTimestamp() ? newestTimestamp()!.toLocaleString("lv-LV") : "Waiting for observations"}Newest available reading in the configured station set
Could not load observations. Existing manual fields remain available.
{city => { const observation = () => observationsByCity().get(city); return ; }}

2. Add weather symbols and wind, then export

{currentTemplate => }
; }