+function postViewToCombined(data: PostView): Combined {
+ return {
+ type_: "posts",
+ data,
+ published: data.post.published,
+ };
+}
+
+function commentViewToCombined(data: CommentView): Combined {
+ return {
+ type_: "comments",
+ data,
+ published: data.comment.published,
+ };
+}
+
+function communityViewToCombined(data: CommunityView): Combined {
+ return {
+ type_: "communities",
+ data,
+ published: data.community.published,
+ };
+}
+
+function personViewSafeToCombined(data: PersonView): Combined {
+ return {
+ type_: "users",
+ data,
+ published: data.person.published,
+ };
+}
+
+const Filter = ({
+ filterType,
+ options,
+ onChange,
+ onSearch,
+ value,
+ loading,
+}: {
+ filterType: FilterType;
+ options: Choice[];
+ onSearch: (text: string) => void;
+ onChange: (choice: Choice) => void;
+ value?: number | null;
+ loading: boolean;
+}) => {
+ return (
+ <div className="col-sm-6">
+ <label className="mb-1" htmlFor={`${filterType}-filter`}>
+ {capitalizeFirstLetter(I18NextService.i18n.t(filterType))}
+ </label>
+ <SearchableSelect
+ id={`${filterType}-filter`}
+ options={[
+ {
+ label: I18NextService.i18n.t("all"),
+ value: "0",
+ },
+ ].concat(options)}
+ value={value ?? 0}
+ onSearch={onSearch}
+ onChange={onChange}
+ loading={loading}
+ />
+ </div>
+ );
+};
+
+const communityListing = ({
+ community,
+ counts: { subscribers },
+}: CommunityView) =>
+ getListing(
+ <CommunityLink community={community} />,
+ subscribers,
+ "number_of_subscribers"
+ );
+
+const personListing = ({ person, counts: { comment_count } }: PersonView) =>
+ getListing(
+ <PersonListing person={person} showApubName />,
+ comment_count,
+ "number_of_comments"
+ );
+
+function getListing(
+ listing: JSX.ElementClass,
+ count: number,
+ translationKey: "number_of_comments" | "number_of_subscribers"
+) {
+ return (
+ <>
+ <span>{listing}</span>
+ <span>{` - ${I18NextService.i18n.t(translationKey, {
+ count: Number(count),
+ formattedCount: numToSI(count),
+ })}`}</span>
+ </>
+ );
+}
+
+export class Search extends Component<any, SearchState> {
+ private isoData = setIsoData<SearchData>(this.context);
+
+ state: SearchState = {
+ resolveObjectRes: { state: "empty" },
+ creatorDetailsRes: { state: "empty" },
+ communitiesRes: { state: "empty" },
+ communityRes: { state: "empty" },
+ siteRes: this.isoData.site_res,
+ creatorSearchOptions: [],
+ communitySearchOptions: [],
+ searchRes: { state: "empty" },
+ searchCreatorLoading: false,
+ searchCommunitiesLoading: false,
+ isIsomorphic: false,
+ };