Skip to content

Commit c31a12c

Browse files
authored
✨ Use suspense for items page (#1167)
1 parent cc10bf6 commit c31a12c

File tree

3 files changed

+98
-62
lines changed

3 files changed

+98
-62
lines changed

frontend/package-lock.json

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"framer-motion": "10.16.16",
2424
"react": "^18.2.0",
2525
"react-dom": "^18.2.0",
26+
"react-error-boundary": "^4.0.13",
2627
"react-hook-form": "7.49.3",
2728
"react-icons": "5.0.1"
2829
},

frontend/src/routes/_layout/items.tsx

Lines changed: 77 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import {
22
Container,
33
Flex,
44
Heading,
5-
Spinner,
5+
Skeleton,
66
Table,
77
TableContainer,
88
Tbody,
@@ -11,82 +11,97 @@ import {
1111
Thead,
1212
Tr,
1313
} from "@chakra-ui/react"
14-
import { useQuery } from "@tanstack/react-query"
14+
import { useSuspenseQuery } from "@tanstack/react-query"
1515
import { createFileRoute } from "@tanstack/react-router"
1616

17+
import { Suspense } from "react"
18+
import { ErrorBoundary } from "react-error-boundary"
1719
import { ItemsService } from "../../client"
1820
import ActionsMenu from "../../components/Common/ActionsMenu"
1921
import Navbar from "../../components/Common/Navbar"
20-
import useCustomToast from "../../hooks/useCustomToast"
2122

2223
export const Route = createFileRoute("/_layout/items")({
2324
component: Items,
2425
})
2526

26-
function Items() {
27-
const showToast = useCustomToast()
28-
const {
29-
data: items,
30-
isLoading,
31-
isError,
32-
error,
33-
} = useQuery({
27+
function ItemsTableBody() {
28+
const { data: items } = useSuspenseQuery({
3429
queryKey: ["items"],
3530
queryFn: () => ItemsService.readItems({}),
3631
})
3732

38-
if (isError) {
39-
const errDetail = (error as any).body?.detail
40-
showToast("Something went wrong.", `${errDetail}`, "error")
41-
}
42-
4333
return (
44-
<>
45-
{isLoading ? (
46-
// TODO: Add skeleton
47-
<Flex justify="center" align="center" height="100vh" width="full">
48-
<Spinner size="xl" color="ui.main" />
49-
</Flex>
50-
) : (
51-
items && (
52-
<Container maxW="full">
53-
<Heading
54-
size="lg"
55-
textAlign={{ base: "center", md: "left" }}
56-
pt={12}
57-
>
58-
Items Management
59-
</Heading>
60-
<Navbar type={"Item"} />
61-
<TableContainer>
62-
<Table size={{ base: "sm", md: "md" }}>
63-
<Thead>
64-
<Tr>
65-
<Th>ID</Th>
66-
<Th>Title</Th>
67-
<Th>Description</Th>
68-
<Th>Actions</Th>
69-
</Tr>
70-
</Thead>
71-
<Tbody>
72-
{items.data.map((item) => (
73-
<Tr key={item.id}>
74-
<Td>{item.id}</Td>
75-
<Td>{item.title}</Td>
76-
<Td color={!item.description ? "ui.dim" : "inherit"}>
77-
{item.description || "N/A"}
78-
</Td>
79-
<Td>
80-
<ActionsMenu type={"Item"} value={item} />
34+
<Tbody>
35+
{items.data.map((item) => (
36+
<Tr key={item.id}>
37+
<Td>{item.id}</Td>
38+
<Td>{item.title}</Td>
39+
<Td color={!item.description ? "ui.dim" : "inherit"}>
40+
{item.description || "N/A"}
41+
</Td>
42+
<Td>
43+
<ActionsMenu type={"Item"} value={item} />
44+
</Td>
45+
</Tr>
46+
))}
47+
</Tbody>
48+
)
49+
}
50+
function ItemsTable() {
51+
return (
52+
<TableContainer>
53+
<Table size={{ base: "sm", md: "md" }}>
54+
<Thead>
55+
<Tr>
56+
<Th>ID</Th>
57+
<Th>Title</Th>
58+
<Th>Description</Th>
59+
<Th>Actions</Th>
60+
</Tr>
61+
</Thead>
62+
<ErrorBoundary
63+
fallbackRender={({ error }) => (
64+
<Tbody>
65+
<Tr>
66+
<Td colSpan={4}>Something went wrong: {error.message}</Td>
67+
</Tr>
68+
</Tbody>
69+
)}
70+
>
71+
<Suspense
72+
fallback={
73+
<Tbody>
74+
{new Array(5).fill(null).map((_, index) => (
75+
<Tr key={index}>
76+
{new Array(4).fill(null).map((_, index) => (
77+
<Td key={index}>
78+
<Flex>
79+
<Skeleton height="20px" width="20px" />
80+
</Flex>
8181
</Td>
82-
</Tr>
83-
))}
84-
</Tbody>
85-
</Table>
86-
</TableContainer>
87-
</Container>
88-
)
89-
)}
90-
</>
82+
))}
83+
</Tr>
84+
))}
85+
</Tbody>
86+
}
87+
>
88+
<ItemsTableBody />
89+
</Suspense>
90+
</ErrorBoundary>
91+
</Table>
92+
</TableContainer>
93+
)
94+
}
95+
96+
function Items() {
97+
return (
98+
<Container maxW="full">
99+
<Heading size="lg" textAlign={{ base: "center", md: "left" }} pt={12}>
100+
Items Management
101+
</Heading>
102+
103+
<Navbar type={"Item"} />
104+
<ItemsTable />
105+
</Container>
91106
)
92107
}

0 commit comments

Comments
 (0)