"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)}%
}
/>
)}
{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}`;
};