|
|
@ -2,7 +2,7 @@ import { |
|
|
|
Container, |
|
|
|
Flex, |
|
|
|
Heading, |
|
|
|
Spinner, |
|
|
|
Skeleton, |
|
|
|
Table, |
|
|
|
TableContainer, |
|
|
|
Tbody, |
|
|
@ -11,53 +11,44 @@ import { |
|
|
|
Thead, |
|
|
|
Tr, |
|
|
|
} from "@chakra-ui/react" |
|
|
|
import { useQuery } from "@tanstack/react-query" |
|
|
|
import { useSuspenseQuery } from "@tanstack/react-query" |
|
|
|
import { createFileRoute } from "@tanstack/react-router" |
|
|
|
|
|
|
|
import { Suspense } from "react" |
|
|
|
import { ErrorBoundary } from "react-error-boundary" |
|
|
|
import { ItemsService } from "../../client" |
|
|
|
import ActionsMenu from "../../components/Common/ActionsMenu" |
|
|
|
import Navbar from "../../components/Common/Navbar" |
|
|
|
import useCustomToast from "../../hooks/useCustomToast" |
|
|
|
|
|
|
|
export const Route = createFileRoute("/_layout/items")({ |
|
|
|
component: Items, |
|
|
|
}) |
|
|
|
|
|
|
|
function Items() { |
|
|
|
const showToast = useCustomToast() |
|
|
|
const { |
|
|
|
data: items, |
|
|
|
isLoading, |
|
|
|
isError, |
|
|
|
error, |
|
|
|
} = useQuery({ |
|
|
|
function ItemsTableBody() { |
|
|
|
const { data: items } = useSuspenseQuery({ |
|
|
|
queryKey: ["items"], |
|
|
|
queryFn: () => ItemsService.readItems({}), |
|
|
|
}) |
|
|
|
|
|
|
|
if (isError) { |
|
|
|
const errDetail = (error as any).body?.detail |
|
|
|
showToast("Something went wrong.", `${errDetail}`, "error") |
|
|
|
return ( |
|
|
|
<Tbody> |
|
|
|
{items.data.map((item) => ( |
|
|
|
<Tr key={item.id}> |
|
|
|
<Td>{item.id}</Td> |
|
|
|
<Td>{item.title}</Td> |
|
|
|
<Td color={!item.description ? "ui.dim" : "inherit"}> |
|
|
|
{item.description || "N/A"} |
|
|
|
</Td> |
|
|
|
<Td> |
|
|
|
<ActionsMenu type={"Item"} value={item} /> |
|
|
|
</Td> |
|
|
|
</Tr> |
|
|
|
))} |
|
|
|
</Tbody> |
|
|
|
) |
|
|
|
} |
|
|
|
|
|
|
|
function ItemsTable() { |
|
|
|
return ( |
|
|
|
<> |
|
|
|
{isLoading ? ( |
|
|
|
// TODO: Add skeleton
|
|
|
|
<Flex justify="center" align="center" height="100vh" width="full"> |
|
|
|
<Spinner size="xl" color="ui.main" /> |
|
|
|
</Flex> |
|
|
|
) : ( |
|
|
|
items && ( |
|
|
|
<Container maxW="full"> |
|
|
|
<Heading |
|
|
|
size="lg" |
|
|
|
textAlign={{ base: "center", md: "left" }} |
|
|
|
pt={12} |
|
|
|
> |
|
|
|
Items Management |
|
|
|
</Heading> |
|
|
|
<Navbar type={"Item"} /> |
|
|
|
<TableContainer> |
|
|
|
<Table size={{ base: "sm", md: "md" }}> |
|
|
|
<Thead> |
|
|
@ -68,25 +59,49 @@ function Items() { |
|
|
|
<Th>Actions</Th> |
|
|
|
</Tr> |
|
|
|
</Thead> |
|
|
|
<ErrorBoundary |
|
|
|
fallbackRender={({ error }) => ( |
|
|
|
<Tbody> |
|
|
|
{items.data.map((item) => ( |
|
|
|
<Tr key={item.id}> |
|
|
|
<Td>{item.id}</Td> |
|
|
|
<Td>{item.title}</Td> |
|
|
|
<Td color={!item.description ? "ui.dim" : "inherit"}> |
|
|
|
{item.description || "N/A"} |
|
|
|
</Td> |
|
|
|
<Td> |
|
|
|
<ActionsMenu type={"Item"} value={item} /> |
|
|
|
<Tr> |
|
|
|
<Td colSpan={4}>Something went wrong: {error.message}</Td> |
|
|
|
</Tr> |
|
|
|
</Tbody> |
|
|
|
)} |
|
|
|
> |
|
|
|
<Suspense |
|
|
|
fallback={ |
|
|
|
<Tbody> |
|
|
|
{new Array(5).fill(null).map((_, index) => ( |
|
|
|
<Tr key={index}> |
|
|
|
{new Array(4).fill(null).map((_, index) => ( |
|
|
|
<Td key={index}> |
|
|
|
<Flex> |
|
|
|
<Skeleton height="20px" width="20px" /> |
|
|
|
</Flex> |
|
|
|
</Td> |
|
|
|
))} |
|
|
|
</Tr> |
|
|
|
))} |
|
|
|
</Tbody> |
|
|
|
} |
|
|
|
> |
|
|
|
<ItemsTableBody /> |
|
|
|
</Suspense> |
|
|
|
</ErrorBoundary> |
|
|
|
</Table> |
|
|
|
</TableContainer> |
|
|
|
</Container> |
|
|
|
) |
|
|
|
)} |
|
|
|
</> |
|
|
|
} |
|
|
|
|
|
|
|
function Items() { |
|
|
|
return ( |
|
|
|
<Container maxW="full"> |
|
|
|
<Heading size="lg" textAlign={{ base: "center", md: "left" }} pt={12}> |
|
|
|
Items Management |
|
|
|
</Heading> |
|
|
|
|
|
|
|
<Navbar type={"Item"} /> |
|
|
|
<ItemsTable /> |
|
|
|
</Container> |
|
|
|
) |
|
|
|
} |
|
|
|