"use client";
import { Box, Group, HoverCard, Stack, Text } from "@mantine/core";
import { IconArrowDownRight, IconArrowUpRight, IconMapPin, IconWind } from "@tabler/icons-react";
import combineClasses from "clsx";
import dayjs from "dayjs";
import type { RouterOutputs } from "@homarr/api";
import { clientApi } from "@homarr/api/client";
import { useScopedI18n } from "@homarr/translation/client";
import type { WidgetComponentProps } from "../definition";
import { WeatherDescription, WeatherIcon } from "./icon";
export default function WeatherWidget({ isEditMode, options }: WidgetComponentProps<"weather">) {
const [weather] = clientApi.widget.weather.atLocation.useSuspenseQuery(
{
latitude: options.location.latitude,
longitude: options.location.longitude,
},
{
refetchOnMount: false,
refetchOnWindowFocus: false,
refetchOnReconnect: false,
},
);
return (
{options.hasForecast ? (
) : (
)}
);
}
interface WeatherProps extends Pick, "options"> {
weather: RouterOutputs["widget"]["weather"]["atLocation"];
}
const DailyWeather = ({ options, weather }: WeatherProps) => {
const t = useScopedI18n("widget.weather");
return (
<>
{getPreferredUnit(
weather.current.temperature,
options.isFormatFahrenheit,
options.disableTemperatureDecimals,
)}
{options.showCurrentWindSpeed && (
{t("currentWindSpeed", { currentWindSpeed: String(weather.current.windspeed) })}
)}
{getPreferredUnit(
weather.daily[0]?.maxTemp,
options.isFormatFahrenheit,
options.disableTemperatureDecimals,
)}
{getPreferredUnit(
weather.daily[0]?.minTemp,
options.isFormatFahrenheit,
options.disableTemperatureDecimals,
)}
{options.showCity && (
<>
{options.location.name}
>
)}
>
);
};
const WeeklyForecast = ({ options, weather }: WeatherProps) => {
return (
<>
{options.showCity && (
{options.location.name}
)}
{getPreferredUnit(
weather.current.temperature,
options.isFormatFahrenheit,
options.disableTemperatureDecimals,
)}
>
);
};
function Forecast({ weather, options }: WeatherProps) {
const dateFormat = options.dateFormat;
return (
{weather.daily.slice(0, options.forecastDayCount).map((dayWeather, index) => (
{dayjs(dayWeather.time).format("dd")}
{getPreferredUnit(dayWeather.maxTemp, options.isFormatFahrenheit, options.disableTemperatureDecimals)}
))}
);
}
const getPreferredUnit = (value?: number, isFahrenheit = false, disableTemperatureDecimals = false): string =>
value
? isFahrenheit
? `${(value * (9 / 5) + 32).toFixed(disableTemperatureDecimals ? 0 : 1)}°F`
: `${value.toFixed(disableTemperatureDecimals ? 0 : 1)}°C`
: "?";