import React, { useState, useEffect, useCallback } from 'react'; import { Avatar } from '../../ui/Avatar'; import { useSpaceStore, getApiForOrigin } from '../../../stores/spaceStore'; interface Ban { spaceId: string; userId: string; reason: string | null; bannedBy: string; createdAt: number; user: { id: string; username: string; displayName?: string | null; avatar?: string | null } | null; moderator: { id: string; username: string; displayName?: string | null } | null; } interface BansPanelProps { spaceId: string; } export function BansPanel({ spaceId }: BansPanelProps) { const spaces = useSpaceStore((s) => s.spaces); const space = spaces.find((s) => s.id === spaceId); const spaceApi = getApiForOrigin(space?._instanceOrigin ?? ''); const [bans, setBans] = useState([]); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(''); const loadBans = useCallback(async () => { try { setIsLoading(true); const data = await spaceApi.spaces.getBans(spaceId); setBans(data); } catch (err) { setError(err instanceof Error ? err.message : 'Failed to load bans'); } finally { setIsLoading(false); } }, [spaceId, spaceApi]); useEffect(() => { loadBans(); }, [loadBans]); const handleUnban = async (userId: string) => { try { await spaceApi.spaces.unban(spaceId, userId); setBans((prev) => prev.filter((b) => b.userId !== userId)); } catch (err) { setError(err instanceof Error ? err.message : 'Failed to unban user'); } }; if (isLoading) { return (
Loading bans...
); } return (
{error && (
{error}
)}

Banned users cannot rejoin this space until unbanned.

{bans.length === 0 ? (
No banned users
) : (
Bans ({bans.length})
{bans.map((ban) => { const displayName = ban.user?.displayName ?? ban.user?.username ?? ban.userId; const moderatorName = ban.moderator?.displayName ?? ban.moderator?.username ?? ban.bannedBy; const bannedDate = new Date(ban.createdAt).toLocaleDateString(); return (
{displayName}
Banned by {moderatorName} on {bannedDate} {ban.reason && ` — ${ban.reason}`}
); })}
)}
); }