Skip to content

Commit d0e5326

Browse files
committed
progress on remix
1 parent f7ed73c commit d0e5326

File tree

6 files changed

+90
-52
lines changed

6 files changed

+90
-52
lines changed

remix/app/error-handler.tsx

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { isRouteErrorResponse, useRouteError } from '@remix-run/react'
2+
3+
export function ErrorBoundary() {
4+
const error = useRouteError()
5+
6+
if (isRouteErrorResponse(error)) {
7+
return (
8+
<div>
9+
<h1>
10+
{error.status} {error.statusText}
11+
</h1>
12+
<p>...{error.data}</p>
13+
</div>
14+
)
15+
} else if (error instanceof Error) {
16+
return (
17+
<div>
18+
<h1>Error</h1>
19+
<p>{error.message}</p>
20+
<p>The stack trace is:</p>
21+
<pre>{error.stack}</pre>
22+
</div>
23+
)
24+
} else {
25+
return <h1>Unknown Error</h1>
26+
}
27+
}

remix/app/root.tsx

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,29 @@ import { AuthProvider } from '~/state/AuthContext'
1414
import { CartProvider } from '~/state/CartContext'
1515
import { getCart } from '~/utils/cart.server'
1616
import stylesheet from '~/styles/app.css'
17+
import type { UnpackLoader } from '~/utils/helpers'
18+
import type { PropsWithChildren } from 'react'
1719

20+
export { ErrorBoundary } from './error-handler'
1821
export const links: LinksFunction = () => [{ rel: 'stylesheet', href: stylesheet }]
1922

2023
export async function loader({ request }: LoaderArgs) {
2124
const [sessionUser, cart] = await Promise.all([getSessionUser(request), getCart(request)])
2225
return json({ sessionUser, cart })
2326
}
2427

28+
export type LoaderType = UnpackLoader<typeof loader>
29+
2530
export default function App() {
26-
const { sessionUser, cart } = useLoaderData<typeof loader>()
31+
return (
32+
<Document>
33+
<Outlet />
34+
</Document>
35+
)
36+
}
37+
38+
function Document({ children }: PropsWithChildren) {
39+
const { sessionUser, cart } = useLoaderData() as LoaderType
2740

2841
return (
2942
<html lang="en">
@@ -41,9 +54,7 @@ export default function App() {
4154
<body>
4255
<AuthProvider user={sessionUser}>
4356
<CartProvider cart={cart}>
44-
<MainLayout>
45-
<Outlet />
46-
</MainLayout>
57+
<MainLayout>{children}</MainLayout>
4758
</CartProvider>
4859
</AuthProvider>
4960
<ScrollRestoration />

remix/app/routes/products.$productId.tsx renamed to remix/app/routes/_products-layout.products.$productId.tsx

Lines changed: 37 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -44,50 +44,43 @@ export default function () {
4444
const categoryLabel = categories.find((c) => c.handle === product.category)?.label as string
4545

4646
return (
47-
<div className="flex gap-6">
48-
<aside className="w-72 p-6 border rounded-lg bg-white space-y-6">aside</aside>
49-
<div className="flex-1 space-y-10">
50-
<main className="p-6 border rounded-lg bg-white">
51-
<ProductProfile
52-
id={product.id}
53-
name={product.name}
54-
image={product.image}
55-
brand={brandLabel}
56-
brandHandle={product.brand}
57-
category={categoryLabel}
58-
categoryHandle={product.category}
59-
price={product.price}
60-
quantityInCart={quantityInCart}
61-
/>
62-
</main>
63-
<div className="space-y-3">
64-
<div>Other Products From This Brand</div>
65-
<hr />
66-
<Suspense fallback={<div>Loading...</div>}>
67-
<Await resolve={relatedProductsPromise}>
68-
{(products) => {
69-
return (
70-
<Tiles>
71-
{products.map((product) => {
72-
const quantityInCart =
73-
cart.find((item) => item.productId === product.id)?.quantity || 0
74-
return (
75-
<div className="border rounded-lg bg-white">
76-
<BrowseProductItem
77-
key={product.id}
78-
product={product}
79-
quantityInCart={quantityInCart}
80-
/>
81-
</div>
82-
)
83-
})}
84-
</Tiles>
85-
)
86-
}}
87-
</Await>
88-
</Suspense>
89-
</div>
47+
<>
48+
<main className="p-6 border rounded-lg bg-white">
49+
<ProductProfile
50+
id={product.id}
51+
name={product.name}
52+
image={product.image}
53+
brand={brandLabel}
54+
brandHandle={product.brand}
55+
category={categoryLabel}
56+
categoryHandle={product.category}
57+
price={product.price}
58+
quantityInCart={quantityInCart}
59+
/>
60+
</main>
61+
<div className="space-y-3">
62+
<div>Other Products From This Brand</div>
63+
<hr />
64+
<Suspense fallback={<div>Loading...</div>}>
65+
<Await resolve={relatedProductsPromise}>
66+
{(products) => {
67+
return (
68+
<Tiles>
69+
{products.map((product) => {
70+
const quantityInCart =
71+
cart.find((item) => item.productId === product.id)?.quantity || 0
72+
return (
73+
<div key={product.id} className="border rounded-lg bg-white">
74+
<BrowseProductItem product={product} quantityInCart={quantityInCart} />
75+
</div>
76+
)
77+
})}
78+
</Tiles>
79+
)
80+
}}
81+
</Await>
82+
</Suspense>
9083
</div>
91-
</div>
84+
</>
9285
)
9386
}

remix/app/routes/_products-layout.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { json } from '@remix-run/node'
2-
import { Outlet, useLoaderData, useLocation } from '@remix-run/react'
2+
import { Outlet, useLoaderData, useLocation, useRouteError } from '@remix-run/react'
33
import { Heading } from '~/components/Heading'
44
import { FilterLink, FilterLinkAll } from '~/components/FilterLink'
55
import {
@@ -13,6 +13,8 @@ import type { LoaderArgs } from '@remix-run/node'
1313
import type { V2_MetaFunction } from '@remix-run/react'
1414
import { type UnpackLoader, sortLabel } from '~/utils/helpers'
1515

16+
export { ErrorBoundary } from '~/error-handler'
17+
1618
export const meta: V2_MetaFunction = () => {
1719
return [{ title: 'New Remix App' }]
1820
}

remix/lessons/02-loaders/exercise-final/routes/_products-layout.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,12 @@ export const loader = async ({ request }: LoaderArgs) => {
1818
export type LoaderData = UnpackLoader<typeof loader>
1919

2020
export default function () {
21-
const { products, brands } = useLoaderData<LoaderData>()
22-
const context = useMemo(() => ({ products }), [products])
21+
// Task 1
22+
// const { products, brands } = useLoaderData<LoaderData>()
23+
// const context = useMemo(() => ({ products }), [products])
24+
25+
// Task 2
26+
const { brands } = useLoaderData() as LoaderData
2327

2428
return (
2529
<div className="flex gap-6">
@@ -39,7 +43,8 @@ export default function () {
3943
})}
4044
</aside>
4145
<main className="flex-1 space-y-3">
42-
<Outlet context={context} />
46+
{/* <Outlet context={context} /> */}
47+
<Outlet />
4348
</main>
4449
</div>
4550
)

0 commit comments

Comments
 (0)