diff --git a/src/components/ProfileCard.tsx b/src/components/ProfileCard.tsx index fb10138d..b4f7b32a 100644 --- a/src/components/ProfileCard.tsx +++ b/src/components/ProfileCard.tsx @@ -97,6 +97,12 @@ interface ProfileCardProps { showNip05?: boolean; /** Show NIP-58 badge showcase row (default true). */ showBadges?: boolean; + /** + * Which kind-0 field the editable text slot below the name edits. + * - `'about'` (default): the bio textarea. + * - `'website'`: a single-line website input, replacing the bio entirely. + */ + bioField?: 'about' | 'website'; /** When provided, render an editable profile fields section below bio */ extraFields?: ProfileField[]; onExtraFieldsChange?: (fields: ProfileField[]) => void; @@ -110,6 +116,7 @@ export function ProfileCard({ onRemoveAvatar, showNip05 = true, showBadges = true, + bioField = 'about', extraFields, onExtraFieldsChange, }: ProfileCardProps) { @@ -268,9 +275,23 @@ export function ProfileCard({ )} - {/* Bio */} + {/* Bio — or, when `bioField` is `'website'`, a website input that + takes the bio's place entirely. */}
- {editable ? ( + {bioField === 'website' ? ( + editable ? ( + + ) : metadata.website ? ( +

+ {metadata.website} +

+ ) : null + ) : editable ? ( 0; - const websiteValid = !!sanitizeUrl(draft.website.trim()); - const websiteTouched = draft.website.trim().length > 0; const avatarProvided = draft.picture.trim().length > 0; - const bannerProvided = draft.banner.trim().length > 0; - const canContinue = - nameProvided && websiteValid && avatarProvided && bannerProvided && !isUploading; + const websiteTouched = draft.website.trim().length > 0; + const websiteValid = !websiteTouched || !!sanitizeUrl(draft.website.trim()); + const canContinue = nameProvided && avatarProvided && websiteValid && !isUploading; return (
@@ -172,41 +170,29 @@ export function VerifierIdentityStep({ { if (patch.name !== undefined) onChange({ name: patch.name }); + if (patch.website !== undefined) { + onChange({ website: patch.website as string }); + } }} onPickImage={handlePickImage} + bioField="website" showNip05={false} showBadges={false} />
- {/* Website — a first-class required field for organizations, so it - gets its own labeled input rather than living in ProfileCard's - collapsible extra-fields section. */} -
- - onChange({ website: e.target.value })} - placeholder="https://your-org.org" - aria-required - aria-invalid={websiteTouched && !websiteValid} - /> - {websiteTouched && !websiteValid && ( -

- {t('onboarding.verifier.identity.websiteInvalid')} -

- )} -
+ {/* Website is optional, but if entered it must be a valid https URL. */} + {websiteTouched && !websiteValid && ( +

+ {t('onboarding.verifier.identity.websiteInvalid')} +

+ )} {isUploading && (
diff --git a/src/locales/en.json b/src/locales/en.json index 4384f348..ac388fb9 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -153,8 +153,7 @@ "verifier": { "identity": { "title": "Set up your organization", - "subtitle": "Add your organization's name, website, logo, and a banner. Donors will see these on every campaign you verify.", - "websiteLabel": "Website", + "subtitle": "Add your organization's name and logo. A website and banner are optional. Donors will see these on every campaign you verify.", "websiteInvalid": "Enter a valid website starting with https://", "cropAvatar": "Crop logo", "cropBanner": "Crop banner",