diff --git a/apps/my_sample_app/src/App.tsx b/apps/my_sample_app/src/App.tsx index 11898ce0..ca9b68ce 100644 --- a/apps/my_sample_app/src/App.tsx +++ b/apps/my_sample_app/src/App.tsx @@ -1,87 +1,30 @@ -import { ErrorNotFound } from '#components/ErrorNotFound' import { appRoutes } from '#data/routes' -import { - Button, - EmptyState, - HomePageLayout, - Spacer, - useTokenProvider -} from '@commercelayer/app-elements' +import { Routes } from '@commercelayer/app-elements' import type { FC } from 'react' -import { Route, Router, Switch } from 'wouter' +import { Router } from 'wouter' interface AppProps { routerBase?: string } export const App: FC = ({ routerBase }) => { - const { canUser } = useTokenProvider() - return ( - - - - - - - - {canUser('create', 'orders') ? ( - - You can use the helper canUser() to check - user permissions. -
- In this case, you can see that the user has permission to - create orders. - - } - action={ - - } - /> - ) : canUser('read', 'orders') ? ( - - You can use the helper canUser() to check - user permissions. -
- In this case, you can see that the user has permission to - read orders. - - } - /> - ) : ( - - You can use the helper canUser() to check - user permissions. -
- In this case, you can see that the user does not have - permission to read orders. This is the classic "Not - Authorized" case. - - } - /> - )} -
-
-
- - - -
+ await import('#pages/Home') + }, + list: { + component: async () => await import('#pages/List') + }, + details: { + component: async () => await import('#pages/Details'), + overlay: true + } + }} + />
) } diff --git a/apps/my_sample_app/src/data/routes.ts b/apps/my_sample_app/src/data/routes.ts index 708db7e4..db41b8e2 100644 --- a/apps/my_sample_app/src/data/routes.ts +++ b/apps/my_sample_app/src/data/routes.ts @@ -1,4 +1,5 @@ -import { createRoute } from '@commercelayer/app-elements' +import { createRoute, createTypedRoute } from '@commercelayer/app-elements' +import type { ListableResourceType } from '@commercelayer/sdk' export type AppRoute = keyof typeof appRoutes @@ -7,5 +8,12 @@ export type AppRoute = keyof typeof appRoutes // a `path` property to be used as patter matching in component // and `makePath` method to be used to generate the path used in navigation and links export const appRoutes = { - home: createRoute('/') + home: createRoute('/'), + list: createTypedRoute<{ resourceType: ListableResourceType }>()( + '/:resourceType/' + ), + details: createTypedRoute<{ + resourceType: ListableResourceType + resourceId: string + }>()('/:resourceType/:resourceId/') } diff --git a/apps/my_sample_app/src/pages/Details.tsx b/apps/my_sample_app/src/pages/Details.tsx new file mode 100644 index 00000000..0f5949fb --- /dev/null +++ b/apps/my_sample_app/src/pages/Details.tsx @@ -0,0 +1,60 @@ +import { appRoutes } from '#data/routes' +import { + EmptyState, + PageLayout, + type PageProps, + ResourceDetails, + ResourceMetadata, + Spacer, + formatResourceName, + useCoreApi +} from '@commercelayer/app-elements' +import type { FC } from 'react' +import { useLocation } from 'wouter' + +const Page: FC> = ({ params }) => { + const { resourceType, resourceId } = params + const [, setLocation] = useLocation() + const { data, isLoading, mutate } = useCoreApi(resourceType, 'retrieve', [ + resourceId + ]) + + return ( + { + setLocation(appRoutes.list.makePath({ resourceType })) + } + }} + > + {isLoading ? ( +
Loading...
+ ) : data == null ? ( + + ) : ( + <> + + { + void mutate() + }} + /> + + + + )} +
+ ) +} + +export default Page diff --git a/apps/my_sample_app/src/pages/Home.tsx b/apps/my_sample_app/src/pages/Home.tsx new file mode 100644 index 00000000..328c9076 --- /dev/null +++ b/apps/my_sample_app/src/pages/Home.tsx @@ -0,0 +1,48 @@ +import { appRoutes } from '#data/routes' +import { + formatResourceName, + HomePageLayout, + Icon, + List, + ListItem, + Spacer +} from '@commercelayer/app-elements' +import type { ListableResourceType } from '@commercelayer/sdk' +import type { FC } from 'react' +import { useLocation } from 'wouter' + +const resources: ListableResourceType[] = [ + 'customers', + 'markets', + 'shipments', + 'skus' +] + +const Page: FC = () => { + const [, setLocation] = useLocation() + return ( + + + + {resources.map((resourceType) => ( + { + setLocation(appRoutes.list.makePath({ resourceType })) + }} + > + {formatResourceName({ + resource: resourceType, + format: 'title', + count: 'plural' + })} + + + ))} + + + + ) +} + +export default Page diff --git a/apps/my_sample_app/src/pages/List.tsx b/apps/my_sample_app/src/pages/List.tsx new file mode 100644 index 00000000..a5757be8 --- /dev/null +++ b/apps/my_sample_app/src/pages/List.tsx @@ -0,0 +1,81 @@ +import { appRoutes } from '#data/routes' +import { + Icon, + ListItem, + PageLayout, + type PageProps, + Text, + formatResourceName, + useResourceList +} from '@commercelayer/app-elements' +import type { FC } from 'react' +import { useLocation } from 'wouter' + +const Page: FC> = ({ params }) => { + const { resourceType } = params + const [, setLocation] = useLocation() + const { ResourceList, isLoading } = useResourceList({ + type: resourceType, + query: { + pageSize: 25 + } + }) + + if (isLoading) { + return null + } + + return ( + { + setLocation(appRoutes.home.makePath({})) + } + }} + > + { + if (resource == null) { + return null + } + return ( + { + setLocation( + appRoutes.details.makePath({ + resourceType, + resourceId: resource.id + }) + ) + }} + > +
+ + #{resource.id} + + + {/* for customers */} + {'email' in resource && resource.email} + {/* for other markets and skus */} + {'name' in resource && resource.name} + {/* for other shipments */} + {'number' in resource && resource.number} + +
+ +
+ ) + }} + /> +
+ ) +} + +export default Page