diff options
author | 2024-04-24 12:12:47 +0200 | |
---|---|---|
committer | 2024-04-24 11:12:47 +0100 | |
commit | 7a1e6394831fb07e303c5ed0900dfe1ea4820de5 (patch) | |
tree | bcd526463b19a85fbe821dcad2276da401daec18 /web/source/settings/admin/accounts | |
parent | [chore]: Bump codeberg.org/gruf/go-mutexes from 1.4.0 to 1.4.1 (#2860) (diff) | |
download | gotosocial-7a1e6394831fb07e303c5ed0900dfe1ea4820de5.tar.xz |
[chore] Refactor settings panel routing (and other fixes) (#2864)
Diffstat (limited to 'web/source/settings/admin/accounts')
-rw-r--r-- | web/source/settings/admin/accounts/detail/actions.tsx | 89 | ||||
-rw-r--r-- | web/source/settings/admin/accounts/detail/handlesignup.tsx | 118 | ||||
-rw-r--r-- | web/source/settings/admin/accounts/detail/index.tsx | 179 | ||||
-rw-r--r-- | web/source/settings/admin/accounts/index.tsx | 49 | ||||
-rw-r--r-- | web/source/settings/admin/accounts/pending/index.tsx | 40 | ||||
-rw-r--r-- | web/source/settings/admin/accounts/search/index.tsx | 125 |
6 files changed, 0 insertions, 600 deletions
diff --git a/web/source/settings/admin/accounts/detail/actions.tsx b/web/source/settings/admin/accounts/detail/actions.tsx deleted file mode 100644 index 75ab8db6e..000000000 --- a/web/source/settings/admin/accounts/detail/actions.tsx +++ /dev/null @@ -1,89 +0,0 @@ -/* - GoToSocial - Copyright (C) GoToSocial Authors admin@gotosocial.org - SPDX-License-Identifier: AGPL-3.0-or-later - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -import React from "react"; - -import { useActionAccountMutation } from "../../../lib/query"; - -import MutationButton from "../../../components/form/mutation-button"; - -import useFormSubmit from "../../../lib/form/submit"; -import { - useValue, - useTextInput, - useBoolInput, -} from "../../../lib/form"; - -import { Checkbox, TextInput } from "../../../components/form/inputs"; -import { AdminAccount } from "../../../lib/types/account"; - -export interface AccountActionsProps { - account: AdminAccount, -} - -export function AccountActions({ account }: AccountActionsProps) { - const form = { - id: useValue("id", account.id), - reason: useTextInput("text") - }; - - const reallySuspend = useBoolInput("reallySuspend"); - const [accountAction, result] = useFormSubmit(form, useActionAccountMutation()); - - return ( - <form - onSubmit={accountAction} - aria-labelledby="account-moderation-actions" - > - <h3 id="account-moderation-actions">Account Moderation Actions</h3> - <div> - Currently only the "suspend" action is implemented.<br/> - Suspending an account will delete it from your server, and remove all of its media, posts, relationships, etc.<br/> - If the suspended account is local, suspending will also send out a "delete" message to other servers, requesting them to remove its data from their instance as well.<br/> - <b>Account suspension cannot be reversed.</b> - </div> - <TextInput - field={form.reason} - placeholder="Reason for this action" - /> - <div className="action-buttons"> - {/* <MutationButton - label="Disable" - name="disable" - result={result} - /> - <MutationButton - label="Silence" - name="silence" - result={result} - /> */} - <MutationButton - disabled={account.suspended || reallySuspend.value === undefined || reallySuspend.value === false} - label="Suspend" - name="suspend" - result={result} - /> - <Checkbox - label="Really suspend" - field={reallySuspend} - ></Checkbox> - </div> - </form> - ); -} diff --git a/web/source/settings/admin/accounts/detail/handlesignup.tsx b/web/source/settings/admin/accounts/detail/handlesignup.tsx deleted file mode 100644 index a61145a22..000000000 --- a/web/source/settings/admin/accounts/detail/handlesignup.tsx +++ /dev/null @@ -1,118 +0,0 @@ -/* - GoToSocial - Copyright (C) GoToSocial Authors admin@gotosocial.org - SPDX-License-Identifier: AGPL-3.0-or-later - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -import React from "react"; -import { useLocation } from "wouter"; - -import { useHandleSignupMutation } from "../../../lib/query"; - -import MutationButton from "../../../components/form/mutation-button"; - -import useFormSubmit from "../../../lib/form/submit"; -import { - useValue, - useTextInput, - useBoolInput, -} from "../../../lib/form"; - -import { Checkbox, Select, TextInput } from "../../../components/form/inputs"; -import { AdminAccount } from "../../../lib/types/account"; - -export interface HandleSignupProps { - account: AdminAccount, - accountsBaseUrl: string, -} - -export function HandleSignup({account, accountsBaseUrl}: HandleSignupProps) { - const form = { - id: useValue("id", account.id), - approveOrReject: useTextInput("approve_or_reject", { defaultValue: "approve" }), - privateComment: useTextInput("private_comment"), - message: useTextInput("message"), - sendEmail: useBoolInput("send_email"), - }; - - const [_location, setLocation] = useLocation(); - - const [handleSignup, result] = useFormSubmit(form, useHandleSignupMutation(), { - changedOnly: false, - // After submitting the form, redirect back to - // /settings/admin/accounts if rejecting, since - // account will no longer be available at - // /settings/admin/accounts/:accountID endpoint. - onFinish: (res) => { - if (form.approveOrReject.value === "approve") { - // An approve request: - // stay on this page and - // serve updated details. - return; - } - - if (res.data) { - // "reject" successful, - // redirect to accounts page. - setLocation(accountsBaseUrl); - } - } - }); - - return ( - <form - onSubmit={handleSignup} - aria-labelledby="account-handle-signup" - > - <h3 id="account-handle-signup">Handle Account Sign-Up</h3> - <Select - field={form.approveOrReject} - label="Approve or Reject" - options={ - <> - <option value="approve">Approve</option> - <option value="reject">Reject</option> - </> - } - > - </Select> - { form.approveOrReject.value === "reject" && - // Only show form fields relevant - // to "reject" if rejecting. - // On "approve" these fields will - // be ignored anyway. - <> - <TextInput - field={form.privateComment} - label="(Optional) private comment on why sign-up was rejected (shown to other admins only)" - /> - <Checkbox - field={form.sendEmail} - label="Send email to applicant" - /> - <TextInput - field={form.message} - label={"(Optional) message to include in email to applicant, if send email is checked"} - /> - </> } - <MutationButton - disabled={false} - label={form.approveOrReject.value === "approve" ? "Approve" : "Reject"} - result={result} - /> - </form> - ); -} diff --git a/web/source/settings/admin/accounts/detail/index.tsx b/web/source/settings/admin/accounts/detail/index.tsx deleted file mode 100644 index 79eb493de..000000000 --- a/web/source/settings/admin/accounts/detail/index.tsx +++ /dev/null @@ -1,179 +0,0 @@ -/* - GoToSocial - Copyright (C) GoToSocial Authors admin@gotosocial.org - SPDX-License-Identifier: AGPL-3.0-or-later - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -import React from "react"; -import { useRoute, Redirect } from "wouter"; - -import { useGetAccountQuery } from "../../../lib/query"; - -import FormWithData from "../../../lib/form/form-with-data"; - -import { useBaseUrl } from "../../../lib/navigation/util"; -import FakeProfile from "../../../components/fake-profile"; - -import { AdminAccount } from "../../../lib/types/account"; -import { HandleSignup } from "./handlesignup"; -import { AccountActions } from "./actions"; -import BackButton from "../../../components/back-button"; - -export default function AccountDetail() { - // /settings/admin/accounts - const accountsBaseUrl = useBaseUrl(); - - let [_match, params] = useRoute(`${accountsBaseUrl}/:accountId`); - - if (params?.accountId == undefined) { - return <Redirect to={accountsBaseUrl} />; - } else { - return ( - <div className="account-detail"> - <h1 className="text-cutoff"> - <BackButton to={accountsBaseUrl} /> Account Details - </h1> - <FormWithData - dataQuery={useGetAccountQuery} - queryArg={params.accountId} - DataForm={AccountDetailForm} - {...{accountsBaseUrl}} - /> - </div> - ); - } -} - -interface AccountDetailFormProps { - accountsBaseUrl: string, - data: AdminAccount, -} - -function AccountDetailForm({ data: adminAcct, accountsBaseUrl }: AccountDetailFormProps) { - let yesOrNo = (b: boolean) => { - return b ? "yes" : "no"; - }; - - let created = new Date(adminAcct.created_at).toDateString(); - let lastPosted = "never"; - if (adminAcct.account.last_status_at) { - lastPosted = new Date(adminAcct.account.last_status_at).toDateString(); - } - const local = !adminAcct.domain; - - return ( - <> - <FakeProfile {...adminAcct.account} /> - <h3>General Account Details</h3> - { adminAcct.suspended && - <div className="info"> - <i className="fa fa-fw fa-info-circle" aria-hidden="true"></i> - <b>Account is suspended.</b> - </div> - } - <dl className="info-list"> - { !local && - <div className="info-list-entry"> - <dt>Domain</dt> - <dd>{adminAcct.domain}</dd> - </div>} - <div className="info-list-entry"> - <dt>Created</dt> - <dd><time dateTime={adminAcct.created_at}>{created}</time></dd> - </div> - <div className="info-list-entry"> - <dt>Last posted</dt> - <dd>{lastPosted}</dd> - </div> - <div className="info-list-entry"> - <dt>Suspended</dt> - <dd>{yesOrNo(adminAcct.suspended)}</dd> - </div> - <div className="info-list-entry"> - <dt>Silenced</dt> - <dd>{yesOrNo(adminAcct.silenced)}</dd> - </div> - <div className="info-list-entry"> - <dt>Statuses</dt> - <dd>{adminAcct.account.statuses_count}</dd> - </div> - <div className="info-list-entry"> - <dt>Followers</dt> - <dd>{adminAcct.account.followers_count}</dd> - </div> - <div className="info-list-entry"> - <dt>Following</dt> - <dd>{adminAcct.account.following_count}</dd> - </div> - </dl> - { local && - // Only show local account details - // if this is a local account! - <> - <h3>Local Account Details</h3> - { !adminAcct.approved && - <div className="info"> - <i className="fa fa-fw fa-info-circle" aria-hidden="true"></i> - <b>Account is pending.</b> - </div> - } - { !adminAcct.confirmed && - <div className="info"> - <i className="fa fa-fw fa-info-circle" aria-hidden="true"></i> - <b>Account email not yet confirmed.</b> - </div> - } - <dl className="info-list"> - <div className="info-list-entry"> - <dt>Email</dt> - <dd>{adminAcct.email} {<b>{adminAcct.confirmed ? "(confirmed)" : "(not confirmed)"}</b> }</dd> - </div> - <div className="info-list-entry"> - <dt>Disabled</dt> - <dd>{yesOrNo(adminAcct.disabled)}</dd> - </div> - <div className="info-list-entry"> - <dt>Approved</dt> - <dd>{yesOrNo(adminAcct.approved)}</dd> - </div> - <div className="info-list-entry"> - <dt>Sign-Up Reason</dt> - <dd>{adminAcct.invite_request ?? <i>none provided</i>}</dd> - </div> - { (adminAcct.ip && adminAcct.ip !== "0.0.0.0") && - <div className="info-list-entry"> - <dt>Sign-Up IP</dt> - <dd>{adminAcct.ip}</dd> - </div> } - { adminAcct.locale && - <div className="info-list-entry"> - <dt>Locale</dt> - <dd>{adminAcct.locale}</dd> - </div> } - </dl> - </> } - { local && !adminAcct.approved - ? - <HandleSignup - account={adminAcct} - accountsBaseUrl={accountsBaseUrl} - /> - : - <AccountActions account={adminAcct} /> - } - </> - ); -} diff --git a/web/source/settings/admin/accounts/index.tsx b/web/source/settings/admin/accounts/index.tsx deleted file mode 100644 index 3c69f7406..000000000 --- a/web/source/settings/admin/accounts/index.tsx +++ /dev/null @@ -1,49 +0,0 @@ -/* - GoToSocial - Copyright (C) GoToSocial Authors admin@gotosocial.org - SPDX-License-Identifier: AGPL-3.0-or-later - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -import React from "react"; -import { Switch, Route } from "wouter"; - -import AccountDetail from "./detail"; -import { AccountSearchForm } from "./search"; - -export default function Accounts({ baseUrl }) { - return ( - <Switch> - <Route path={`${baseUrl}/:accountId`}> - <AccountDetail /> - </Route> - <AccountOverview /> - </Switch> - ); -} - -function AccountOverview({ }) { - return ( - <div className="accounts-view"> - <h1>Accounts Overview</h1> - <span> - You can perform actions on an account by clicking - its name in a report, or by searching for the account - using the form below and clicking on its name. - </span> - <AccountSearchForm /> - </div> - ); -} diff --git a/web/source/settings/admin/accounts/pending/index.tsx b/web/source/settings/admin/accounts/pending/index.tsx deleted file mode 100644 index 459472147..000000000 --- a/web/source/settings/admin/accounts/pending/index.tsx +++ /dev/null @@ -1,40 +0,0 @@ -/* - GoToSocial - Copyright (C) GoToSocial Authors admin@gotosocial.org - SPDX-License-Identifier: AGPL-3.0-or-later - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -import React from "react"; -import { useSearchAccountsQuery } from "../../../lib/query"; -import { AccountList } from "../../../components/account-list"; - -export default function AccountsPending() { - const searchRes = useSearchAccountsQuery({status: "pending"}); - - return ( - <div className="accounts-view"> - <h1>Pending Accounts</h1> - <AccountList - isLoading={searchRes.isLoading} - isSuccess={searchRes.isSuccess} - data={searchRes.data} - isError={searchRes.isError} - error={searchRes.error} - emptyMessage="No pending account sign-ups." - /> - </div> - ); -} diff --git a/web/source/settings/admin/accounts/search/index.tsx b/web/source/settings/admin/accounts/search/index.tsx deleted file mode 100644 index 560bbb76a..000000000 --- a/web/source/settings/admin/accounts/search/index.tsx +++ /dev/null @@ -1,125 +0,0 @@ -/* - GoToSocial - Copyright (C) GoToSocial Authors admin@gotosocial.org - SPDX-License-Identifier: AGPL-3.0-or-later - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -import React from "react"; - -import { useLazySearchAccountsQuery } from "../../../lib/query"; -import { useTextInput } from "../../../lib/form"; - -import { AccountList } from "../../../components/account-list"; -import { SearchAccountParams } from "../../../lib/types/account"; -import { Select, TextInput } from "../../../components/form/inputs"; -import MutationButton from "../../../components/form/mutation-button"; - -export function AccountSearchForm() { - const [searchAcct, searchRes] = useLazySearchAccountsQuery(); - - const form = { - origin: useTextInput("origin"), - status: useTextInput("status"), - permissions: useTextInput("permissions"), - username: useTextInput("username"), - display_name: useTextInput("display_name"), - by_domain: useTextInput("by_domain"), - email: useTextInput("email"), - ip: useTextInput("ip"), - }; - - function submitSearch(e) { - e.preventDefault(); - - // Parse query parameters. - const entries = Object.entries(form).map(([k, v]) => { - // Take only defined form fields. - if (v.value === undefined || v.value.length === 0) { - return null; - } - return [[k, v.value]]; - }).flatMap(kv => { - // Remove any nulls. - return kv || []; - }); - - const params: SearchAccountParams = Object.fromEntries(entries); - searchAcct(params); - } - - return ( - <> - <form onSubmit={submitSearch}> - <TextInput - field={form.username} - label={"(Optional) username (without leading '@' symbol)"} - placeholder="someone" - /> - <TextInput - field={form.by_domain} - label={"(Optional) domain"} - placeholder="example.org" - /> - <Select - field={form.origin} - label="Account origin" - options={ - <> - <option value="">Local or remote</option> - <option value="local">Local only</option> - <option value="remote">Remote only</option> - </> - } - ></Select> - <TextInput - field={form.email} - label={"(Optional) email address (local accounts only)"} - placeholder={"someone@example.org"} - /> - <TextInput - field={form.ip} - label={"(Optional) IP address (local accounts only)"} - placeholder={"198.51.100.0"} - /> - <Select - field={form.status} - label="Account status" - options={ - <> - <option value="">Any</option> - <option value="pending">Pending only</option> - <option value="disabled">Disabled only</option> - <option value="suspended">Suspended only</option> - </> - } - ></Select> - <MutationButton - disabled={false} - label={"Search"} - result={searchRes} - /> - </form> - <AccountList - isLoading={searchRes.isLoading} - isSuccess={searchRes.isSuccess} - data={searchRes.data} - isError={searchRes.isError} - error={searchRes.error} - emptyMessage="No accounts found that match your query" - /> - </> - ); -} |