Signup: require a display name (changeable later), remove skip
Per request, a display name is now mandatory when signing up:
- Removed the "Skip for now" button from the profile step — the only forward
path is Save, which is disabled until a non-empty name is entered.
- Marked the field required (*), added helper copy ("Required — how you'll show
up across SkateSpots. Change it anytime."), and a hint under the button.
- finishSignup guards against an empty/whitespace name (defense-in-depth for
keyboard/Enter), trims the name before publishing kind 0.
- Reworded the step copy: name required, bio + avatar still optional.
Only affects the primary nsec signup dialog (also the endpoint the mnemonic
flow feeds into); the mnemonic dialog has no name step.
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
This commit is contained in:
parent
39afc00b6e
commit
3833625bde
1 changed files with 32 additions and 24 deletions
|
|
@ -152,14 +152,26 @@ const SignupDialog: React.FC<SignupDialogProps> = ({ isOpen, onClose, onComplete
|
|||
};
|
||||
|
||||
const finishSignup = async (skipProfile = false) => {
|
||||
// A display name is mandatory (changeable later). Guard here too so the step
|
||||
// can't be completed without one, even via keyboard/Enter.
|
||||
const trimmedName = profileData.name.trim();
|
||||
if (!skipProfile && !trimmedName) {
|
||||
toast({
|
||||
title: 'Display name required',
|
||||
description: 'Pick a display name so other skaters know who you are. You can change it anytime.',
|
||||
variant: 'destructive',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Mark signup completion time for fallback welcome modal
|
||||
localStorage.setItem('signup_completed', Date.now().toString());
|
||||
|
||||
try {
|
||||
// Publish profile if user provided information
|
||||
if (!skipProfile && (profileData.name || profileData.about || profileData.picture)) {
|
||||
if (!skipProfile && (trimmedName || profileData.about || profileData.picture)) {
|
||||
const metadata: Record<string, string> = {};
|
||||
if (profileData.name) metadata.name = profileData.name;
|
||||
if (trimmedName) metadata.name = trimmedName;
|
||||
if (profileData.about) metadata.about = profileData.about;
|
||||
if (profileData.picture) metadata.picture = profileData.picture;
|
||||
|
||||
|
|
@ -365,11 +377,11 @@ const SignupDialog: React.FC<SignupDialogProps> = ({ isOpen, onClose, onComplete
|
|||
|
||||
<div className='relative z-10 space-y-2'>
|
||||
<p className='text-base font-semibold'>
|
||||
You're in! 🛹 Add a name so skaters know who you are
|
||||
You're in! 🛹 Pick a display name so skaters know who you are
|
||||
</p>
|
||||
|
||||
<p className='text-sm text-muted-foreground'>
|
||||
This is optional — you can skip it and fill it in later.
|
||||
You can change it anytime later. Bio and avatar are optional.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -390,16 +402,22 @@ const SignupDialog: React.FC<SignupDialogProps> = ({ isOpen, onClose, onComplete
|
|||
<div className={`space-y-4 text-left ${isPublishing ? 'opacity-50 pointer-events-none' : ''}`}>
|
||||
<div className='space-y-2'>
|
||||
<label htmlFor='profile-name' className='text-sm font-medium'>
|
||||
Display Name
|
||||
Display Name <span className='text-red-500'>*</span>
|
||||
</label>
|
||||
<Input
|
||||
id='profile-name'
|
||||
value={profileData.name}
|
||||
onChange={(e) => setProfileData(prev => ({ ...prev, name: e.target.value }))}
|
||||
placeholder='Your name'
|
||||
placeholder='e.g. Tony, gnarlyGrind, or your crew name'
|
||||
className='rounded-lg'
|
||||
maxLength={64}
|
||||
required
|
||||
aria-required='true'
|
||||
disabled={isPublishing}
|
||||
/>
|
||||
<p className='text-xs text-muted-foreground'>
|
||||
Required — how you'll show up across SkateSpots. Change it anytime.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className='space-y-2'>
|
||||
|
|
@ -456,12 +474,12 @@ const SignupDialog: React.FC<SignupDialogProps> = ({ isOpen, onClose, onComplete
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{/* Action buttons */}
|
||||
{/* Action button — a display name is required to continue. */}
|
||||
<div className='space-y-3'>
|
||||
<Button
|
||||
className='w-full rounded-full py-4 text-base font-semibold bg-gradient-to-r from-blue-600 to-indigo-600 hover:from-blue-700 hover:to-indigo-700 transform transition-all duration-200 hover:scale-105 shadow-lg disabled:opacity-50 disabled:cursor-not-allowed disabled:transform-none'
|
||||
className='w-full rounded-full py-4 text-base font-semibold bg-gradient-to-r from-blue-600 to-indigo-600 hover:from-blue-700 hover:to-indigo-700 transform transition-all duration-200 hover:scale-105 shadow-lg disabled:opacity-50 disabled:cursor-not-allowed disabled:transform-none disabled:hover:scale-100'
|
||||
onClick={() => finishSignup(false)}
|
||||
disabled={isPublishing || isUploading}
|
||||
disabled={isPublishing || isUploading || !profileData.name.trim()}
|
||||
>
|
||||
{isPublishing ? (
|
||||
<>
|
||||
|
|
@ -476,21 +494,11 @@ const SignupDialog: React.FC<SignupDialogProps> = ({ isOpen, onClose, onComplete
|
|||
)}
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
variant='outline'
|
||||
className='w-full rounded-full py-3 disabled:opacity-50 disabled:cursor-not-allowed'
|
||||
onClick={() => finishSignup(true)}
|
||||
disabled={isPublishing || isUploading}
|
||||
>
|
||||
{isPublishing ? (
|
||||
<>
|
||||
<div className='w-4 h-4 mr-2 border-2 border-current border-t-transparent rounded-full animate-spin' />
|
||||
Setting up account...
|
||||
</>
|
||||
) : (
|
||||
'Skip for now'
|
||||
)}
|
||||
</Button>
|
||||
{!profileData.name.trim() && !isPublishing && (
|
||||
<p className='text-center text-xs text-muted-foreground'>
|
||||
Add a display name to continue.
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
|
|
|||
Loading…
Reference in a new issue