Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
204 changes: 122 additions & 82 deletions apps/cyberstorm-remix/app/c/tabs/PackageSearch/PackageSearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,97 +10,135 @@
import { DapperTs } from "@thunderstore/dapper-ts";

import type { Route } from "./+types/PackageSearch";
import { throwUserFacingPayloadResponse } from "cyberstorm/utils/errors/userFacingErrorResponse";
import { handleLoaderError } from "cyberstorm/utils/errors/handleLoaderError";

Check failure

Code scanning / ESLint

Ensure code is properly formatted, use insertion, deletion, or replacement to obtain desired formatting. Error

Replace handleLoaderError·}·from·"cyberstorm/utils/errors/handleLoaderError with getLoaderTools·}·from·"cyberstorm/utils/getLoaderTools
import { createNotFoundMapping } from "cyberstorm/utils/errors/loaderMappings";

Check failure

Code scanning / ESLint

Ensure code is properly formatted, use insertion, deletion, or replacement to obtain desired formatting. Error

Replace createNotFoundMapping·}·from·"cyberstorm/utils/errors/loaderMapping with parseIntegerSearchParam·}·from·"cyberstorm/utils/searchParamsUtil
import { NimbusDefaultRouteErrorBoundary } from "cyberstorm/utils/errors/NimbusErrorBoundary";

Check failure

Code scanning / ESLint

Ensure code is properly formatted, use insertion, deletion, or replacement to obtain desired formatting. Error

Replace NimbusDefaultRouteErrorBoundary·}·from·"cyberstorm/utils/errors/NimbusErrorBoundary with useLoaderData,·useOutletContext·}·from·"react-router";⏎import·{·PackageSearch·}·from·"~/commonComponents/PackageSearch/PackageSearch
import { getLoaderTools } from "cyberstorm/utils/getLoaderTools";

Check failure

Code scanning / ESLint

Ensure code is properly formatted, use insertion, deletion, or replacement to obtain desired formatting. Error

Replace getLoaderTools·}·from·"cyberstorm/utils/getLoaderTools with PackageOrderOptions·}·from·"~/commonComponents/PackageSearch/components/PackageOrder
import { parseIntegerSearchParam } from "cyberstorm/utils/searchParamsUtils";

Check failure

Code scanning / ESLint

Ensure code is properly formatted, use insertion, deletion, or replacement to obtain desired formatting. Error

Replace parseIntegerSearchParam·}·from·"cyberstorm/utils/searchParamsUtils with type·OutletContextShape·}·from·"~/root";⏎⏎import·{·DapperTs·}·from·"@thunderstore/dapper-ts";⏎⏎import·type·{·Route·}·from·"./+types/PackageSearch

interface PackageSearchQuery {
ordering: string;
page: number | undefined;
search: string;
includedCategories: string[] | undefined;
excludedCategories: string[] | undefined;
section: string;
nsfw: boolean;
deprecated: boolean;
}

const communityNotFoundMappings = [
createNotFoundMapping(
"Community not found.",
"We could not find the requested community."
),
];

function resolvePackageSearchQuery(request: Request): PackageSearchQuery {
const searchParams = new URL(request.url).searchParams;
const ordering = searchParams.get("ordering") ?? PackageOrderOptions.Updated;
const page = parseIntegerSearchParam(searchParams.get("page"));
const search = searchParams.get("search") ?? "";
const included = searchParams.get("includedCategories");
const excluded = searchParams.get("excludedCategories");
const sectionParam = searchParams.get("section");
const section = sectionParam
? sectionParam === "all"
? ""
: sectionParam
: "";
const nsfw = searchParams.get("nsfw") === "true";
const deprecated = searchParams.get("deprecated") === "true";

return {
ordering,
page,
search,
includedCategories: included?.split(",") ?? undefined,
excludedCategories: excluded?.split(",") ?? undefined,
section,
nsfw,
deprecated,
};
}

export async function loader({ params, request }: Route.LoaderArgs) {
if (params.communityId) {
const publicEnvVariables = getPublicEnvVariables(["VITE_API_URL"]);
const dapper = new DapperTs(() => {
const { dapper } = getLoaderTools();
try {
const query = resolvePackageSearchQuery(request);

return {
apiHost: publicEnvVariables.VITE_API_URL,
sessionId: undefined,
filters: await dapper.getCommunityFilters(params.communityId),
listings: await dapper.getPackageListings(
{
kind: "community",
communityId: params.communityId,
},
query.ordering ?? "",
query.page,
query.search,
query.includedCategories,
query.excludedCategories,
query.section,
query.nsfw,
query.deprecated
),
};
});
const searchParams = new URL(request.url).searchParams;
const ordering =
searchParams.get("ordering") ?? PackageOrderOptions.Updated;
const page = searchParams.get("page");
const search = searchParams.get("search");
const includedCategories = searchParams.get("includedCategories");
const excludedCategories = searchParams.get("excludedCategories");
const section = searchParams.get("section");
const nsfw = searchParams.get("nsfw");
const deprecated = searchParams.get("deprecated");
const filters = await dapper.getCommunityFilters(params.communityId);

return {
filters: filters,
listings: await dapper.getPackageListings(
{
kind: "community",
communityId: params.communityId,
},
ordering ?? "",
page === null ? undefined : Number(page),
search ?? "",
includedCategories?.split(",") ?? undefined,
excludedCategories?.split(",") ?? undefined,
section ? (section === "all" ? "" : section) : "",
nsfw === "true" ? true : false,
deprecated === "true" ? true : false
),
};
} catch (error) {
handleLoaderError(error, { mappings: communityNotFoundMappings });
}
}
throw new Response("Community not found", { status: 404 });
throwUserFacingPayloadResponse({
headline: "Community not found.",
description: "We could not find the requested community.",
category: "not_found",
status: 404,
});
}

export async function clientLoader({
request,
params,
}: Route.ClientLoaderArgs) {
if (params.communityId) {
const tools = getSessionTools();
const dapper = new DapperTs(() => {
return {
apiHost: tools?.getConfig().apiHost,
sessionId: tools?.getConfig().sessionId,
};
});
const searchParams = new URL(request.url).searchParams;
const ordering =
searchParams.get("ordering") ?? PackageOrderOptions.Updated;
const page = searchParams.get("page");
const search = searchParams.get("search");
const includedCategories = searchParams.get("includedCategories");
const excludedCategories = searchParams.get("excludedCategories");
const section = searchParams.get("section");
const nsfw = searchParams.get("nsfw");
const deprecated = searchParams.get("deprecated");
const filters = dapper.getCommunityFilters(params.communityId);
const { dapper } = getLoaderTools();
const query = resolvePackageSearchQuery(request);
return {
filters: filters,
listings: dapper.getPackageListings(
{
kind: "community",
communityId: params.communityId,
},
ordering ?? "",
page === null ? undefined : Number(page),
search ?? "",
includedCategories?.split(",") ?? undefined,
excludedCategories?.split(",") ?? undefined,
section ? (section === "all" ? "" : section) : "",
nsfw === "true" ? true : false,
deprecated === "true" ? true : false
),
filters: dapper
.getCommunityFilters(params.communityId)
.catch((error) =>
handleLoaderError(error, { mappings: communityNotFoundMappings })
),
listings: dapper
.getPackageListings(
{
kind: "community",
communityId: params.communityId,
},
query.ordering ?? "",
query.page,
query.search,
query.includedCategories,
query.excludedCategories,
query.section,
query.nsfw,
query.deprecated
)
.catch((error) =>
handleLoaderError(error, { mappings: communityNotFoundMappings })
),
};
}
throw new Response("Community not found", { status: 404 });
throwUserFacingPayloadResponse({
headline: "Community not found.",
description: "We could not find the requested community.",
category: "not_found",
status: 404,
});
}

// function shouldRevalidate(arg: ShouldRevalidateFunctionArgs) {
// return true; // false
// }

export default function CommunityPackageSearch() {
const { filters, listings } = useLoaderData<
typeof loader | typeof clientLoader
Expand All @@ -109,14 +147,16 @@
const outletContext = useOutletContext() as OutletContextShape;

return (
<>
<PackageSearch
listings={listings}
filters={filters}
config={outletContext.requestConfig}
currentUser={outletContext.currentUser}
dapper={outletContext.dapper}
/>
</>
<PackageSearch
listings={listings}
filters={filters}
config={outletContext.requestConfig}
currentUser={outletContext.currentUser}
dapper={outletContext.dapper}
/>
);
}

export function ErrorBoundary() {
return <NimbusDefaultRouteErrorBoundary />;
}
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,16 @@
align-self: stretch;
}

.package-search__error {
display: flex;
flex-direction: column;
gap: 1rem;
align-items: flex-start;
align-items: center;
align-self: stretch;
padding: 1rem;
}

.package-search__grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
Expand Down
Loading
Loading