@@ -31,12 +31,14 @@ import {
31
31
import { initServerServices } from '@app-builder/services/init.server' ;
32
32
import { getCaseFileUploadEndpoint } from '@app-builder/utils/files' ;
33
33
import { formatDateTime , useFormatLanguage } from '@app-builder/utils/format' ;
34
+ import { parseIdParamSafe } from '@app-builder/utils/input-validation' ;
34
35
import { getRoute , type RouteID } from '@app-builder/utils/routes' ;
35
- import { fromParams , fromUUID } from '@app-builder/utils/short-uuid' ;
36
+ import { fromUUIDtoSUUID } from '@app-builder/utils/short-uuid' ;
36
37
import { defer , type LoaderFunctionArgs , type SerializeFrom } from '@remix-run/node' ;
37
38
import {
38
39
isRouteErrorResponse ,
39
40
Outlet ,
41
+ redirect ,
40
42
useLoaderData ,
41
43
useNavigate ,
42
44
useRouteError ,
@@ -62,12 +64,12 @@ export const handle = {
62
64
) ;
63
65
} ,
64
66
( { isLast } : BreadCrumbProps ) => {
65
- const { inbox } = useLoaderData < typeof loader > ( ) ;
67
+ const { inbox } = useLoaderData < typeof loader > ( ) ; // Ensure inbox is part of the loader's return type
66
68
67
69
return (
68
70
< BreadCrumbLink
69
71
to = { getRoute ( '/cases/inboxes/:inboxId' , {
70
- inboxId : fromUUID ( inbox . id ) ,
72
+ inboxId : fromUUIDtoSUUID ( inbox . id ) ,
71
73
} ) }
72
74
isLast = { isLast }
73
75
>
@@ -76,12 +78,13 @@ export const handle = {
76
78
) ;
77
79
} ,
78
80
( { isLast } : BreadCrumbProps ) => {
79
- const { caseDetail } = useLoaderData < typeof loader > ( ) ;
81
+ const data = useLoaderData < typeof loader > ( ) ;
82
+ const caseDetail = data . caseDetail ; // Safely access caseDetail from the loader data
80
83
81
84
return (
82
85
< div className = "flex items-center gap-4" >
83
86
< BreadCrumbLink
84
- to = { getRoute ( '/cases/:caseId' , { caseId : fromUUID ( caseDetail . id ) } ) }
87
+ to = { getRoute ( '/cases/:caseId' , { caseId : fromUUIDtoSUUID ( caseDetail . id ) } ) }
85
88
isLast = { isLast }
86
89
>
87
90
< span className = "line-clamp-2 text-start" > { caseDetail . name } </ span >
@@ -114,9 +117,12 @@ export async function loader({ request, params }: LoaderFunctionArgs) {
114
117
failureRedirect : getRoute ( '/sign-in' ) ,
115
118
} ) ;
116
119
117
- const caseId = fromParams ( params , 'caseId' ) ;
120
+ const parsedParams = await parseIdParamSafe ( params , 'caseId' ) ;
121
+
122
+ if ( ! parsedParams . success ) return redirect ( getRoute ( '/cases/inboxes' ) ) ;
123
+
118
124
try {
119
- const caseDetail = await cases . getCase ( { caseId } ) ;
125
+ const caseDetail = await cases . getCase ( { caseId : parsedParams . data . caseId } ) ;
120
126
const currentInbox = await inbox . getInbox ( caseDetail . inboxId ) ;
121
127
122
128
const dataModelPromise = dataModelRepository . getDataModel ( ) ;
@@ -159,9 +165,8 @@ export async function loader({ request, params }: LoaderFunctionArgs) {
159
165
} ;
160
166
} ) ,
161
167
) ;
162
-
163
168
return defer ( {
164
- caseDetail,
169
+ caseDetail, // Ensure caseDetail is explicitly included in the returned data
165
170
inbox : currentInbox ,
166
171
user,
167
172
entitlements,
@@ -182,10 +187,14 @@ export async function loader({ request, params }: LoaderFunctionArgs) {
182
187
}
183
188
}
184
189
185
- export function useCurrentCase ( ) {
186
- return useRouteLoaderData (
190
+ export function useCurrentCase ( ) : SerializeFrom < typeof loader > {
191
+ const data = useRouteLoaderData < typeof loader > (
187
192
'routes/_builder+/cases+/$caseId._layout' satisfies RouteID ,
188
- ) as SerializeFrom < typeof loader > ;
193
+ ) ;
194
+ if ( ! data || typeof data !== 'object' ) {
195
+ throw new Error ( 'Loader data is undefined or invalid' ) ;
196
+ }
197
+ return data as SerializeFrom < typeof loader > ;
189
198
}
190
199
191
200
export default function CasePage ( ) {
0 commit comments