diff --git a/src/components/EditProfileForm.tsx b/src/components/EditProfileForm.tsx index fe532b9..3b54f61 100644 --- a/src/components/EditProfileForm.tsx +++ b/src/components/EditProfileForm.tsx @@ -20,7 +20,7 @@ import { Input } from '@/components/ui/input'; import { Textarea } from '@/components/ui/textarea'; import { Switch } from '@/components/ui/switch'; import { Label } from '@/components/ui/label'; -import { Loader2, Upload, Zap, ShieldCheck, AlertCircle, Bitcoin, Award, MessageSquareLock, UserRound, X, Plus, Bot, BadgeCheck, HelpCircle, Server, AtSign } from 'lucide-react'; +import { Loader2, Upload, Zap, ShieldCheck, AlertCircle, Bitcoin, Award, MessageSquareLock, UserRound, Handshake, X, Plus, Bot, BadgeCheck, HelpCircle, Server, AtSign } from 'lucide-react'; import { NSchema as n, type NostrMetadata } from '@nostrify/nostrify'; import { useQueryClient } from '@tanstack/react-query'; import { useUploadFile } from '@/hooks/useUploadFile'; @@ -72,6 +72,8 @@ export const EditProfileForm: React.FC = () => { // pointer formats as Settings → Coordinator (nprofile / cordn.net link / // npub / hex) as well as an http(s) URL — this is the discovery field. const [cordn, setCordn] = useState(''); + const [openToSponsorships, setOpenToSponsorships] = useState(false); + const [sponsorNote, setSponsorNote] = useState(''); // Extra personal NIP-05 handles — stored in a separate kind-30078 record so // another client re-saving the profile can't drop them. @@ -131,6 +133,8 @@ export const EditProfileForm: React.FC = () => { ); } if (typeof raw.cordn === 'string') setCordn(raw.cordn); + setOpenToSponsorships(raw.sponsorships_open === true); + if (typeof raw.sponsorships_note === 'string') setSponsorNote(raw.sponsorships_note); } }, [metadata, form]); @@ -252,6 +256,17 @@ export const EditProfileForm: React.FC = () => { // Retire the legacy field now that badges supersede it. delete data.sponsors; + // Sponsorship opt-in (custom kind-0 fields). The profile only claims + // this when the skater explicitly turned it on. + if (openToSponsorships) { + data.sponsorships_open = true; + if (sponsorNote.trim()) data.sponsorships_note = sponsorNote.trim(); + else delete data.sponsorships_note; + } else { + delete data.sponsorships_open; + delete data.sponsorships_note; + } + // Cordn contact link (custom field). if (cordnTrimmed) { // Normalise a bare pointer (nprofile/npub/hex) to Cordn's canonical @@ -402,6 +417,41 @@ export const EditProfileForm: React.FC = () => { )} /> + {/* Sponsorship opt-in — explicit consent, never inferred from activity. */} +
+
+
+ +

+ {t('settingsUi.editProfile.openToSponsorshipsHint')} +

+
+ +
+ {openToSponsorships && ( +
+ +