overview.js (3380B)
1 /* 2 GoToSocial 3 Copyright (C) GoToSocial Authors admin@gotosocial.org 4 SPDX-License-Identifier: AGPL-3.0-or-later 5 6 This program is free software: you can redistribute it and/or modify 7 it under the terms of the GNU Affero General Public License as published by 8 the Free Software Foundation, either version 3 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU Affero General Public License for more details. 15 16 You should have received a copy of the GNU Affero General Public License 17 along with this program. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 "use strict"; 21 22 const React = require("react"); 23 const { Link, useLocation } = require("wouter"); 24 const { matchSorter } = require("match-sorter"); 25 26 const { useTextInput } = require("../../lib/form"); 27 28 const { TextInput } = require("../../components/form/inputs"); 29 30 const query = require("../../lib/query"); 31 32 const Loading = require("../../components/loading"); 33 34 module.exports = function InstanceOverview({ baseUrl }) { 35 const { data: blockedInstances = [], isLoading } = query.useInstanceBlocksQuery(); 36 37 const [_location, setLocation] = useLocation(); 38 39 const filterField = useTextInput("filter"); 40 const filter = filterField.value; 41 42 const blockedInstancesList = React.useMemo(() => { 43 return Object.values(blockedInstances); 44 }, [blockedInstances]); 45 46 const filteredInstances = React.useMemo(() => { 47 return matchSorter(blockedInstancesList, filter, { keys: ["domain"] }); 48 }, [blockedInstancesList, filter]); 49 50 let filtered = blockedInstancesList.length - filteredInstances.length; 51 52 function filterFormSubmit(e) { 53 e.preventDefault(); 54 setLocation(`${baseUrl}/${filter}`); 55 } 56 57 if (isLoading) { 58 return <Loading />; 59 } 60 61 return ( 62 <> 63 <h1>Federation</h1> 64 65 <div className="instance-list"> 66 <h2>Suspended instances</h2> 67 <p> 68 Suspending a domain blocks all current and future accounts on that instance. Stored content will be removed, 69 and no more data is sent to the remote server.<br /> 70 This extends to all subdomains as well, so blocking 'example.com' also includes 'social.example.com'. 71 </p> 72 <form className="filter" role="search" onSubmit={filterFormSubmit}> 73 <TextInput field={filterField} placeholder="example.com" label="Search or add domain suspension" /> 74 <Link to={`${baseUrl}/${filter}`}><a className="button">Suspend</a></Link> 75 </form> 76 <div> 77 <span> 78 {blockedInstancesList.length} blocked instance{blockedInstancesList.length != 1 ? "s" : ""} {filtered > 0 && `(${filtered} filtered by search)`} 79 </span> 80 <div className="list"> 81 <div className="entries scrolling"> 82 {filteredInstances.map((entry) => { 83 return ( 84 <Link key={entry.domain} to={`${baseUrl}/${entry.domain}`}> 85 <a className="entry nounderline"> 86 <span id="domain"> 87 {entry.domain} 88 </span> 89 <span id="date"> 90 {new Date(entry.created_at).toLocaleString()} 91 </span> 92 </a> 93 </Link> 94 ); 95 })} 96 </div> 97 </div> 98 </div> 99 </div> 100 <Link to={`${baseUrl}/import-export`}><a>Or use the bulk import/export interface</a></Link> 101 </> 102 ); 103 };