diff --git a/apps/cyberstorm-nextjs/app/communities/@searchAndOrder/SearchAndOrder.module.css b/apps/cyberstorm-nextjs/app/communities/@searchAndOrder/SearchAndOrder.module.css
new file mode 100644
index 000000000..f2c73c21c
--- /dev/null
+++ b/apps/cyberstorm-nextjs/app/communities/@searchAndOrder/SearchAndOrder.module.css
@@ -0,0 +1,34 @@
+.root {
+ display: flex;
+ flex-direction: column;
+ gap: var(--gap--16);
+}
+
+.searchTextInput {
+ width: 100%;
+}
+
+@media (min-width: 40rem) {
+ .searchTextInput {
+ width: 50%;
+ }
+
+ .root {
+ flex-direction: row;
+ justify-content: space-between;
+ }
+}
+
+.searchFilters {
+ display: flex;
+ flex: 1 1 auto;
+ gap: var(--gap--16);
+ align-content: center;
+ justify-content: flex-end;
+}
+
+.searchFiltersSortLabel {
+ align-self: center;
+ color: var(--color-text--tertiary);
+ font-weight: var(--font-weight-bold);
+}
diff --git a/apps/cyberstorm-nextjs/app/communities/@searchAndOrder/page.tsx b/apps/cyberstorm-nextjs/app/communities/@searchAndOrder/page.tsx
new file mode 100644
index 000000000..06b4fbe5e
--- /dev/null
+++ b/apps/cyberstorm-nextjs/app/communities/@searchAndOrder/page.tsx
@@ -0,0 +1,94 @@
+"use client";
+import styles from "./SearchAndOrder.module.css";
+import { TextInput, Select } from "@thunderstore/cyberstorm";
+import { useCallback, useEffect, useState } from "react";
+import { useDebounce } from "use-debounce";
+
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import {
+ faSearch,
+ faArrowDownAZ,
+ faStar,
+} from "@fortawesome/free-solid-svg-icons";
+import { faFire } from "@fortawesome/pro-solid-svg-icons";
+import { usePathname, useSearchParams } from "next/navigation";
+import { useRouter } from "next/navigation";
+
+enum SortOptions {
+ Name = "name",
+ Latest = "-datetime_created",
+ Popular = "-aggregated_fields__download_count",
+}
+
+export default function Page() {
+ const router = useRouter();
+ const pathname = usePathname();
+ const searchParams = useSearchParams();
+
+ const createQueryString = useCallback(
+ (name: string, value: string, isDefault?: boolean) => {
+ const params = new URLSearchParams(searchParams.toString());
+ if (isDefault || value.length === 0) {
+ params.delete(name);
+ } else {
+ params.set(name, value);
+ }
+
+ return params.toString();
+ },
+ [searchParams]
+ );
+
+ const [order, setOrder] = useState(SortOptions.Popular);
+
+ const changeOrder = (v: SortOptions) => {
+ setOrder(v);
+ router.push(
+ pathname + "?" + createQueryString("order", v, v === SortOptions.Popular)
+ );
+ };
+
+ const [searchValue, setSearchValue] = useState("");
+ const [debouncedSearchValue] = useDebounce(searchValue, 300);
+
+ useEffect(() => {
+ router.push(
+ pathname + "?" + createQueryString("search", debouncedSearchValue)
+ );
+ }, [createQueryString, debouncedSearchValue, pathname, router]);
+
+ return (
+
+
+ setSearchValue(e.target.value)}
+ value={searchValue}
+ placeholder="Search communities..."
+ leftIcon={}
+ />
+
+
+
+ );
+}
+
+const selectOptions = [
+ {
+ value: SortOptions.Name,
+ label: "Name",
+ leftIcon: ,
+ },
+ {
+ value: SortOptions.Latest,
+ label: "Latest",
+ leftIcon: ,
+ },
+ {
+ value: SortOptions.Popular,
+ label: "Popular",
+ leftIcon: ,
+ },
+];
diff --git a/apps/cyberstorm-nextjs/app/communities/@searchAndOrder/searchAndOrderSkeleton.tsx b/apps/cyberstorm-nextjs/app/communities/@searchAndOrder/searchAndOrderSkeleton.tsx
new file mode 100644
index 000000000..d26e37bec
--- /dev/null
+++ b/apps/cyberstorm-nextjs/app/communities/@searchAndOrder/searchAndOrderSkeleton.tsx
@@ -0,0 +1,5 @@
+import styles from "./SearchAndOrder.module.css";
+
+export const SearchAndOrderSkeleton = () => {
+ return TODO: SKELETON
;
+};
diff --git a/apps/cyberstorm-nextjs/app/communities/CommunitiesLayout.module.css b/apps/cyberstorm-nextjs/app/communities/CommunitiesLayout.module.css
index 98522b4b2..3d712b9c0 100644
--- a/apps/cyberstorm-nextjs/app/communities/CommunitiesLayout.module.css
+++ b/apps/cyberstorm-nextjs/app/communities/CommunitiesLayout.module.css
@@ -3,12 +3,6 @@
flex-direction: column;
}
-.topNavigation {
- display: flex;
- flex-direction: column;
- gap: var(--gap--16);
-}
-
.filters {
display: flex;
flex-direction: column;
diff --git a/apps/cyberstorm-nextjs/app/communities/layout.tsx b/apps/cyberstorm-nextjs/app/communities/layout.tsx
index 9b938758c..48e46056f 100644
--- a/apps/cyberstorm-nextjs/app/communities/layout.tsx
+++ b/apps/cyberstorm-nextjs/app/communities/layout.tsx
@@ -1,73 +1,17 @@
-"use client";
import rootStyles from "../RootLayout.module.css";
-import styles from "./CommunitiesLayout.module.css";
-import {
- TextInput,
- Select,
- BreadCrumbs,
- PageHeader,
-} from "@thunderstore/cyberstorm";
-import { ReactNode, Suspense, useCallback, useEffect, useState } from "react";
-import { useDebounce } from "use-debounce";
+import { BreadCrumbs, PageHeader } from "@thunderstore/cyberstorm";
+import { ReactNode, Suspense } from "react";
-import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import {
- faArrowDownAZ,
- faSearch,
- faStar,
-} from "@fortawesome/free-solid-svg-icons";
-import { faFire } from "@fortawesome/pro-solid-svg-icons";
import { CommunityListSkeleton } from "./@communityList/CommunityListSkeleton";
-import { usePathname, useSearchParams } from "next/navigation";
-import { useRouter } from "next/navigation";
-
-enum SortOptions {
- Name = "name",
- Latest = "-datetime_created",
- Popular = "-aggregated_fields__download_count",
-}
+import { SearchAndOrderSkeleton } from "./@searchAndOrder/searchAndOrderSkeleton";
export default function CommunitiesLayout({
communityList,
+ searchAndOrder,
}: {
communityList: ReactNode;
+ searchAndOrder: ReactNode;
}) {
- const router = useRouter();
- const pathname = usePathname();
- const searchParams = useSearchParams();
-
- const createQueryString = useCallback(
- (name: string, value: string, isDefault?: boolean) => {
- const params = new URLSearchParams(searchParams.toString());
- if (isDefault || value.length === 0) {
- params.delete(name);
- } else {
- params.set(name, value);
- }
-
- return params.toString();
- },
- [searchParams]
- );
-
- const [order, setOrder] = useState(SortOptions.Popular);
-
- const changeOrder = (v: SortOptions) => {
- setOrder(v);
- router.push(
- pathname + "?" + createQueryString("order", v, v === SortOptions.Popular)
- );
- };
-
- const [searchValue, setSearchValue] = useState("");
- const [debouncedSearchValue] = useDebounce(searchValue, 300);
-
- useEffect(() => {
- router.push(
- pathname + "?" + createQueryString("search", debouncedSearchValue)
- );
- }, [createQueryString, debouncedSearchValue, pathname, router]);
-
return (
@@ -77,24 +21,9 @@ export default function CommunitiesLayout({
-
-
- setSearchValue(e.target.value)}
- value={searchValue}
- placeholder="Search communities..."
- leftIcon={}
- />
-
-
-
+ }>
+ {searchAndOrder}
+
}>
{communityList}
@@ -104,21 +33,3 @@ export default function CommunitiesLayout({
);
}
-
-const selectOptions = [
- {
- value: SortOptions.Name,
- label: "Name",
- leftIcon: ,
- },
- {
- value: SortOptions.Latest,
- label: "Latest",
- leftIcon: ,
- },
- {
- value: SortOptions.Popular,
- label: "Popular",
- leftIcon: ,
- },
-];