Files
Homarr/src/widgets/weather/WeatherTile.tsx

112 lines
3.4 KiB
TypeScript
Raw Normal View History

2022-12-17 00:28:46 +09:00
import { Center, Group, Skeleton, Stack, Text, Title } from '@mantine/core';
2022-12-18 21:21:23 +01:00
import { IconArrowDownRight, IconArrowUpRight, IconCloudRain } from '@tabler/icons';
import { HomarrCardWrapper } from '../../components/Dashboard/Tiles/HomarrCardWrapper';
import { BaseTileProps } from '../../components/Dashboard/Tiles/type';
2022-12-18 21:21:23 +01:00
import { WidgetsMenu } from '../../components/Dashboard/Tiles/Widgets/WidgetsMenu';
import { defineWidget } from '../helper';
import { IWidget } from '../widgets';
2022-12-10 22:14:31 +01:00
import { useWeatherForCity } from './useWeatherForCity';
import { WeatherIcon } from './WeatherIcon';
2022-12-10 22:14:31 +01:00
2022-12-18 21:21:23 +01:00
const definition = defineWidget({
id: 'weather',
icon: IconCloudRain,
options: {
displayInFahrenheit: {
type: 'switch',
defaultValue: false,
},
location: {
type: 'text',
defaultValue: 'Paris',
},
},
gridstack: {
minWidth: 4,
minHeight: 2,
maxWidth: 12,
maxHeight: 12,
},
2022-12-18 21:21:23 +01:00
component: WeatherTile,
});
export type IWeatherWidget = IWidget<typeof definition['id'], typeof definition>;
2022-12-10 22:14:31 +01:00
interface WeatherTileProps extends BaseTileProps {
2022-12-18 21:21:23 +01:00
module: IWeatherWidget;
2022-12-10 22:14:31 +01:00
}
2022-12-18 21:21:23 +01:00
function WeatherTile({ className, module }: WeatherTileProps) {
const { data: weather, isLoading, isError } = useWeatherForCity(module.properties.location);
2022-12-10 22:14:31 +01:00
if (isLoading) {
return (
<HomarrCardWrapper className={className}>
<Skeleton height={40} width={100} mb="xl" />
<Group noWrap>
<Skeleton height={50} circle />
<Group>
<Skeleton height={25} width={70} mr="lg" />
<Skeleton height={25} width={70} />
</Group>
</Group>
</HomarrCardWrapper>
);
}
if (isError) {
return (
<HomarrCardWrapper className={className}>
<Center>
<Text weight={500}>An error occured</Text>
</Center>
</HomarrCardWrapper>
);
}
// TODO: add widgetWrapper that is generic and uses the definition
2022-12-10 22:14:31 +01:00
return (
<HomarrCardWrapper className={className}>
<WidgetsMenu integration={definition.id} module={module} />
2022-12-10 22:14:31 +01:00
<Center style={{ height: '100%' }}>
2022-12-11 13:38:05 +01:00
<Group spacing="md" noWrap align="center">
2022-12-10 22:14:31 +01:00
<WeatherIcon code={weather!.current_weather.weathercode} />
<Stack p={0} spacing={4}>
<Title order={2}>
{getPerferedUnit(
weather!.current_weather.temperature,
2022-12-18 21:21:23 +01:00
module.properties.displayInFahrenheit
2022-12-10 22:14:31 +01:00
)}
</Title>
2022-12-11 13:38:05 +01:00
<Group spacing="xs" noWrap>
2022-12-10 22:14:31 +01:00
<div>
<span>
{getPerferedUnit(
weather!.daily.temperature_2m_max[0],
2022-12-18 21:21:23 +01:00
module.properties.displayInFahrenheit
2022-12-10 22:14:31 +01:00
)}
</span>
<IconArrowUpRight size={16} style={{ right: 15 }} />
</div>
<div>
<span>
{getPerferedUnit(
weather!.daily.temperature_2m_min[0],
2022-12-18 21:21:23 +01:00
module.properties.displayInFahrenheit
2022-12-10 22:14:31 +01:00
)}
</span>
<IconArrowDownRight size={16} />
</div>
</Group>
</Stack>
</Group>
</Center>
</HomarrCardWrapper>
);
2022-12-18 21:21:23 +01:00
}
2022-12-10 22:14:31 +01:00
2022-12-17 00:28:46 +09:00
const getPerferedUnit = (value: number, isFahrenheit = false): string =>
isFahrenheit ? `${(value * (9 / 5) + 32).toFixed(1)}°F` : `${value.toFixed(1)}°C`;
2022-12-18 21:21:23 +01:00
export default definition;