import React, { useEffect, useState, useContext } from 'react'; import { Table, Avatar, Button, Tabs } from 'antd'; import { ColumnsType, SortOrder } from 'antd/lib/table/interface'; import format from 'date-fns/format'; import { UserAddOutlined, UserDeleteOutlined } from '@ant-design/icons'; import { ServerStatusContext } from '../../../utils/server-status-context'; import { FOLLOWERS, FOLLOWERS_PENDING, SET_FOLLOWER_APPROVAL, FOLLOWERS_BLOCKED, fetchData, } from '../../../utils/apis'; import { isEmptyObject } from '../../../utils/format'; const { TabPane } = Tabs; export interface Follower { link: string; username: string; image: string; name: string; timestamp: Date; approved: Date; } export default function FediverseFollowers() { const [followersPending, setFollowersPending] = useState([]); const [followersBlocked, setFollowersBlocked] = useState([]); const [followers, setFollowers] = useState([]); const [totalCount, setTotalCount] = useState(0); const [currentPage, setCurrentPage] = useState(0); const serverStatusData = useContext(ServerStatusContext); const { serverConfig } = serverStatusData || {}; const { federation } = serverConfig; const { isPrivate } = federation; const getFollowers = async () => { try { const limit = 50; const offset = currentPage * limit; const u = `${FOLLOWERS}?offset=${offset}&limit=${limit}`; // Active followers const result = await fetchData(u, { auth: true }); const { results, total } = result; if (isEmptyObject(results)) { setFollowers([]); } else { setTotalCount(total); setFollowers(results); } // Pending follow requests const pendingFollowersResult = await fetchData(FOLLOWERS_PENDING, { auth: true }); if (isEmptyObject(pendingFollowersResult)) { setFollowersPending([]); } else { setFollowersPending(pendingFollowersResult); } // Blocked/rejected followers const blockedFollowersResult = await fetchData(FOLLOWERS_BLOCKED, { auth: true }); if (isEmptyObject(followersBlocked)) { setFollowersBlocked([]); } else { setFollowersBlocked(blockedFollowersResult); } } catch (error) { console.log('==== error', error); } }; useEffect(() => { getFollowers(); }, []); const columns: ColumnsType = [ { title: '', dataIndex: 'image', key: 'image', width: 90, render: image => , }, { title: 'Name', dataIndex: 'name', key: 'name', render: (_, follower) => ( {follower.name || follower.username} ), }, { title: 'URL', dataIndex: 'link', key: 'link', render: (_, follower) => ( {follower.link} ), }, ]; function makeTable(data: Follower[], tableColumns: ColumnsType) { return ( row.link} pagination={{ pageSize: 50, hideOnSinglePage: true, showSizeChanger: false, total: totalCount, }} onChange={pagination => { const page = pagination.current; setCurrentPage(page); }} /> ); } async function approveFollowRequest(request) { try { await fetchData(SET_FOLLOWER_APPROVAL, { auth: true, method: 'POST', data: { actorIRI: request.link, approved: true, }, }); // Refetch and update the current data. getFollowers(); } catch (err) { console.error(err); } } async function rejectFollowRequest(request) { try { await fetchData(SET_FOLLOWER_APPROVAL, { auth: true, method: 'POST', data: { actorIRI: request.link, approved: false, }, }); // Refetch and update the current data. getFollowers(); } catch (err) { console.error(err); } } const pendingColumns: ColumnsType = [...columns]; pendingColumns.unshift( { title: 'Approve', dataIndex: null, key: null, render: request => (