"use client"; import { Sparkline } from "@mantine/charts"; import { Flex, Stack, Text, Title, useMantineTheme } from "@mantine/core"; import { IconTrendingDown, IconTrendingUp } from "@tabler/icons-react"; import { clientApi } from "@homarr/api/client"; import { useScopedI18n } from "@homarr/translation/client"; import type { WidgetComponentProps } from "../definition"; function round(value: number) { return Math.round(value * 100) / 100; } function calculateChange(valueA: number, valueB: number) { return valueA - valueB; } function calculateChangePercentage(valueA: number, valueB: number) { return 100 * ((valueA - valueB) / valueA); } export default function StockPriceWidget({ options, width, height }: WidgetComponentProps<"stockPrice">) { const t = useScopedI18n("widget.stockPrice"); const theme = useMantineTheme(); const [{ data }] = clientApi.widget.stockPrice.getPriceHistory.useSuspenseQuery(options); const stockValuesChange = round(calculateChange(data.priceHistory.at(-1) ?? 0, data.priceHistory[0] ?? 0)); const stockValuesChangePercentage = round( calculateChangePercentage(data.priceHistory.at(-1) ?? 0, data.priceHistory[0] ?? 0), ); const stockValuesMin = Math.min(...data.priceHistory); const stockGraphValues = data.priceHistory.map((value) => value - stockValuesMin + 50); return ( 280 ? "75%" : "50%"} data={stockGraphValues} curveType="linear" trendColors={{ positive: "green.7", negative: "red.7", neutral: "gray.6" }} fillOpacity={0.6} strokeWidth={2.5} /> {stockValuesChange > 0 ? ( ) : ( )} {data.symbol} {width > 280 && height > 280 && ( {data.shortName} )} 280 ? 1 : 2} fw={700}> {new Intl.NumberFormat().format(round(data.priceHistory.at(-1) ?? 0))} {width > 280 && ( {new Intl.NumberFormat().format(stockValuesChange)} ({stockValuesChange > 0 ? "+" : ""} {new Intl.NumberFormat().format(stockValuesChangePercentage)}%) )} {width > 280 && ( {t(`option.timeRange.option.${options.timeRange}.label`)} )} {stockValuesChange > 0 ? ( ) : ( )} {data.symbol} {width > 280 && height > 280 && ( {data.shortName} )} ); }