diff --git a/thoughts-frontend/components/federation/pending-requests.tsx b/thoughts-frontend/components/federation/pending-requests.tsx new file mode 100644 index 0000000..57dd975 --- /dev/null +++ b/thoughts-frontend/components/federation/pending-requests.tsx @@ -0,0 +1,90 @@ +"use client"; + +import { useEffect, useState } from "react"; +import { + getPendingFollowRequests, + acceptFollowRequest, + rejectFollowRequest, + type RemoteActor, +} from "@/lib/api"; +import { useAuth } from "@/hooks/use-auth"; +import { UserAvatar } from "@/components/user-avatar"; +import { Button } from "@/components/ui/button"; +import { toast } from "sonner"; + +interface Props { + compact?: boolean; +} + +export function PendingRequests({ compact = false }: Props) { + const { token } = useAuth(); + const [requests, setRequests] = useState([]); + const [loading, setLoading] = useState(true); + + useEffect(() => { + if (!token) return; + getPendingFollowRequests(token) + .then(setRequests) + .catch(() => toast.error("Failed to load follow requests")) + .finally(() => setLoading(false)); + }, [token]); + + const accept = async (actorUrl: string) => { + if (!token) return; + setRequests((prev) => prev.filter((r) => r.url !== actorUrl)); + await acceptFollowRequest(actorUrl, token).catch(() => { + toast.error("Failed to accept follow request"); + }); + }; + + const reject = async (actorUrl: string) => { + if (!token) return; + setRequests((prev) => prev.filter((r) => r.url !== actorUrl)); + await rejectFollowRequest(actorUrl, token).catch(() => { + toast.error("Failed to reject follow request"); + }); + }; + + if (loading) return

Loading…

; + if (requests.length === 0) + return

No pending requests.

; + + return ( + + ); +}