Skip to content

Commit 11210c0

Browse files
committed
feat: add long word validation for name input in onboarding and settings
1 parent a20c1bb commit 11210c0

3 files changed

Lines changed: 49 additions & 24 deletions

File tree

frontend/src/components/Navigation/Navbar/Navbar.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,13 @@ export function Navbar() {
8181
<ThemeSelector />
8282
<div className="flex items-center space-x-2">
8383
<span className="hidden text-sm sm:inline-block">
84-
Welcome <span className="text-muted-foreground">{userName}</span>
84+
Welcome{' '}
85+
<span
86+
className="text-muted-foreground inline-block max-w-[150px] truncate align-bottom"
87+
title={userName}
88+
>
89+
{userName.split(' ')[0]}
90+
</span>
8591
</span>
8692
<Link to="/settings#account" className="p-2">
8793
<img

frontend/src/components/OnboardingSteps/AvatarSelectionStep.tsx

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ export const AvatarSelectionStep: React.FC<AvatarNameSelectionStepProps> = ({
4040
const isEditing = useSelector(
4141
(state: RootState) => state.onboarding.isEditing,
4242
);
43+
const [longWordError, setLongWordError] = useState(false);
4344

4445
useEffect(() => {
4546
if (
@@ -56,6 +57,13 @@ export const AvatarSelectionStep: React.FC<AvatarNameSelectionStepProps> = ({
5657
};
5758

5859
const handleNameChange = (value: string) => {
60+
const words = value.split(' ');
61+
const hasLongWord = words.some((word) => word.length > 30);
62+
if (hasLongWord) {
63+
setLongWordError(true);
64+
return;
65+
}
66+
setLongWordError(false);
5967
setLocalName(value);
6068
};
6169

@@ -115,6 +123,11 @@ export const AvatarSelectionStep: React.FC<AvatarNameSelectionStepProps> = ({
115123
onChange={(e) => handleNameChange(e.target.value)}
116124
className="h-8 text-sm placeholder:text-sm"
117125
/>
126+
{longWordError && (
127+
<p className="mt-2 text-xs text-red-500">
128+
A single word in your name cannot exceed 30 characters.
129+
</p>
130+
)}
118131
</div>
119132

120133
{/* Avatar Grid */}
@@ -128,18 +141,16 @@ export const AvatarSelectionStep: React.FC<AvatarNameSelectionStepProps> = ({
128141
type="button"
129142
key={avatar}
130143
onClick={() => handleAvatarSelect(avatar)}
131-
className={`bg-background relative inline-flex h-20 w-20 items-center justify-center rounded-full transition-all duration-300 ${
132-
isSelected
144+
className={`bg-background relative inline-flex h-20 w-20 items-center justify-center rounded-full transition-all duration-300 ${isSelected
133145
? 'border-primary ring-primary ring-offset-background ring-2 ring-offset-2'
134146
: 'border-muted'
135-
}`}
147+
}`}
136148
>
137149
<img
138150
src={avatar}
139151
alt="Avatar"
140-
className={`h-20 w-20 rounded-full object-cover transition-all duration-300 ${
141-
isSelected ? 'scale-105' : ''
142-
}`}
152+
className={`h-20 w-20 rounded-full object-cover transition-all duration-300 ${isSelected ? 'scale-105' : ''
153+
}`}
143154
/>
144155
</button>
145156
);
@@ -152,7 +163,7 @@ export const AvatarSelectionStep: React.FC<AvatarNameSelectionStepProps> = ({
152163
<Button
153164
className="cursor-pointer px-4 py-1 text-sm"
154165
onClick={handleNextClick}
155-
disabled={!name || !selectedAvatar}
166+
disabled={!name || !selectedAvatar || longWordError}
156167
>
157168
Next
158169
</Button>

frontend/src/pages/SettingsPage/components/AccountSettingsCard.tsx

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ const AccountSettingsCard: React.FC = () => {
1919
return avatars.includes(stored) ? stored : '';
2020
});
2121
const [nameError, setNameError] = useState(false);
22+
const [longWordError, setLongWordError] = useState(false);
2223

2324
// The redundant useEffect has been removed.
2425

@@ -27,10 +28,15 @@ const AccountSettingsCard: React.FC = () => {
2728
};
2829

2930
const handleNameChange = (value: string) => {
30-
setLocalName(value);
31-
if (nameError) {
32-
setNameError(false);
31+
const words = value.split(' ');
32+
const hasLongWord = words.some((word) => word.length > 30);
33+
if (hasLongWord) {
34+
setLongWordError(true);
35+
return;
3336
}
37+
setLongWordError(false);
38+
setLocalName(value);
39+
if (nameError) setNameError(false);
3440
};
3541

3642
const handleSave = () => {
@@ -72,12 +78,16 @@ const AccountSettingsCard: React.FC = () => {
7278
}
7379
value={name}
7480
onChange={(e) => handleNameChange(e.target.value)}
75-
className={`h-10 w-full text-sm placeholder:text-sm ${
76-
nameError
77-
? 'border-red-500 placeholder:text-red-500/80 focus-visible:ring-red-500'
78-
: ''
79-
}`}
81+
className={`h-10 w-full text-sm placeholder:text-sm ${nameError
82+
? 'border-red-500 placeholder:text-red-500/80 focus-visible:ring-red-500'
83+
: ''
84+
}`}
8085
/>
86+
{longWordError && (
87+
<p className="mt-2 text-xs text-red-500">
88+
A single word in your name cannot exceed 30 characters.
89+
</p>
90+
)}
8191
</div>
8292

8393
{/* Avatar Section */}
@@ -91,18 +101,16 @@ const AccountSettingsCard: React.FC = () => {
91101
type="button"
92102
key={avatar}
93103
onClick={() => handleAvatarSelect(avatar)}
94-
className={`bg-background relative inline-flex h-24 w-24 items-center justify-center rounded-full transition-all duration-300 ${
95-
isSelected
96-
? 'ring-offset-background scale-90 ring-2 ring-blue-500 ring-offset-4'
97-
: 'hover:ring-4 hover:ring-blue-500 hover:ring-offset-4'
98-
}`}
104+
className={`bg-background relative inline-flex h-24 w-24 items-center justify-center rounded-full transition-all duration-300 ${isSelected
105+
? 'ring-offset-background scale-90 ring-2 ring-blue-500 ring-offset-4'
106+
: 'hover:ring-4 hover:ring-blue-500 hover:ring-offset-4'
107+
}`}
99108
>
100109
<img
101110
src={avatar}
102111
alt="Avatar"
103-
className={`h-24 w-24 rounded-full object-cover transition-all duration-300 ${
104-
isSelected ? 'brightness-110' : ''
105-
}`}
112+
className={`h-24 w-24 rounded-full object-cover transition-all duration-300 ${isSelected ? 'brightness-110' : ''
113+
}`}
106114
/>
107115
</button>
108116
);

0 commit comments

Comments
 (0)