"use client"; import { Badge, Box, Group, Paper, Progress, RingProgress, ScrollArea, SimpleGrid, Stack, Text, VisuallyHidden, } from "@mantine/core"; import { useCurrentIntlLocale, useScopedI18n } from "@homarr/translation/client"; import { formatLocalizedDate } from "../common/locale"; import { useWidgetNow } from "../common/use-widget-now"; import type { WidgetComponentProps } from "../definition"; import { getTodayLayout, getTodayStats } from "./date-stats"; const formatProgress = (value: number) => Math.round(value); export default function TodayWidget({ options, width, height, displayMode }: WidgetComponentProps<"today">) { const now = useWidgetNow("minute"); const locale = useCurrentIntlLocale(); const t = useScopedI18n("widget.today"); if (now === null) { return ( — ); } const stats = getTodayStats(now, options.weekConvention, locale); if (displayMode === "advanced") { return ; } const layout = getTodayLayout(width, height); const weekday = formatLocalizedDate(now, locale, { weekday: "long" }); const month = formatLocalizedDate(now, locale, { month: "long" }); const fullDate = formatLocalizedDate(now, locale, { dateStyle: "long" }); if (layout.tiny) { return ( {weekday} · {month} {now.getDate()} ); } return ( {weekday} {layout.showFullDate ? fullDate : `${month} ${now.getDate()}`} {options.showYearProgress && ( {formatProgress(stats.yearProgress)}% } /> {t("yearProgress", { progress: formatProgress(stats.yearProgress) })} )} {layout.showStats && ( {options.showWeekNumber && {t("weekNumber", { week: stats.weekNumber })}} {options.showDayOfYear && ( {t("dayOfYear", { day: stats.dayOfYear, total: stats.daysInYear })} )} {layout.showQuarter && options.showQuarter && ( {t("quarter", { quarter: stats.quarter })} )} {layout.showQuarter && ( {t("daysAfterToday", { days: stats.daysAfterToday })} )} )} {layout.showMonthProgress && } ); } interface AdvancedTodayProps { now: Date; locale: string; options: WidgetComponentProps<"today">["options"]; stats: ReturnType; } const AdvancedToday = ({ now, locale, options, stats }: AdvancedTodayProps) => { const t = useScopedI18n("widget.today"); const numberFormatter = new Intl.NumberFormat(locale); const visibleMetrics = [ options.showWeekNumber && { label: t("advanced.week"), value: numberFormatter.format(stats.weekNumber) }, options.showDayOfYear && { label: t("advanced.dayOfYear"), value: `${numberFormatter.format(stats.dayOfYear)} / ${numberFormatter.format(stats.daysInYear)}`, }, options.showQuarter && { label: t("advanced.quarter"), value: `Q${stats.quarter}` }, { label: t("advanced.daysRemaining"), value: numberFormatter.format(stats.daysAfterToday) }, ].filter((metric): metric is { label: string; value: string } => Boolean(metric)); return ( {formatLocalizedDate(now, locale, { dateStyle: "full" })} {options.showWeekNumber && ( {t(`weekConvention.${options.weekConvention}`)} )} {visibleMetrics.map((metric) => ( {metric.label} {metric.value} ))} {options.showYearProgress && } {Array.from({ length: 12 }, (_, monthIndex) => { const date = new Date(now.getFullYear(), monthIndex, 1); const isCurrent = monthIndex === stats.monthIndex; return ( {formatLocalizedDate(date, locale, { month: "short" })} {isCurrent && ( {now.getDate()} )} ); })} ); }; const ProgressMetric = ({ label, value }: { label: string; value: number }) => { const roundedValue = formatProgress(value); return ( {label} {roundedValue}% ); }; const toDateTime = (date: Date) => { const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, "0"); const day = String(date.getDate()).padStart(2, "0"); return `${year}-${month}-${day}`; };