11import { useLoaderData , useOutletContext } from "react-router" ;
22import { PackageSearch } from "~/commonComponents/PackageSearch/PackageSearch" ;
33import { PackageOrderOptions } from "~/commonComponents/PackageSearch/components/PackageOrder" ;
4- import { DapperTs } from "@thunderstore/dapper-ts" ;
5- import {
6- getPublicEnvVariables ,
7- getSessionTools ,
8- } from "cyberstorm/security/publicEnvVariables" ;
94import { type OutletContextShape } from "~/root" ;
105import type { Route } from "./+types/PackageSearch" ;
6+ import { throwUserFacingPayloadResponse } from "cyberstorm/utils/errors/userFacingErrorResponse" ;
7+ import { handleLoaderError } from "cyberstorm/utils/errors/handleLoaderError" ;
8+ import { createNotFoundMapping } from "cyberstorm/utils/errors/loaderMappings" ;
9+ import { NimbusDefaultRouteErrorBoundary } from "cyberstorm/utils/errors/NimbusErrorBoundary" ;
10+ import { getLoaderTools } from "cyberstorm/utils/getLoaderTools" ;
11+ import { parseIntegerSearchParam } from "cyberstorm/utils/searchParamsUtils" ;
12+
13+ interface PackageSearchQuery {
14+ ordering : string ;
15+ page : number | undefined ;
16+ search : string ;
17+ includedCategories : string [ ] | undefined ;
18+ excludedCategories : string [ ] | undefined ;
19+ section : string ;
20+ nsfw : boolean ;
21+ deprecated : boolean ;
22+ }
23+
24+ const communityNotFoundMappings = [
25+ createNotFoundMapping (
26+ "Community not found." ,
27+ "We could not find the requested community."
28+ ) ,
29+ ] ;
30+
31+ function resolvePackageSearchQuery ( request : Request ) : PackageSearchQuery {
32+ const searchParams = new URL ( request . url ) . searchParams ;
33+ const ordering = searchParams . get ( "ordering" ) ?? PackageOrderOptions . Updated ;
34+ const page = parseIntegerSearchParam ( searchParams . get ( "page" ) ) ;
35+ const search = searchParams . get ( "search" ) ?? "" ;
36+ const included = searchParams . get ( "includedCategories" ) ;
37+ const excluded = searchParams . get ( "excludedCategories" ) ;
38+ const sectionParam = searchParams . get ( "section" ) ;
39+ const section = sectionParam
40+ ? sectionParam === "all"
41+ ? ""
42+ : sectionParam
43+ : "" ;
44+ const nsfw = searchParams . get ( "nsfw" ) === "true" ;
45+ const deprecated = searchParams . get ( "deprecated" ) === "true" ;
46+
47+ return {
48+ ordering,
49+ page,
50+ search,
51+ includedCategories : included ?. split ( "," ) ?? undefined ,
52+ excludedCategories : excluded ?. split ( "," ) ?? undefined ,
53+ section,
54+ nsfw,
55+ deprecated,
56+ } ;
57+ }
1158
1259export async function loader ( { params, request } : Route . LoaderArgs ) {
1360 if ( params . communityId ) {
14- const publicEnvVariables = getPublicEnvVariables ( [ "VITE_API_URL" ] ) ;
15- const dapper = new DapperTs ( ( ) => {
61+ const { dapper } = getLoaderTools ( ) ;
62+ try {
63+ const query = resolvePackageSearchQuery ( request ) ;
64+
1665 return {
17- apiHost : publicEnvVariables . VITE_API_URL ,
18- sessionId : undefined ,
66+ filters : await dapper . getCommunityFilters ( params . communityId ) ,
67+ listings : await dapper . getPackageListings (
68+ {
69+ kind : "community" ,
70+ communityId : params . communityId ,
71+ } ,
72+ query . ordering ?? "" ,
73+ query . page ,
74+ query . search ,
75+ query . includedCategories ,
76+ query . excludedCategories ,
77+ query . section ,
78+ query . nsfw ,
79+ query . deprecated
80+ ) ,
1981 } ;
20- } ) ;
21- const searchParams = new URL ( request . url ) . searchParams ;
22- const ordering =
23- searchParams . get ( "ordering" ) ?? PackageOrderOptions . Updated ;
24- const page = searchParams . get ( "page" ) ;
25- const search = searchParams . get ( "search" ) ;
26- const includedCategories = searchParams . get ( "includedCategories" ) ;
27- const excludedCategories = searchParams . get ( "excludedCategories" ) ;
28- const section = searchParams . get ( "section" ) ;
29- const nsfw = searchParams . get ( "nsfw" ) ;
30- const deprecated = searchParams . get ( "deprecated" ) ;
31- const filters = await dapper . getCommunityFilters ( params . communityId ) ;
32-
33- return {
34- filters : filters ,
35- listings : await dapper . getPackageListings (
36- {
37- kind : "community" ,
38- communityId : params . communityId ,
39- } ,
40- ordering ?? "" ,
41- page === null ? undefined : Number ( page ) ,
42- search ?? "" ,
43- includedCategories ?. split ( "," ) ?? undefined ,
44- excludedCategories ?. split ( "," ) ?? undefined ,
45- section ? ( section === "all" ? "" : section ) : "" ,
46- nsfw === "true" ? true : false ,
47- deprecated === "true" ? true : false
48- ) ,
49- } ;
82+ } catch ( error ) {
83+ handleLoaderError ( error , { mappings : communityNotFoundMappings } ) ;
84+ }
5085 }
51- throw new Response ( "Community not found" , { status : 404 } ) ;
86+ throwUserFacingPayloadResponse ( {
87+ headline : "Community not found." ,
88+ description : "We could not find the requested community." ,
89+ category : "not_found" ,
90+ status : 404 ,
91+ } ) ;
5292}
5393
5494export async function clientLoader ( {
5595 request,
5696 params,
5797} : Route . ClientLoaderArgs ) {
5898 if ( params . communityId ) {
59- const tools = getSessionTools ( ) ;
60- const dapper = new DapperTs ( ( ) => {
61- return {
62- apiHost : tools ?. getConfig ( ) . apiHost ,
63- sessionId : tools ?. getConfig ( ) . sessionId ,
64- } ;
65- } ) ;
66- const searchParams = new URL ( request . url ) . searchParams ;
67- const ordering =
68- searchParams . get ( "ordering" ) ?? PackageOrderOptions . Updated ;
69- const page = searchParams . get ( "page" ) ;
70- const search = searchParams . get ( "search" ) ;
71- const includedCategories = searchParams . get ( "includedCategories" ) ;
72- const excludedCategories = searchParams . get ( "excludedCategories" ) ;
73- const section = searchParams . get ( "section" ) ;
74- const nsfw = searchParams . get ( "nsfw" ) ;
75- const deprecated = searchParams . get ( "deprecated" ) ;
76- const filters = dapper . getCommunityFilters ( params . communityId ) ;
99+ const { dapper } = getLoaderTools ( ) ;
100+ const query = resolvePackageSearchQuery ( request ) ;
77101 return {
78- filters : filters ,
79- listings : dapper . getPackageListings (
80- {
81- kind : "community" ,
82- communityId : params . communityId ,
83- } ,
84- ordering ?? "" ,
85- page === null ? undefined : Number ( page ) ,
86- search ?? "" ,
87- includedCategories ?. split ( "," ) ?? undefined ,
88- excludedCategories ?. split ( "," ) ?? undefined ,
89- section ? ( section === "all" ? "" : section ) : "" ,
90- nsfw === "true" ? true : false ,
91- deprecated === "true" ? true : false
92- ) ,
102+ filters : dapper
103+ . getCommunityFilters ( params . communityId )
104+ . catch ( ( error ) =>
105+ handleLoaderError ( error , { mappings : communityNotFoundMappings } )
106+ ) ,
107+ listings : dapper
108+ . getPackageListings (
109+ {
110+ kind : "community" ,
111+ communityId : params . communityId ,
112+ } ,
113+ query . ordering ?? "" ,
114+ query . page ,
115+ query . search ,
116+ query . includedCategories ,
117+ query . excludedCategories ,
118+ query . section ,
119+ query . nsfw ,
120+ query . deprecated
121+ )
122+ . catch ( ( error ) =>
123+ handleLoaderError ( error , { mappings : communityNotFoundMappings } )
124+ ) ,
93125 } ;
94126 }
95- throw new Response ( "Community not found" , { status : 404 } ) ;
127+ throwUserFacingPayloadResponse ( {
128+ headline : "Community not found." ,
129+ description : "We could not find the requested community." ,
130+ category : "not_found" ,
131+ status : 404 ,
132+ } ) ;
96133}
97134
98- // function shouldRevalidate(arg: ShouldRevalidateFunctionArgs) {
99- // return true; // false
100- // }
101-
102135export default function CommunityPackageSearch ( ) {
103136 const { filters, listings } = useLoaderData <
104137 typeof loader | typeof clientLoader
@@ -107,14 +140,16 @@ export default function CommunityPackageSearch() {
107140 const outletContext = useOutletContext ( ) as OutletContextShape ;
108141
109142 return (
110- < >
111- < PackageSearch
112- listings = { listings }
113- filters = { filters }
114- config = { outletContext . requestConfig }
115- currentUser = { outletContext . currentUser }
116- dapper = { outletContext . dapper }
117- />
118- </ >
143+ < PackageSearch
144+ listings = { listings }
145+ filters = { filters }
146+ config = { outletContext . requestConfig }
147+ currentUser = { outletContext . currentUser }
148+ dapper = { outletContext . dapper }
149+ />
119150 ) ;
120151}
152+
153+ export function ErrorBoundary ( ) {
154+ return < NimbusDefaultRouteErrorBoundary /> ;
155+ }
0 commit comments