fix: custom relative time to shorten strings for better UI fit

This commit is contained in:
Dries Augustyns
2025-12-11 11:13:39 +01:00
parent 1019ba0d82
commit 5e4adb71ad
6 changed files with 35 additions and 10 deletions
+20
View File
@@ -2,6 +2,8 @@
* Shared date formatting and manipulation utilities
*/
import dayjs from 'dayjs';
/**
* Get the user's timezone
*/
@@ -106,3 +108,21 @@ export function formatUTCDateTime(date: Date): string {
timeZone: 'UTC',
});
}
/**
* Format a date as relative time with short format for very recent updates
* Returns "just now" for updates within the last minute to avoid text wrapping
*/
export function formatRelativeTime(date: Date | string): string {
const now = dayjs();
const then = dayjs(date);
const secondsAgo = now.diff(then, 'second');
// If less than 60 seconds, show "just now"
if (secondsAgo < 60) {
return 'just now';
}
// Otherwise use standard relative time
return then.fromNow();
}
+3 -2
View File
@@ -23,6 +23,7 @@ import {DashboardLayout} from '../../components/DashboardLayout';
import {TemplateSelectionDialog} from '../../components/TemplateSelectionDialog';
import {CampaignSelectionDialog} from '../../components/CampaignSelectionDialog';
import {network} from '../../lib/network';
import {formatRelativeTime} from '../../lib/dateUtils';
import {Calendar, ChevronDown, Copy, FileText, Info, Mail, Plus, RefreshCw, Trash2, Users} from 'lucide-react';
import {NextSeo} from 'next-seo';
import Link from 'next/link';
@@ -471,14 +472,14 @@ export default function CampaignsPage() {
<div className="flex items-center gap-1.5">
<Calendar className="h-3 w-3" />
<div className="group relative inline-block cursor-help">
<span>Created {dayjs(campaign.createdAt).fromNow()}</span>
<span>Created {formatRelativeTime(campaign.createdAt)}</span>
<div className="hidden group-hover:block absolute z-10 w-48 p-2 bg-neutral-900 text-white text-xs rounded shadow-lg bottom-full left-0 mb-1 whitespace-nowrap">
{dayjs(campaign.createdAt).format('DD MMMM YYYY, hh:mm')}
</div>
</div>
</div>
<div className="group relative inline-block cursor-help">
<span> Updated {dayjs(campaign.updatedAt).fromNow()}</span>
<span> Updated {formatRelativeTime(campaign.updatedAt)}</span>
<div className="hidden group-hover:block absolute z-10 w-48 p-2 bg-neutral-900 text-white text-xs rounded shadow-lg bottom-full left-0 mb-1 whitespace-nowrap">
{dayjs(campaign.updatedAt).format('DD MMMM YYYY, hh:mm')}
</div>
+3 -2
View File
@@ -19,6 +19,7 @@ import type {Contact} from '@plunk/db';
import {DashboardLayout} from '../../components/DashboardLayout';
import {KeyValueEditor} from '../../components/KeyValueEditor';
import {network} from '../../lib/network';
import {formatRelativeTime} from '../../lib/dateUtils';
import {
CheckCircle,
ChevronLeft,
@@ -281,7 +282,7 @@ export default function ContactsPage() {
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-neutral-500">
<div className="group relative inline-block cursor-help">
{dayjs(contact.createdAt).fromNow()}
{formatRelativeTime(contact.createdAt)}
<div className="hidden group-hover:block absolute z-10 w-48 p-2 bg-neutral-900 text-white text-xs rounded shadow-lg bottom-full left-1/2 transform -translate-x-1/2 mb-1 whitespace-nowrap">
{dayjs(contact.createdAt).format('DD MMMM YYYY, hh:mm')}
</div>
@@ -331,7 +332,7 @@ export default function ContactsPage() {
</div>
<div className="flex items-center justify-between">
<div className="group relative inline-block cursor-help">
<span className="text-xs text-neutral-500">{dayjs(contact.createdAt).fromNow()}</span>
<span className="text-xs text-neutral-500">{formatRelativeTime(contact.createdAt)}</span>
<div className="hidden group-hover:block absolute z-10 w-48 p-2 bg-neutral-900 text-white text-xs rounded shadow-lg bottom-full left-0 mb-1 whitespace-nowrap">
{dayjs(contact.createdAt).format('Do MMMM YYYY, h:mm A')}
</div>
+3 -2
View File
@@ -13,6 +13,7 @@ import type {Segment} from '@plunk/db';
import type {FilterCondition} from '@plunk/types';
import {DashboardLayout} from '../../components/DashboardLayout';
import {network} from '../../lib/network';
import {formatRelativeTime} from '../../lib/dateUtils';
import {AlertTriangle, Calendar, Edit, Filter, Plus, Trash2, Users} from 'lucide-react';
import {NextSeo} from 'next-seo';
import Link from 'next/link';
@@ -199,14 +200,14 @@ export default function SegmentsPage() {
<div className="flex items-center gap-1.5">
<Calendar className="h-3 w-3" />
<div className="group relative inline-block cursor-help">
<span>Created {dayjs(segment.createdAt).fromNow()}</span>
<span>Created {formatRelativeTime(segment.createdAt)}</span>
<div className="hidden group-hover:block absolute z-10 w-48 p-2 bg-neutral-900 text-white text-xs rounded shadow-lg bottom-full left-0 mb-1 whitespace-nowrap">
{dayjs(segment.createdAt).format('DD MMMM YYYY, hh:mm')}
</div>
</div>
</div>
<div className="group relative inline-block cursor-help">
<span> Updated {dayjs(segment.updatedAt).fromNow()}</span>
<span> Updated {formatRelativeTime(segment.updatedAt)}</span>
<div className="hidden group-hover:block absolute z-10 w-48 p-2 bg-neutral-900 text-white text-xs rounded shadow-lg bottom-full left-0 mb-1 whitespace-nowrap">
{dayjs(segment.updatedAt).format('DD MMMM YYYY, hh:mm')}
</div>
+3 -2
View File
@@ -12,6 +12,7 @@ import {
import type {Template} from '@plunk/db';
import {DashboardLayout} from '../../components/DashboardLayout';
import {network} from '../../lib/network';
import {formatRelativeTime} from '../../lib/dateUtils';
import {Calendar, Copy, Edit, FileText, Plus, Search, Trash2} from 'lucide-react';
import {NextSeo} from 'next-seo';
import Link from 'next/link';
@@ -257,14 +258,14 @@ export default function TemplatesPage() {
<div className="flex items-center gap-1.5">
<Calendar className="h-3 w-3" />
<div className="group relative inline-block cursor-help">
<span>Created {dayjs(template.createdAt).fromNow()}</span>
<span>Created {formatRelativeTime(template.createdAt)}</span>
<div className="hidden group-hover:block absolute z-10 w-48 p-2 bg-neutral-900 text-white text-xs rounded shadow-lg bottom-full left-0 mb-1 whitespace-nowrap">
{dayjs(template.createdAt).format('DD MMMM YYYY, hh:mm')}
</div>
</div>
</div>
<div className="group relative inline-block cursor-help">
<span> Updated {dayjs(template.updatedAt).fromNow()}</span>
<span> Updated {formatRelativeTime(template.updatedAt)}</span>
<div className="hidden group-hover:block absolute z-10 w-48 p-2 bg-neutral-900 text-white text-xs rounded shadow-lg bottom-full left-0 mb-1 whitespace-nowrap">
{dayjs(template.updatedAt).format('DD MMMM YYYY, hh:mm')}
</div>
+3 -2
View File
@@ -23,6 +23,7 @@ import {
import type {Workflow} from '@plunk/db';
import {DashboardLayout} from '../../components/DashboardLayout';
import {network} from '../../lib/network';
import {formatRelativeTime} from '../../lib/dateUtils';
import {Calendar, Edit, Plus, Power, PowerOff, Search, Trash2, Workflow as WorkflowIcon} from 'lucide-react';
import {NextSeo} from 'next-seo';
import Link from 'next/link';
@@ -258,14 +259,14 @@ export default function WorkflowsPage() {
<div className="flex items-center gap-1.5">
<Calendar className="h-3 w-3" />
<div className="group relative inline-block cursor-help">
<span>Created {dayjs(workflow.createdAt).fromNow()}</span>
<span>Created {formatRelativeTime(workflow.createdAt)}</span>
<div className="hidden group-hover:block absolute z-10 w-48 p-2 bg-neutral-900 text-white text-xs rounded shadow-lg bottom-full left-0 mb-1 whitespace-nowrap">
{dayjs(workflow.createdAt).format('DD MMMM YYYY, hh:mm')}
</div>
</div>
</div>
<div className="group relative inline-block cursor-help">
<span> Updated {dayjs(workflow.updatedAt).fromNow()}</span>
<span> Updated {formatRelativeTime(workflow.updatedAt)}</span>
<div className="hidden group-hover:block absolute z-10 w-48 p-2 bg-neutral-900 text-white text-xs rounded shadow-lg bottom-full left-0 mb-1 whitespace-nowrap">
{dayjs(workflow.updatedAt).format('DD MMMM YYYY, hh:mm')}
</div>