{ "name": "relative-time-card", "type": "registry:ui", "files": [ { "path": "ui/relative-time-card.tsx", "type": "registry:ui", "content": "\"use client\";\n\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport * as React from \"react\";\nimport { cn } from \"@/lib/utils\";\nimport {\n HoverCard,\n HoverCardContent,\n HoverCardTrigger,\n} from \"@/registry/bases/base/ui/hover-card\";\n\nfunction pluralize(n: number, word: string) {\n return `${n} ${word}${n === 1 ? \"\" : \"s\"}`;\n}\n\nfunction formatRelativeTime(date: Date): string {\n const now = new Date();\n const diff = now.getTime() - date.getTime();\n const isInFuture = diff < 0;\n const absDiff = Math.abs(diff);\n\n const seconds = Math.floor(absDiff / 1000);\n const minutes = Math.floor(seconds / 60);\n const hours = Math.floor(minutes / 60);\n const days = Math.floor(hours / 24);\n\n if (seconds < 5) return \"just now\";\n\n if (isInFuture) {\n if (seconds < 60) return `in ${pluralize(seconds, \"second\")}`;\n if (minutes < 60) return `in ${pluralize(minutes, \"minute\")}`;\n if (hours < 24) return `in ${pluralize(hours, \"hour\")}`;\n if (days < 7) return `in ${pluralize(days, \"day\")}`;\n return date.toLocaleDateString();\n }\n\n if (seconds < 60) return `${pluralize(seconds, \"second\")} ago`;\n if (minutes < 60)\n return `${pluralize(minutes, \"minute\")} ${pluralize(seconds % 60, \"second\")} ago`;\n if (hours < 24) return `${pluralize(hours, \"hour\")} ago`;\n if (days < 7) return `${pluralize(days, \"day\")} ago`;\n return date.toLocaleDateString();\n}\n\ninterface TimezoneCardProps extends React.ComponentProps<\"div\"> {\n date: Date;\n timezone?: string;\n}\n\nfunction TimezoneCard(props: TimezoneCardProps) {\n const { date, timezone, ...cardProps } = props;\n\n const locale = React.useMemo(\n () => Intl.DateTimeFormat().resolvedOptions().locale,\n [],\n );\n\n const timezoneName = React.useMemo(\n () =>\n timezone ??\n new Intl.DateTimeFormat(locale, { timeZoneName: \"shortOffset\" })\n .formatToParts(date)\n .find((part) => part.type === \"timeZoneName\")?.value,\n [date, timezone, locale],\n );\n\n const { formattedDate, formattedTime } = React.useMemo(\n () => ({\n formattedDate: new Intl.DateTimeFormat(locale, {\n month: \"long\",\n day: \"numeric\",\n year: \"numeric\",\n timeZone: timezone,\n }).format(date),\n formattedTime: new Intl.DateTimeFormat(locale, {\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\",\n hour12: true,\n timeZone: timezone,\n }).format(date),\n }),\n [date, timezone, locale],\n );\n\n return (\n