added organ in cms

This commit is contained in:
2024-10-26 20:24:36 +08:00
parent dcf4e3efe8
commit 1475714c7a
8 changed files with 782 additions and 4 deletions

View File

@@ -0,0 +1,161 @@
import {
Button,
Container,
Flex,
Heading,
SkeletonText,
Table,
TableContainer,
Tbody,
Td,
Th,
Thead,
Tr,
} from "@chakra-ui/react"
import { useQuery, useQueryClient } from "@tanstack/react-query"
import { createFileRoute, useNavigate } from "@tanstack/react-router"
import { useEffect } from "react"
import { z } from "zod"
import parse from 'html-react-parser';
import { OrganService } from "../../client"
import ActionsMenu from "../../components/Common/ActionsMenu"
import Navbar from "../../components/Common/Navbar"
import AddOrgan from "../../components/Organ/AddOrgan"
const organSearchSchema = z.object({
page: z.number().catch(1),
})
export const Route = createFileRoute("/_layout/organ")({
component: Organ,
validateSearch: (search) => organSearchSchema.parse(search),
})
const PER_PAGE = 100
function getItemsQueryOptions({ page }: { page: number }) {
return {
queryFn: () =>
OrganService.readOrgan({ skip: (page - 1) * PER_PAGE, limit: PER_PAGE }),
queryKey: ["organ", { page }],
}
}
function OrganTable() {
const queryClient = useQueryClient()
const { page } = Route.useSearch()
const navigate = useNavigate({ from: Route.fullPath })
const setPage = (page: number) =>
navigate({ search: (prev) => ({ ...prev, page }) })
const {
data: organ,
isPending,
isPlaceholderData,
} = useQuery({
...getItemsQueryOptions({ page }),
placeholderData: (prevData) => prevData,
})
organ?.data.sort((a, b) => a.index - b.index)
const hasNextPage = !isPlaceholderData && organ?.data.length === PER_PAGE
const hasPreviousPage = page > 1
useEffect(() => {
if (hasNextPage) {
queryClient.prefetchQuery(getItemsQueryOptions({ page: page + 1 }))
}
}, [page, queryClient, hasNextPage])
return (
<>
<TableContainer>
<Table size={{ base: "sm", md: "md" }}>
<Thead>
<Tr>
<Th>ID</Th>
<Th>Title</Th>
<Th>Description</Th>
<Th>Image</Th>
<Th>Index</Th>
<Th>Actions</Th>
</Tr>
</Thead>
{isPending ? (
<Tbody>
<Tr>
{new Array(4).fill(null).map((_, index) => (
<Td key={index}>
<SkeletonText noOfLines={1} paddingBlock="16px" />
</Td>
))}
</Tr>
</Tbody>
) : (
<Tbody>
{organ?.data.map((organ) => (
<Tr key={organ.id} opacity={isPlaceholderData ? 0.5 : 1}>
<Td isTruncated maxWidth="50">{organ.id}</Td>
<Td
whiteSpace="pre-line"
maxWidth="350px"
>
{parse(organ.title)}
</Td>
<Td
whiteSpace="pre-line"
maxWidth="350px"
>
{parse(organ.description) || "N/A"}
</Td>
<Td>
<img src={import.meta.env.VITE_IMAGE_URL + "/" + organ.image} width="100px" height="100px" />
</Td>
<Td isTruncated maxWidth="10px">
{organ.index}
</Td>
<Td>
<ActionsMenu type={"AboutUs"} value={organ} />
</Td>
</Tr>
))}
</Tbody>
)}
</Table>
</TableContainer>
<Flex
gap={4}
alignItems="center"
mt={4}
direction="row"
justifyContent="flex-end"
>
<Button onClick={() => setPage(page - 1)} isDisabled={!hasPreviousPage}>
Previous
</Button>
<span>Page {page}</span>
<Button isDisabled={!hasNextPage} onClick={() => setPage(page + 1)}>
Next
</Button>
</Flex>
</>
)
}
function Organ() {
return (
<Container maxW="full">
<Heading size="lg" textAlign={{ base: "center", md: "left" }} pt={12}>
Electric organ Management
</Heading>
<Navbar type={"AboutUs"} addModalAs={AddOrgan} />
<OrganTable />
</Container>
)
}