- {media.map((m) => (
-
- {sensitive && <>
-
-
-
-
-
-
-
-
-
- >}
-
-
-
-
- ))}
+
+
Reported Statuses
+
+ { report.statuses.map((status) => {
+ return (
+
+ );
+ })}
+
);
}
diff --git a/web/source/settings/views/moderation/reports/overview.tsx b/web/source/settings/views/moderation/reports/overview.tsx
deleted file mode 100644
index 18eb5492a..000000000
--- a/web/source/settings/views/moderation/reports/overview.tsx
+++ /dev/null
@@ -1,97 +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
.
-*/
-
-import React from "react";
-import { Link } from "wouter";
-import FormWithData from "../../../lib/form/form-with-data";
-import Username from "../../../components/username";
-import { useListReportsQuery } from "../../../lib/query/admin/reports";
-
-export function ReportOverview({ }) {
- return (
-
- );
-}
-
-function ReportsList({ data: reports }) {
- return (
-
-
-
- {reports.map((report) => (
-
- ))}
-
-
- );
-}
-
-function ReportEntry({ report }) {
- const from = report.account;
- const target = report.target_account;
-
- let comment = report.comment.length > 200
- ? report.comment.slice(0, 200) + "..."
- : report.comment;
-
- return (
-
-
-
-
- reported
-
-
- {report.action_taken ? "Resolved" : "Open"}
-
-
-
-
Created:
-
{new Date(report.created_at).toLocaleString()}
-
-
Reason:
- {comment.length > 0
- ?
{comment}
- :
none provided
- }
-
-
-
- );
-}
diff --git a/web/source/settings/views/moderation/reports/search.tsx b/web/source/settings/views/moderation/reports/search.tsx
new file mode 100644
index 000000000..da0c80d69
--- /dev/null
+++ b/web/source/settings/views/moderation/reports/search.tsx
@@ -0,0 +1,252 @@
+/*
+ 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
.
+*/
+
+import React, { ReactNode, useEffect, useMemo } from "react";
+
+import { useLazySearchReportsQuery } from "../../../lib/query/admin/reports";
+import { useTextInput } from "../../../lib/form";
+import { PageableList } from "../../../components/pageable-list";
+import { Select } from "../../../components/form/inputs";
+import MutationButton from "../../../components/form/mutation-button";
+import { useLocation, useSearch } from "wouter";
+import Username from "../../../components/username";
+import { AdminReport } from "../../../lib/types/report";
+
+export default function ReportsSearch() {
+ return (
+
+
Reports Search
+
+ You can use the form below to search through reports
+ created by, or directed towards, accounts on this instance.
+
+
+
+ );
+}
+
+function ReportSearchForm() {
+ const [ location, setLocation ] = useLocation();
+ const search = useSearch();
+ const urlQueryParams = useMemo(() => new URLSearchParams(search), [search]);
+ const hasParams = urlQueryParams.size != 0;
+ const [ searchReports, searchRes ] = useLazySearchReportsQuery();
+
+ // Populate search form using values from
+ // urlQueryParams, to allow paging.
+ const resolved = useMemo(() => {
+ const resolvedRaw = urlQueryParams.get("resolved");
+ if (resolvedRaw !== null) {
+ return resolvedRaw;
+ }
+ }, [urlQueryParams]);
+
+ const form = {
+ resolved: useTextInput("resolved", { defaultValue: resolved }),
+ account_id: useTextInput("account_id", { defaultValue: urlQueryParams.get("account_id") ?? "" }),
+ target_account_id: useTextInput("target_account_id", { defaultValue: urlQueryParams.get("target_account_id") ?? "" }),
+ limit: useTextInput("limit", { defaultValue: urlQueryParams.get("limit") ?? "20" })
+ };
+
+ const setResolved = form.resolved.setter;
+
+ // On mount, if urlQueryParams were provided,
+ // trigger the search. For example, if page
+ // was accessed at /search?origin=local&limit=20,
+ // then run a search with origin=local and
+ // limit=20 and immediately render the results.
+ //
+ // If no urlQueryParams set, use the default
+ // search (just show unresolved reports).
+ useEffect(() => {
+ if (hasParams) {
+ searchReports(Object.fromEntries(urlQueryParams));
+ } else {
+ setResolved("false");
+ setLocation(location + "?resolved=false");
+ }
+ }, [
+ urlQueryParams,
+ hasParams,
+ searchReports,
+ location,
+ setLocation,
+ setResolved,
+ ]);
+
+ // Rather than triggering the search directly,
+ // the "submit" button changes the location
+ // based on form field params, and lets the
+ // useEffect hook above actually do the search.
+ function submitQuery(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 || v.value === "any") {
+ return null;
+ }
+ return [[k, v.value]];
+ }).flatMap(kv => {
+ // Remove any nulls.
+ return kv || [];
+ });
+
+ const searchParams = new URLSearchParams(entries);
+ setLocation(location + "?" + searchParams.toString());
+ }
+
+ // Location to return to when user clicks "back" on the detail view.
+ const backLocation = location + (hasParams ? `?${urlQueryParams}` : "");
+
+ // Function to map an item to a list entry.
+ function itemToEntry(report: AdminReport): ReactNode {
+ return (
+
+ );
+ }
+
+ return (
+ <>
+
+
No reports found that match your query.}
+ prevNextLinks={searchRes.data?.links}
+ />
+ >
+ );
+}
+
+interface ReportEntryProps {
+ report: AdminReport;
+ linkTo: string;
+ backLocation: string;
+}
+
+function ReportListEntry({ report, linkTo, backLocation }: ReportEntryProps) {
+ const [ _location, setLocation ] = useLocation();
+
+ const from = report.account;
+ const target = report.target_account;
+ const comment = report.comment;
+ const status = report.action_taken ? "Resolved" : "Unresolved";
+ const created = new Date(report.created_at).toLocaleString();
+ const title = `${status}. @${target.account.acct} was reported by @${from.account.acct} on ${created}. Reason: "${comment}"`;
+
+ return (
+ {
+ // When clicking on a report, direct
+ // to the detail view for that report.
+ setLocation(linkTo, {
+ // Store the back location in history so
+ // the detail view can use it to return to
+ // this page (including query parameters).
+ state: { backLocation: backLocation }
+ });
+ }}
+ role="link"
+ tabIndex={0}
+ >
+
+
+
- Reported account:
+ -
+
+
+
+
+
+
- Reported by:
+ -
+
+
+
+
+
+
- Status:
+ -
+ { report.action_taken
+ ? <>{status}>
+ : {status}
+ }
+
+
+
+
+
- Reason:
+ -
+ { comment.length > 0
+ ? <>{comment}>
+ : none provided
+ }
+
+
+
+
+
- Created:
+ -
+
+
+
+
+
+ );
+}
diff --git a/web/source/settings/views/moderation/router.tsx b/web/source/settings/views/moderation/router.tsx
index d23ab336a..93f7e481a 100644
--- a/web/source/settings/views/moderation/router.tsx
+++ b/web/source/settings/views/moderation/router.tsx
@@ -20,7 +20,7 @@
import React from "react";
import { BaseUrlContext, useBaseUrl, useHasPermission } from "../../lib/navigation/util";
import { Redirect, Route, Router, Switch } from "wouter";
-import { ReportOverview } from "./reports/overview";
+import ReportsSearch from "./reports/search";
import ReportDetail from "./reports/detail";
import { ErrorBoundary } from "../../lib/navigation/error";
import ImportExport from "./domain-permissions/import-export";
@@ -85,8 +85,9 @@ function ModerationReportsRouter() {
+
-
+
diff --git a/web/source/settings/views/user/profile.tsx b/web/source/settings/views/user/profile.tsx
index c1735259e..a65405faa 100644
--- a/web/source/settings/views/user/profile.tsx
+++ b/web/source/settings/views/user/profile.tsx
@@ -39,7 +39,7 @@ import {
} from "../../components/form/inputs";
import FormWithData from "../../lib/form/form-with-data";
-import FakeProfile from "../../components/fake-profile";
+import FakeProfile from "../../components/profile";
import MutationButton from "../../components/form/mutation-button";
import { useAccountThemesQuery } from "../../lib/query/user";
--
cgit v1.2.3