From 9045dbca726c088307ca0b7400d5496d3f77b56f Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Thu, 23 Jul 2026 17:38:13 +0530 Subject: [PATCH] chore: refactor format date in UI --- ui/src/app/api-keys/page.tsx | 11 ++--- ui/src/app/billing/page.tsx | 17 +++---- ui/src/app/campaigns/[campaignId]/page.tsx | 24 +++++----- ui/src/app/campaigns/page.tsx | 11 +++-- ui/src/app/files/DocumentList.tsx | 10 ++-- ui/src/app/recordings/RecordingsList.tsx | 10 ++-- ui/src/app/superadmin/runs/page.tsx | 5 +- .../[configId]/page.tsx | 5 +- ui/src/app/usage/page.tsx | 24 ++-------- .../[workflowId]/run/[runId]/page.tsx | 12 +++++ ui/src/components/DailyUsageTable.tsx | 13 +----- ui/src/components/filters/DateRangeFilter.tsx | 3 +- .../workflow-runs/WorkflowRunsTable.tsx | 9 ++-- ui/src/components/workflow/WorkflowCard.tsx | 6 ++- ui/src/components/workflow/WorkflowTable.tsx | 10 ++-- ui/src/hooks/useOrganizationTimezone.ts | 9 ++++ ui/src/lib/dateTime.test.ts | 21 +++++++++ ui/src/lib/dateTime.ts | 46 +++++++++++++++++++ ui/src/lib/filters.ts | 7 +-- 19 files changed, 155 insertions(+), 98 deletions(-) create mode 100644 ui/src/hooks/useOrganizationTimezone.ts create mode 100644 ui/src/lib/dateTime.test.ts create mode 100644 ui/src/lib/dateTime.ts diff --git a/ui/src/app/api-keys/page.tsx b/ui/src/app/api-keys/page.tsx index 05aa7c33..eb3c2955 100644 --- a/ui/src/app/api-keys/page.tsx +++ b/ui/src/app/api-keys/page.tsx @@ -21,12 +21,15 @@ import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Skeleton } from '@/components/ui/skeleton'; import { useAppConfig } from '@/context/AppConfigContext'; +import { useOrganizationTimezone } from '@/hooks/useOrganizationTimezone'; import { useAuth } from '@/lib/auth'; +import { formatDateTime } from '@/lib/dateTime'; import logger from '@/lib/logger'; export default function APIKeysPage() { const { user, getAccessToken, redirectToLogin, loading } = useAuth(); const { config } = useAppConfig(); + const organizationTimezone = useOrganizationTimezone(); const isOSS = config?.deploymentMode === 'oss'; logger.debug('[APIKeysPage] Component render', { @@ -292,13 +295,7 @@ export default function APIKeysPage() { const formatDate = (dateString: string | null) => { if (!dateString) return 'Never'; - return new Date(dateString).toLocaleDateString('en-US', { - year: 'numeric', - month: 'short', - day: 'numeric', - hour: '2-digit', - minute: '2-digit' - }); + return formatDateTime(dateString, organizationTimezone); }; // Don't render content until auth is loaded diff --git a/ui/src/app/billing/page.tsx b/ui/src/app/billing/page.tsx index d11870d2..d6ea61ad 100644 --- a/ui/src/app/billing/page.tsx +++ b/ui/src/app/billing/page.tsx @@ -30,7 +30,9 @@ import { TableRow, } from "@/components/ui/table"; import { useAppConfig } from "@/context/AppConfigContext"; +import { useOrganizationTimezone } from "@/hooks/useOrganizationTimezone"; import { useAuth } from "@/lib/auth"; +import { formatDateTime } from "@/lib/dateTime"; const LEDGER_PAGE_SIZE = 50; @@ -52,16 +54,6 @@ const formatAmount = (amountMinor?: number | null, currency?: string | null) => }).format(amountMinor / 100); }; -const formatDate = (value: string) => ( - new Date(value).toLocaleString(undefined, { - month: "short", - day: "numeric", - year: "numeric", - hour: "2-digit", - minute: "2-digit", - }) -); - const metricLabels: Record = { voice_minutes: "Voice usage", platform_usage: "Platform usage", @@ -117,6 +109,7 @@ export default function BillingPage() { const searchParams = useSearchParams(); const auth = useAuth(); const { config, loading: configLoading } = useAppConfig(); + const organizationTimezone = useOrganizationTimezone(); const [credits, setCredits] = useState(null); const [loading, setLoading] = useState(true); const [refreshing, setRefreshing] = useState(false); @@ -353,7 +346,9 @@ export default function BillingPage() { const billableQuantity = formatBillableQuantity(entry); return ( - {formatDate(entry.created_at)} + + {formatDateTime(entry.created_at, organizationTimezone)} +
{getLedgerEntryLabel(entry)} diff --git a/ui/src/app/campaigns/[campaignId]/page.tsx b/ui/src/app/campaigns/[campaignId]/page.tsx index baab4a63..f409aeef 100644 --- a/ui/src/app/campaigns/[campaignId]/page.tsx +++ b/ui/src/app/campaigns/[campaignId]/page.tsx @@ -27,10 +27,13 @@ import { Label } from '@/components/ui/label'; import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'; import { Separator } from '@/components/ui/separator'; import { CampaignRuns } from '@/components/workflow-runs'; +import { useOrganizationTimezone } from '@/hooks/useOrganizationTimezone'; import { useAuth } from '@/lib/auth'; +import { formatDate, formatDateTime } from '@/lib/dateTime'; export default function CampaignDetailPage() { const { user, getAccessToken, redirectToLogin, loading } = useAuth(); + const organizationTimezone = useOrganizationTimezone(); const router = useRouter(); const params = useParams(); const searchParams = useSearchParams(); @@ -352,15 +355,6 @@ export default function CampaignDetailPage() { } }; - // Format date for display - const formatDate = (dateString: string) => { - return new Date(dateString).toLocaleDateString(); - }; - - const formatDateTime = (dateString: string) => { - return new Date(dateString).toLocaleString(); - }; - // Get badge variant for state const getStateBadgeVariant = (state: string) => { switch (state) { @@ -410,7 +404,7 @@ export default function CampaignDetailPage() { const formatLogTimestamp = (ts: string) => { const d = new Date(ts); if (isNaN(d.getTime())) return ts; - return d.toLocaleString(); + return formatDateTime(d, organizationTimezone); }; // Render action button based on state @@ -508,7 +502,7 @@ export default function CampaignDetailPage() { {campaign.state} - Created {formatDate(campaign.created_at)} + Created {formatDate(campaign.created_at, organizationTimezone)}
@@ -700,13 +694,17 @@ export default function CampaignDetailPage() { {campaign.started_at && (
Started At
-
{formatDateTime(campaign.started_at)}
+
+ {formatDateTime(campaign.started_at, organizationTimezone)} +
)} {campaign.completed_at && (
Completed At
-
{formatDateTime(campaign.completed_at)}
+
+ {formatDateTime(campaign.completed_at, organizationTimezone)} +
)} diff --git a/ui/src/app/campaigns/page.tsx b/ui/src/app/campaigns/page.tsx index ee08dab0..5680674b 100644 --- a/ui/src/app/campaigns/page.tsx +++ b/ui/src/app/campaigns/page.tsx @@ -17,10 +17,13 @@ import { TableHeader, TableRow, } from '@/components/ui/table'; +import { useOrganizationTimezone } from '@/hooks/useOrganizationTimezone'; import { useAuth } from '@/lib/auth'; +import { formatDate } from '@/lib/dateTime'; export default function CampaignsPage() { const { user, getAccessToken, redirectToLogin, loading } = useAuth(); + const organizationTimezone = useOrganizationTimezone(); const router = useRouter(); const [campaignsData, setCampaignsData] = useState(null); @@ -72,10 +75,6 @@ export default function CampaignsPage() { router.push('/campaigns/new'); }; - const formatDate = (dateString: string) => { - return new Date(dateString).toLocaleDateString(); - }; - const getStateBadgeVariant = (state: string) => { switch (state) { case 'created': @@ -152,7 +151,9 @@ export default function CampaignsPage() { {campaign.executed_count} / {campaign.total_queued_count} - {formatDate(campaign.created_at)} + + {formatDate(campaign.created_at, organizationTimezone)} +