Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/components/common/CreatorCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import CreatorBio from '@/components/common/CreatorBio';
import { useTransactionTelemetry } from '@/hooks/useTransactionTelemetry';
import { useNetworkMismatch } from '@/hooks/useNetworkMismatch';
import { formatCompactNumber, formatNumber, formatFollowerCount } from '@/utils/numberFormat.utils';
import { truncateCreatorName } from '@/utils/creatorName.utils';

interface CreatorCardProps {
creator: Course;
Expand Down Expand Up @@ -138,8 +139,8 @@ const CreatorCard: React.FC<CreatorCardProps> = ({ creator, className }) => {

<div className="mb-4">
<div className="flex items-center gap-2 flex-wrap">
<h3 className="font-jakarta text-lg font-bold text-white">
{creator.title}
<h3 className="font-jakarta text-lg font-bold text-white" title={creator.title}>
{truncateCreatorName(creator.title)}
</h3>
<VerifiedBadge
verified={Boolean(creator.isVerified)}
Expand Down
5 changes: 3 additions & 2 deletions src/components/common/CreatorProfileHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { cn } from '@/lib/utils';
import VerifiedBadge from '@/components/common/VerifiedBadge';
import CreatorInitialsAvatar from '@/components/common/CreatorInitialsAvatar';
import CreatorBio from '@/components/common/CreatorBio';
import { truncateCreatorName } from '@/utils/creatorName.utils';

interface CreatorProfileHeaderProps {
name: string;
Expand Down Expand Up @@ -72,8 +73,8 @@ const CreatorProfileHeader: React.FC<CreatorProfileHeaderProps> = ({
</div>
<div className="min-w-0 space-y-1">
<div className="flex items-center gap-2 overflow-hidden">
<h1 className="truncate font-grotesque text-3xl font-black tracking-tight text-white md:text-4xl">
{name}
<h1 className="truncate font-grotesque text-3xl font-black tracking-tight text-white md:text-4xl" title={name}>
{truncateCreatorName(name, 32)}
</h1>
{isVerified && <div className="shrink-0"><VerifiedBadge verified={true} /></div>}
</div>
Expand Down
39 changes: 39 additions & 0 deletions src/utils/creatorName.utils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { describe, expect, it } from 'vitest';
import { truncateCreatorName } from '@/utils/creatorName.utils';

describe('truncateCreatorName', () => {
it('returns the name unchanged when within the default limit', () => {
expect(truncateCreatorName('Alex Rivers')).toBe('Alex Rivers');
});

it('truncates names that exceed the default 24-character limit', () => {
const long = 'Maximilian Thunderstruck Jr';
expect(long.length).toBeGreaterThan(24);
const result = truncateCreatorName(long);
expect(result.endsWith('…')).toBe(true);
expect(result.length).toBeLessThanOrEqual(25); // 24 chars + ellipsis
});

it('does not truncate a name exactly at the limit', () => {
const exact = 'A'.repeat(24);
expect(truncateCreatorName(exact)).toBe(exact);
});

it('respects a custom maxLength', () => {
const result = truncateCreatorName('Sarah Chen', 5);
expect(result).toBe('Sarah…');
});

it('returns an empty string for empty input', () => {
expect(truncateCreatorName('')).toBe('');
});

it('trims surrounding whitespace before truncating', () => {
expect(truncateCreatorName(' Alex ')).toBe('Alex');
});

it('does not add ellipsis for short names', () => {
expect(truncateCreatorName('Jo')).toBe('Jo');
expect(truncateCreatorName('Jo').includes('…')).toBe(false);
});
});
14 changes: 14 additions & 0 deletions src/utils/creatorName.utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* Truncates a creator name to a maximum character length, appending an ellipsis
* when the name exceeds the limit.
*
* @param name - The creator name to truncate.
* @param maxLength - Maximum number of characters before truncation. Defaults to 24.
* @returns The original name if within limit, or a truncated version ending with `…`.
*/
export function truncateCreatorName(name: string, maxLength = 24): string {
if (!name) return '';
const trimmed = name.trim();
if (trimmed.length <= maxLength) return trimmed;
return `${trimmed.slice(0, maxLength).trimEnd()}…`;
}