diff --git a/packages/web/src/components/modals/TransferOwnershipModal.tsx b/packages/web/src/components/modals/TransferOwnershipModal.tsx index 32266f1c..49503f73 100644 --- a/packages/web/src/components/modals/TransferOwnershipModal.tsx +++ b/packages/web/src/components/modals/TransferOwnershipModal.tsx @@ -1,14 +1,15 @@ import { useState, useRef, useEffect, useMemo } from 'react'; import ReactDOM from 'react-dom'; -import { useSpaceStore } from '../../stores/spaceStore'; +import type { MemberWithUser } from '@backspace/shared'; +import { useSpaceStore, getApiForOrigin, type TaggedSpace } from '../../stores/spaceStore'; import { useAuthStore } from '../../stores/authStore'; import { useUIStore } from '../../stores/uiStore'; +import { normalizeUserAssets } from '../../utils/assetUrls'; import { Avatar } from '../ui/Avatar'; export function TransferOwnershipModal({ spaceId, onClose }: { spaceId: string; onClose: () => void }) { const modalRef = useRef(null); const space = useSpaceStore((s) => s.spaces.find(sp => sp.id === spaceId)); - const members = useSpaceStore((s) => s.members); const currentUserId = useAuthStore((s) => s.user?.id); const transferOwnership = useSpaceStore((s) => s.transferOwnership); const addToast = useUIStore((s) => s.addToast); @@ -16,6 +17,30 @@ export function TransferOwnershipModal({ spaceId, onClose }: { spaceId: string; const [search, setSearch] = useState(''); const [selectedUserId, setSelectedUserId] = useState(null); const [transferring, setTransferring] = useState(false); + const [members, setMembers] = useState([]); + const [loading, setLoading] = useState(true); + + // Fetch members for the target space on mount (federation-aware) + useEffect(() => { + let cancelled = false; + (async () => { + try { + const origin = (space as TaggedSpace)?._instanceOrigin ?? ''; + const client = getApiForOrigin(origin); + const fetched = await client.spaces.members(spaceId); + if (cancelled) return; + if (origin) { + for (const m of fetched) normalizeUserAssets(m.user, origin); + } + setMembers(fetched); + } catch { + // Space may have been deleted or we lost access + } finally { + if (!cancelled) setLoading(false); + } + })(); + return () => { cancelled = true; }; + }, [spaceId, space]); // Filter members: exclude self, filter by search const filteredMembers = useMemo(() => { @@ -126,7 +151,9 @@ export function TransferOwnershipModal({ spaceId, onClose }: { spaceId: string; />
- {filteredMembers.length === 0 ? ( + {loading ? ( +

Loading members...

+ ) : filteredMembers.length === 0 ? (

No members found

) : ( filteredMembers.map((member) => {