From a14662d278fcb745d8954ab70cdf5b1944e83499 Mon Sep 17 00:00:00 2001 From: Temitope-007 Date: Mon, 27 Apr 2026 20:32:48 +0000 Subject: [PATCH] Add shared helper for formatting large follower counts - Extract formatFollowerCount from FollowerCountPill to numberFormat.utils.ts - Apply helper in CreatorCard for creator share supply display - Preserve full value availability via title attribute in FollowerCountPill - Add comprehensive tests for formatFollowerCount function --- src/components/common/CreatorCard.tsx | 4 +-- src/components/common/FollowerCountPill.tsx | 14 +++------- .../__tests__/numberFormat.utils.test.ts | 26 ++++++++++++++++++- src/utils/numberFormat.utils.ts | 10 +++++++ 4 files changed, 40 insertions(+), 14 deletions(-) diff --git a/src/components/common/CreatorCard.tsx b/src/components/common/CreatorCard.tsx index 1bf47401..56652564 100644 --- a/src/components/common/CreatorCard.tsx +++ b/src/components/common/CreatorCard.tsx @@ -25,7 +25,7 @@ import CreatorLabeledStatRow from '@/components/common/CreatorLabeledStatRow'; import CreatorBio from '@/components/common/CreatorBio'; import { useTransactionTelemetry } from '@/hooks/useTransactionTelemetry'; import { useNetworkMismatch } from '@/hooks/useNetworkMismatch'; -import { formatCompactNumber, formatNumber } from '@/utils/numberFormat.utils'; +import { formatCompactNumber, formatNumber, formatFollowerCount } from '@/utils/numberFormat.utils'; interface CreatorCardProps { creator: Course; @@ -185,7 +185,7 @@ const CreatorCard: React.FC = ({ creator, className }) => { label="Creator Share Supply" value={ creator.creatorShareSupply - ? `${formatCompactNumber(creator.creatorShareSupply)} shares` + ? `${formatFollowerCount(creator.creatorShareSupply)} shares` : 'Supply pending' } className="px-3 py-3" diff --git a/src/components/common/FollowerCountPill.tsx b/src/components/common/FollowerCountPill.tsx index dded93fd..20f9f8db 100644 --- a/src/components/common/FollowerCountPill.tsx +++ b/src/components/common/FollowerCountPill.tsx @@ -1,21 +1,12 @@ import { Users } from 'lucide-react'; import { cn } from '@/lib/utils'; +import { formatFollowerCount } from '@/utils/numberFormat.utils'; interface FollowerCountPillProps { count?: number | null; className?: string; } -function formatCount(count: number): string { - if (count >= 1_000_000) { - return `${(count / 1_000_000).toFixed(1).replace(/\.0$/, '')}M`; - } - if (count >= 1_000) { - return `${(count / 1_000).toFixed(1).replace(/\.0$/, '')}K`; - } - return count.toString(); -} - const FollowerCountPill: React.FC = ({ count, className, @@ -30,9 +21,10 @@ const FollowerCountPill: React.FC = ({ 'inline-flex items-center gap-1 rounded-full border border-white/10 bg-white/5 px-2 py-0.5 text-xs font-medium text-white/70', className )} + title={count.toString()} // Preserve full value availability > - {formatCount(count)} + {formatFollowerCount(count)} ); }; diff --git a/src/utils/__tests__/numberFormat.utils.test.ts b/src/utils/__tests__/numberFormat.utils.test.ts index b9564ab6..05c18a75 100644 --- a/src/utils/__tests__/numberFormat.utils.test.ts +++ b/src/utils/__tests__/numberFormat.utils.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import { formatPercent } from '@/utils/numberFormat.utils'; +import { formatPercent, formatFollowerCount } from '@/utils/numberFormat.utils'; describe('formatPercent', () => { it('renders the value with a trailing percent sign', () => { @@ -58,3 +58,27 @@ describe('formatPercent', () => { ).toBe('12.00%'); }); }); + +describe('formatFollowerCount', () => { + it('formats numbers less than 1000 as is', () => { + expect(formatFollowerCount(0)).toBe('0'); + expect(formatFollowerCount(999)).toBe('999'); + }); + + it('formats thousands with K suffix', () => { + expect(formatFollowerCount(1000)).toBe('1K'); + expect(formatFollowerCount(1500)).toBe('1.5K'); + expect(formatFollowerCount(999999)).toBe('1000K'); + }); + + it('formats millions with M suffix', () => { + expect(formatFollowerCount(1000000)).toBe('1M'); + expect(formatFollowerCount(1500000)).toBe('1.5M'); + expect(formatFollowerCount(999999999)).toBe('1000M'); + }); + + it('removes trailing .0', () => { + expect(formatFollowerCount(1000)).toBe('1K'); + expect(formatFollowerCount(1000000)).toBe('1M'); + }); +}); diff --git a/src/utils/numberFormat.utils.ts b/src/utils/numberFormat.utils.ts index 53a6ad8b..d61e79e4 100644 --- a/src/utils/numberFormat.utils.ts +++ b/src/utils/numberFormat.utils.ts @@ -39,6 +39,16 @@ export function formatCompactNumber( return formatNumber(value, { ...options, style: 'compact' }); } +export function formatFollowerCount(count: number): string { + if (count >= 1_000_000) { + return `${(count / 1_000_000).toFixed(1).replace(/\.0$/, '')}M`; + } + if (count >= 1_000) { + return `${(count / 1_000).toFixed(1).replace(/\.0$/, '')}K`; + } + return count.toString(); +} + export interface FormatPercentOptions { /** Maximum fractional digits in the rendered value. Defaults to 2. */ maximumFractionDigits?: number;