import { useEffect, useState } from 'react'; import { Loader2, EyeOff, Globe } from 'lucide-react'; import { Card, CardContent } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { useCurrentUser } from '@/hooks/useCurrentUser'; import { useCollectiveMembers } from '@/hooks/useCollectiveMembers'; import { useConfirmMembership } from '@/hooks/useMembershipAttestation'; import { useToast } from '@/hooks/useToast'; import { VisibilityPicker } from '@/components/ConfirmMembershipCard'; import { cn } from '@/lib/utils'; import type { MemberVisibility } from '@/lib/types'; interface Props { kind: number; founderPubkey: string; identifier: string; collectiveName: string; claimedMembers: string[]; accentBg?: string; } /** * Shown to a CONFIRMED member so they can change their visibility (public vs * crew-only) at any time. Re-publishes their kind-1985 attestation with the new * `visibility` tag. Hidden for the founder, non-members, and pending members * (those use the ConfirmMembershipCard instead). */ export function MemberVisibilityControl({ kind, founderPubkey, identifier, collectiveName, claimedMembers, accentBg = 'bg-teal-500 hover:bg-teal-600', }: Props) { const { user } = useCurrentUser(); const { toast } = useToast(); const { mutateAsync: republish, isPending } = useConfirmMembership(); const { data: members } = useCollectiveMembers({ kind, founderPubkey, identifier, claimedMembers, enabled: claimedMembers.length > 0, }); const me = user?.pubkey.toLowerCase(); const mine = members?.find((m) => m.pubkey === me); const [visibility, setVisibility] = useState('public'); // Sync local state to the published value once it loads. useEffect(() => { if (mine?.visibility) setVisibility(mine.visibility); }, [mine?.visibility]); if (!user || !me) return null; if (me === founderPubkey.toLowerCase()) return null; // Only for confirmed members. if (!mine || mine.status !== 'confirmed') return null; const changed = visibility !== (mine.visibility ?? 'public'); const handleSave = async () => { try { await republish({ kind, founderPubkey, identifier, collectiveName, visibility }); toast({ title: 'Visibility updated', description: visibility === 'crew' ? 'You now appear only to crew-mates.' : 'You now appear publicly in this crew.', }); } catch (error) { toast({ title: 'Could not update', description: error instanceof Error ? error.message : 'Please try again.', variant: 'destructive', }); } }; return (
{(mine.visibility ?? 'public') === 'crew' ? ( ) : ( )}

Your visibility in this crew

{changed && ( )}
); }