Skip to content

Extract a shared thread-timestamp formatter for the chats sidebars (currently duplicated) #1376

@MODSetter

Description

@MODSetter

Problem

Two sidebar files render thread "updated at" timestamps with byte-identical inline date-fns calls:

surfsense_web/components/layout/ui/sidebar/AllPrivateChatsSidebar.tsx:393

{format(new Date(thread.updatedAt), "MMM d, yyyy 'at' h:mm a")}

surfsense_web/components/layout/ui/sidebar/AllSharedChatsSidebar.tsx:392

{format(new Date(thread.updatedAt), "MMM d, yyyy 'at' h:mm a")}

Meanwhile, the rest of the app uses formatRelativeDate(iso) from surfsense_web/lib/format-date.ts for similar "recent timestamp" needs (e.g. action logs, team page). "How we display a recent timestamp" has two adapters in the codebase, with two different policies (relative vs absolute calendar).

If we ever want to switch threads to relative time, or i18n-localize the format, the two sidebars must be edited in lockstep.

Files

  • surfsense_web/components/layout/ui/sidebar/AllPrivateChatsSidebar.tsx (line 393)
  • surfsense_web/components/layout/ui/sidebar/AllSharedChatsSidebar.tsx (line 392)
  • surfsense_web/lib/format-date.ts (new helper goes here)

What to do

  1. Add a small helper in surfsense_web/lib/format-date.ts:

    /**
     * Format a thread's last-updated timestamp for the chats sidebars.
     * Example: "Mar 23, 2026 at 4:30 PM"
     */
    export function formatThreadTimestamp(dateString: string): string {
        return format(new Date(dateString), "MMM d, yyyy 'at' h:mm a");
    }
  2. Replace both inline calls:

    - {format(new Date(thread.updatedAt), "MMM d, yyyy 'at' h:mm a")}
    + {formatThreadTimestamp(thread.updatedAt)}
  3. Drop the now-unused format import from date-fns in those two sidebars (if format isn't used elsewhere in the file).

Why this matters

  • Locality of date-formatting policy: when we want "relative under 1 day, absolute beyond," or i18n localization, there's one place to edit.
  • Tiny test surface: one helper unit-test instead of two component tests for the formatter.
  • Aligns with the existing formatRelativeDate pattern in format-date.ts.

Acceptance criteria

  • formatThreadTimestamp exported from lib/format-date.ts
  • Both sidebars use the helper
  • Sidebars render identical timestamp strings as before (no visual regression)

Difficulty

Good first issue — trivial DRY extraction.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions