Where: initials(), duplicated identically in src/components/layout/navbar.tsx (lines 30-37) and src/components/dashboard/shipment-ui.tsx (lines 33-40):
function initials(name: string) {
return name
.split(' ')
.map((part) => part[0])
.slice(0, 2)
.join('')
.toUpperCase();
}
Used to render the avatar-badge initials in the desktop nav's AccountMenu (navbar.tsx line 50) and in the dashboard header (authenticated-dashboard.tsx line 173, via the shipment-ui.tsx export).
What: the function splits on a single literal space and takes part[0] of each resulting chunk without filtering out empty strings first, so it isn't resilient to leading/trailing/double spaces.
Why it's a problem: the sign-up form (src/app/signup/page.tsx line 18) validates displayName with only z.string().min(2, 'Tell us your name') — there's no .trim() — so a name like " Jane Doe" (an accidental leading space, easy to introduce on a mobile keyboard with autocapitalize/autocomplete) or "Jane Doe" (double space) passes validation as-is and gets stored via signUp().
Trace through initials(" Jane Doe"):
" Jane Doe".split(' ') → ['', 'Jane', 'Doe']
.map((part) => part[0]) → [undefined, 'J', 'D']
.slice(0, 2) → [undefined, 'J']
.join('') → "J" (wrong — should be "JD")
And for a name with a double leading space, e.g. " Jane Doe":
split(' ') → ['', '', 'Jane', 'Doe']
.map(...) → [undefined, undefined, 'J', 'D']
.slice(0, 2) → [undefined, undefined]
.join('') → "" — the avatar badge renders completely blank in both the nav AccountMenu and the dashboard header, instead of "JD".
Suggested fix direction: filter out empty segments before mapping/slicing, e.g. name.trim().split(/\s+/).filter(Boolean).map((part) => part[0]).... Since the helper is duplicated verbatim in two files, this is also a good opportunity to move it into src/lib/utils.ts and import it in both places instead of keeping two copies in sync.
Labels: bug, good first issue
Where:
initials(), duplicated identically insrc/components/layout/navbar.tsx(lines 30-37) andsrc/components/dashboard/shipment-ui.tsx(lines 33-40):Used to render the avatar-badge initials in the desktop nav's
AccountMenu(navbar.tsxline 50) and in the dashboard header (authenticated-dashboard.tsxline 173, via theshipment-ui.tsxexport).What: the function splits on a single literal space and takes
part[0]of each resulting chunk without filtering out empty strings first, so it isn't resilient to leading/trailing/double spaces.Why it's a problem: the sign-up form (
src/app/signup/page.tsxline 18) validatesdisplayNamewith onlyz.string().min(2, 'Tell us your name')— there's no.trim()— so a name like" Jane Doe"(an accidental leading space, easy to introduce on a mobile keyboard with autocapitalize/autocomplete) or"Jane Doe"(double space) passes validation as-is and gets stored viasignUp().Trace through
initials(" Jane Doe"):" Jane Doe".split(' ')→['', 'Jane', 'Doe'].map((part) => part[0])→[undefined, 'J', 'D'].slice(0, 2)→[undefined, 'J'].join('')→"J"(wrong — should be "JD")And for a name with a double leading space, e.g.
" Jane Doe":split(' ')→['', '', 'Jane', 'Doe'].map(...)→[undefined, undefined, 'J', 'D'].slice(0, 2)→[undefined, undefined].join('')→""— the avatar badge renders completely blank in both the navAccountMenuand the dashboard header, instead of "JD".Suggested fix direction: filter out empty segments before mapping/slicing, e.g.
name.trim().split(/\s+/).filter(Boolean).map((part) => part[0]).... Since the helper is duplicated verbatim in two files, this is also a good opportunity to move it intosrc/lib/utils.tsand import it in both places instead of keeping two copies in sync.Labels: bug, good first issue