diff --git a/src/components/CraftProfileForm.tsx b/src/components/CraftProfileForm.tsx index 17d2fd2..eb9395b 100644 --- a/src/components/CraftProfileForm.tsx +++ b/src/components/CraftProfileForm.tsx @@ -1,4 +1,4 @@ -import { useState } from 'react'; +import { useState, useEffect } from 'react'; import { useNavigate, Link } from 'react-router-dom'; import ngeohash from 'ngeohash'; import { nip19 } from 'nostr-tools'; @@ -21,6 +21,7 @@ import { EntityTypeField } from '@/components/EntityTypeField'; import { CrewLinkField } from '@/components/CrewLinkField'; import { LabProUpgrade } from '@/components/LabProUpgrade'; import { usePlatformFee } from '@/hooks/usePlatformFee'; +import { useMyLabProfileEvent } from '@/hooks/useMyLabProfile'; import { isValidNoffer, type EntityType } from '@/lib/types'; import { cn } from '@/lib/utils'; import { Upload, X, Loader2, ArrowLeft, MapPin } from 'lucide-react'; @@ -117,6 +118,38 @@ export function CraftProfileForm({ config }: { config: CraftFormConfig }) { const [crewRef, setCrewRef] = useState(undefined); const [extras, setExtras] = useState>({}); const [isGettingLocation, setIsGettingLocation] = useState(false); + const [titleInput, setTitleInput] = useState(''); + const [prefilled, setPrefilled] = useState(false); + + // Load + prefill an existing profile so this is an EDIT, not a blind overwrite. + const { data: existingProfile } = useMyLabProfileEvent(kind, identifier); + useEffect(() => { + if (prefilled || !existingProfile) return; + setPrefilled(true); + const tag = (n: string) => existingProfile.tags.find(([t]) => t === n)?.[1]; + setTitleInput(tag('title') ?? ''); + setBio(existingProfile.content ?? ''); + setLocation(tag('location') ?? ''); + setSelected(existingProfile.tags.filter(([t, v]) => t === 't' && v !== selfTag).map(([, v]) => v)); + setImage(tag('image') ?? null); + setExperience(tag('experience') ?? ''); + setRate(tag('rate') ?? ''); + setPhone(tag('phone') ?? ''); + setEmail(tag('email') ?? ''); + setWebsite(tag('website') ?? ''); + setPortfolio(tag('portfolio') ?? ''); + setSocial(tag('social') ?? ''); + setNoffer(tag('noffer') ?? ''); + setEntityType((tag('entity') as EntityType) ?? 'individual'); + setMembers(existingProfile.tags.filter(([t]) => t === 'p').map(([, v]) => v)); + setCrewRef(existingProfile.tags.find(([t]) => t === 'a')?.[1]); + const ex: Record = {}; + for (const f of extraFields) { + const v = tag(f.tag); + if (v !== undefined) ex[f.tag] = v; + } + setExtras(ex); + }, [existingProfile, prefilled, selfTag, extraFields]); const getDisplayName = () => { if (author.data?.metadata?.name) return author.data.metadata.name; @@ -184,7 +217,7 @@ export function CraftProfileForm({ config }: { config: CraftFormConfig }) { const displayName = getDisplayName(); const tags: string[][] = [ ['d', identifier], - ['title', displayName], + ['title', titleInput.trim() || displayName], ['t', selfTag], ['alt', `Skate ${noun}: ${displayName}`], ]; @@ -228,7 +261,7 @@ export function CraftProfileForm({ config }: { config: CraftFormConfig }) { if (isPro && goPro && featuredUntilSeconds) tags.push(['featured', String(featuredUntilSeconds)]); await createEvent({ kind, content: bio.trim(), tags }); - toast({ title: `${heading.replace(/^Become an?/, '').trim()} profile created!`, description: 'Your profile has been published.' }); + toast({ title: `${heading.replace(/^Become an?/, '').trim()} profile ${existingProfile ? 'updated' : 'created'}!`, description: 'Your profile has been published.' }); navigate(`/coach/${user?.pubkey}/${identifier}`); } catch (error) { toast({ title: 'Failed to publish', description: error instanceof Error ? error.message : 'Error', variant: 'destructive' }); @@ -298,6 +331,12 @@ export function CraftProfileForm({ config }: { config: CraftFormConfig }) { )} + {existingProfile && ( +

+ Editing your existing {noun} profile — publishing replaces it. +

+ )} +
{/* Image + Bio */} @@ -325,6 +364,21 @@ export function CraftProfileForm({ config }: { config: CraftFormConfig }) { +
+ + setTitleInput(e.target.value)} + placeholder={getDisplayName()} + maxLength={120} + className="mt-1.5 bg-white/5 border-white/10" + /> +

+ Shown as the title on your Lab card — e.g. “Skate Coach Berlin”. Defaults to your name. +

+
+