Complete source code for the Weather Dashboard built with Nahir UI and K2
This Weather Dashboard demonstrates how to build a data-driven application using Nahir UI, K2's component-based UI framework. The application includes:
The application uses Nahir UI's ramdisk caching to store weather data, reducing API calls and providing ultra-fast rendering even with large datasets.
# Weather Dashboard Example using Nahir UI import NahirUI import HTTP # API configuration const API_KEY = "your_api_key_here" const API_BASE_URL = "https://api.weatherapi.com/v1" # Weather Dashboard component component WeatherDashboard { state = { city: "New York", currentWeather: null, forecast: [], loading: false, error: null } # Initialize component function init() { fetchWeatherData(state.city) } # Fetch weather data from API function fetchWeatherData(city) { state.loading = true state.error = null updateState() # Check if data is in cache const cacheKey = "weather_" + city.toLowerCase() const cachedData = Cache.get(cacheKey) if (cachedData && Date.now() - cachedData.timestamp < 3600000) { # Use cached data if less than 1 hour old state.currentWeather = cachedData.currentWeather state.forecast = cachedData.forecast state.loading = false updateState() return } # Fetch from API if not in cache or cache is stale const url = `${API_BASE_URL}/forecast.json?key=${API_KEY}&q=${city}&days=5` HTTP.get(url) .then(function(response) { if (response.status == 200) { const data = response.json() # Parse current weather state.currentWeather = { temperature: data.current.temp_f, condition: data.current.condition.text, icon: getWeatherIcon(data.current.condition.code), humidity: data.current.humidity, wind: data.current.wind_mph, pressure: data.current.pressure_mb, uv: data.current.uv, location: data.location.name + ", " + data.location.country } # Parse forecast state.forecast = data.forecast.forecastday.map(function(day) { return { date: new Date(day.date).toLocaleDateString("en-US", { weekday: "short" }), icon: getWeatherIcon(day.day.condition.code), highTemp: day.day.maxtemp_f, lowTemp: day.day.mintemp_f } }) # Cache the data Cache.set(cacheKey, { currentWeather: state.currentWeather, forecast: state.forecast, timestamp: Date.now() }) state.loading = false updateState() } else { state.error = "Error fetching weather data" state.loading = false updateState() } }) .catch(function(error) { state.error = error.message state.loading = false updateState() }) } # Map weather condition code to icon function getWeatherIcon(code) { if (code == 1000) return "fa-sun" if (code >= 1003 && code <= 1009) return "fa-cloud-sun" if (code >= 1030 && code <= 1039) return "fa-smog" if (code >= 1063 && code <= 1069) return "fa-cloud-rain" if (code >= 1114 && code <= 1117) return "fa-snowflake" if (code >= 1135 && code <= 1147) return "fa-fog" if (code >= 1150 && code <= 1201) return "fa-cloud-showers-heavy" if (code >= 1204 && code <= 1237) return "fa-snowflake" if (code >= 1240 && code <= 1246) return "fa-cloud-rain" if (code >= 1249 && code <= 1264) return "fa-snowflake" if (code >= 1273 && code <= 1282) return "fa-bolt" return "fa-cloud" } # Handle search function handleSearch() { fetchWeatherData(state.city) } # Handle input change function handleInputChange(e) { state.city = e.target.value updateState() } # Update component state function updateState() { this.setState(state) } render { element = "div" className = "weather-app" children = [ # Header { element: "div", className: "weather-header", children: [ { element: "h2", content: "Weather Dashboard" }, { element: "span", content: "Powered by Nahir UI" } ] }, # Search { element: "div", className: "search-container", children: [ { element: "input", className: "search-input", placeholder: "Enter city name", value: state.city, onChange: handleInputChange }, { element: "button", className: "search-button", content: "Search", onClick: handleSearch } ] }, # Content { element: "div", className: "weather-content", children: state.loading ? [ # Loading state { element: "div", className: "loading", content: "Loading weather data..." } ] : state.error ? [ # Error state { element: "div", className: "error", content: state.error } ] : [ # Current weather { element: "div", className: "current-weather", children: [ { element: "div", className: "weather-icon", children: [ { element: "i", className: "fas " + state.currentWeather.icon } ] }, { element: "h2", className: "temperature", content: Math.round(state.currentWeather.temperature) + "°F" }, { element: "p", className: "weather-description", content: state.currentWeather.condition }, { element: "p", className: "location", content: state.currentWeather.location }, { element: "div", className: "weather-details", children: [ # Humidity { element: "div", className: "weather-detail", children: [ { element: "span", className: "detail-label", content: "Humidity" }, { element: "span", className: "detail-value", content: state.currentWeather.humidity + "%" } ] }, # Wind { element: "div", className: "weather-detail", children: [ { element: "span", className: "detail-label", content: "Wind" }, { element: "span", className: "detail-value", content: state.currentWeather.wind + " mph" } ] }, # Pressure { element: "div", className: "weather-detail", children: [ { element: "span", className: "detail-label", content: "Pressure" }, { element: "span", className: "detail-value", content: state.currentWeather.pressure + " hPa" } ] }, # UV Index { element: "div", className: "weather-detail", children: [ { element: "span", className: "detail-label", content: "UV Index" }, { element: "span", className: "detail-value", content: state.currentWeather.uv } ] } ] } ] }, # Forecast { element: "div", className: "forecast", children: state.forecast.map(function(day) { return { element: "div", className: "forecast-day", children: [ { element: "div", className: "forecast-date", content: day.date }, { element: "div", className: "forecast-icon", children: [ { element: "i", className: "fas " + day.icon } ] }, { element: "div", className: "forecast-temp", children: [ { element: "span", className: "forecast-high", content: Math.round(day.highTemp) + "°" }, { element: "span", className: "forecast-low", content: Math.round(day.lowTemp) + "°" } ] } ] } }) }, # Weather Map { element: "div", className: "weather-map", content: "Weather Map (Placeholder)" } ] } ] } } # Create and render the Weather Dashboard dashboard = WeatherDashboard.new() dashboard.init() UI.render(dashboard)
The Weather Dashboard is built using a single main component that handles all the functionality:
The Weather Dashboard uses several performance optimizations:
The caching system works as follows:
This approach significantly reduces API calls and improves application performance, especially for frequently accessed cities.
To run this example on your machine:
curl -sSL https://k2lang.org/install | bash
k2 install nahir-ui
weather_app.k2
your_api_key_here
with a valid API key from WeatherAPI.comk2 weather_app.k2
The application will open in a window, or if you're in a terminal-only environment, it will render as text UI.
Get started with Nahir UI and build ultra-fast user interfaces for your K2 applications.