added organ in cms
This commit is contained in:
		
							
								
								
									
										161
									
								
								frontend/src/routes/_layout/organ.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										161
									
								
								frontend/src/routes/_layout/organ.tsx
									
									
									
									
									
										Normal 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> | ||||
|     ) | ||||
| } | ||||
		Reference in New Issue
	
	Block a user