diff --git a/frontend/src/lib/components/CommentThread.svelte b/frontend/src/lib/components/CommentThread.svelte
index 6796cc3f..1d5ce5e5 100644
--- a/frontend/src/lib/components/CommentThread.svelte
+++ b/frontend/src/lib/components/CommentThread.svelte
@@ -5,6 +5,7 @@ import type { Comment } from '$lib/types';
import MentionEditor from '$lib/components/MentionEditor.svelte';
import { renderBody, extractContent } from '$lib/utils/mention';
import { relativeTime } from '$lib/utils/time';
+import { getInitials } from '$lib/utils/personFormat';
import type { MentionDTO } from '$lib/types';
type Props = {
@@ -76,14 +77,6 @@ function isOwn(c: { authorId: string | null }): boolean {
return currentUserId !== null && c.authorId === currentUserId;
}
-function getInitials(name: string): string {
- return name
- .split(/\s+/)
- .slice(0, 2)
- .map((w) => w.charAt(0).toUpperCase())
- .join('');
-}
-
function extractQuote(content: string): { quote: string | null; body: string } {
const match = content.match(/^>\s*"(.+?)"\s*\n\n?([\s\S]*)$/);
if (match) return { quote: match[1], body: match[2] };
diff --git a/frontend/src/lib/components/DocumentMetadataDrawer.svelte b/frontend/src/lib/components/DocumentMetadataDrawer.svelte
index d057a993..a24a27d1 100644
--- a/frontend/src/lib/components/DocumentMetadataDrawer.svelte
+++ b/frontend/src/lib/components/DocumentMetadataDrawer.svelte
@@ -2,7 +2,7 @@
import { m } from '$lib/paraglide/messages.js';
import { formatDate } from '$lib/utils/date';
import { formatDocumentStatus } from '$lib/utils/documentStatusLabel';
-import { getInitials as calcInitials, personAvatarColor } from '$lib/utils/personFormat';
+import { getInitials, personAvatarColor } from '$lib/utils/personFormat';
type Person = { id: string; firstName?: string | null; lastName: string; displayName: string };
type Tag = { id: string; name: string };
@@ -32,10 +32,6 @@ let showAllReceivers = $state(false);
const displayedReceivers = $derived(showAllReceivers ? receivers : visibleReceivers);
-function getInitials(person: Person): string {
- return calcInitials(person);
-}
-
function getFullName(person: Person): string {
return person.displayName;
}
@@ -51,7 +47,7 @@ function getFullName(person: Person): string {
style="background-color: {personAvatarColor(person.id)}"
aria-hidden="true"
>
- {getInitials(person)}
+ {getInitials(person.displayName)}
{getFullName(person)}
diff --git a/frontend/src/lib/components/PersonChip.svelte b/frontend/src/lib/components/PersonChip.svelte
index 97796c00..89dd502a 100644
--- a/frontend/src/lib/components/PersonChip.svelte
+++ b/frontend/src/lib/components/PersonChip.svelte
@@ -12,7 +12,7 @@ let { person, abbreviated }: Props = $props();
const name = $derived(abbreviated ? abbreviateName(person) : person.displayName);
const avatarColor = $derived(personAvatarColor(person.id));
-const initials = $derived(getInitials(person));
+const initials = $derived(getInitials(person.displayName));
{
+ it('returns first chars of first and last word uppercased', () => {
+ expect(getInitials('Marcel Raddatz')).toBe('MR');
+ });
+
+ it('returns single char for a single-word name', () => {
+ expect(getInitials('Raddatz')).toBe('R');
+ });
+
+ it('returns empty string for an empty name', () => {
+ expect(getInitials('')).toBe('');
+ });
+
+ it('splits on whitespace only — hyphenated first word counts as one', () => {
+ expect(getInitials('Anna-Maria Raddatz')).toBe('AR');
+ });
+
+ it('ignores extra whitespace between words', () => {
+ expect(getInitials(' Karl Raddatz ')).toBe('KR');
+ });
+});
+
// ─── abbreviateName ──────────────────────────────────────────────────────────
describe('abbreviateName', () => {
diff --git a/frontend/src/lib/utils/personFormat.ts b/frontend/src/lib/utils/personFormat.ts
index 241339f3..d60023e0 100644
--- a/frontend/src/lib/utils/personFormat.ts
+++ b/frontend/src/lib/utils/personFormat.ts
@@ -18,9 +18,11 @@ function djb2(str: string): number {
return Math.abs(hash);
}
-export function getInitials(person: Person): string {
- if (person.firstName) return `${person.firstName[0]}${person.lastName[0]}`.toUpperCase();
- return person.lastName.substring(0, 2).toUpperCase();
+export function getInitials(name: string): string {
+ const words = name.trim().split(/\s+/).filter(Boolean);
+ if (words.length === 0) return '';
+ if (words.length === 1) return words[0].charAt(0).toUpperCase();
+ return (words[0].charAt(0) + words[words.length - 1].charAt(0)).toUpperCase();
}
export function abbreviateName(person: Person): string {