diff --git a/messages/en-US.json b/messages/en-US.json index d5521aec..e731009d 100644 --- a/messages/en-US.json +++ b/messages/en-US.json @@ -1282,6 +1282,8 @@ "productUpdateMoreInfo": "{noOfUpdates} more updates", "productUpdateInfo": "{noOfUpdates} updates", "productUpdateWhatsNew": "What's New", + "productUpdateTitle": "Product Updates", + "dismissAll": "Dismiss all", "pangolinUpdateAvailable": "New version available", "pangolinUpdateAvailableInfo": "Version {version} is ready to install", "pangolinUpdateAvailableReleaseNotes": "View release notes", diff --git a/src/components/ProductUpdates.tsx b/src/components/ProductUpdates.tsx index b67d324a..5df3acd8 100644 --- a/src/components/ProductUpdates.tsx +++ b/src/components/ProductUpdates.tsx @@ -16,6 +16,9 @@ import { useTranslations } from "next-intl"; import { Transition } from "@headlessui/react"; import * as React from "react"; import { Popover, PopoverContent, PopoverTrigger } from "./ui/popover"; +import { Button } from "./ui/button"; +import { Badge } from "./ui/badge"; +import { timeAgoFormatter } from "@app/lib/timeAgoFormatter"; export default function ProductUpdates({ isCollapsed @@ -158,8 +161,40 @@ function ProductUpdatesListPopup({ - - Hello + +
+ + {t("productUpdateTitle")} + {updates.length} + + +
+
    + {updates.map((update) => ( +
  1. +

    + {update.title} + New +

    + + {update.contents} + + +
  2. + ))} +
diff --git a/src/lib/timeAgoFormatter.ts b/src/lib/timeAgoFormatter.ts new file mode 100644 index 00000000..0aeff8bc --- /dev/null +++ b/src/lib/timeAgoFormatter.ts @@ -0,0 +1,48 @@ +export function timeAgoFormatter( + dateInput: string | Date, + short: boolean = false +): string { + const date = new Date(dateInput); + const now = new Date(); + const diffInSeconds = Math.floor((now.getTime() - date.getTime()) / 1000); + + const secondsInMinute = 60; + const secondsInHour = 60 * secondsInMinute; + const secondsInDay = 24 * secondsInHour; + const secondsInWeek = 7 * secondsInDay; + const secondsInMonth = 30 * secondsInDay; + const secondsInYear = 365 * secondsInDay; + + let value: number; + let unit: Intl.RelativeTimeFormatUnit; + + if (diffInSeconds < secondsInMinute) { + value = diffInSeconds; + unit = "second"; + } else if (diffInSeconds < secondsInHour) { + value = Math.floor(diffInSeconds / secondsInMinute); + unit = "minute"; + } else if (diffInSeconds < secondsInDay) { + value = Math.floor(diffInSeconds / secondsInHour); + unit = "hour"; + } else if (diffInSeconds < secondsInWeek) { + value = Math.floor(diffInSeconds / secondsInDay); + unit = "day"; + } else if (diffInSeconds < secondsInMonth) { + value = Math.floor(diffInSeconds / secondsInWeek); + unit = "week"; + } else if (diffInSeconds < secondsInYear) { + value = Math.floor(diffInSeconds / secondsInMonth); + unit = "month"; + } else { + value = Math.floor(diffInSeconds / secondsInYear); + unit = "year"; + } + + const rtf = new Intl.RelativeTimeFormat("en", { + numeric: "auto", + style: short ? "narrow" : "long" + }); + const formatedValue = rtf.format(-value, unit); + return formatedValue === "now" ? "Just now" : formatedValue; +}