summaryrefslogtreecommitdiff
path: root/src/modules/result/components/ProductModal.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules/result/components/ProductModal.tsx')
-rw-r--r--src/modules/result/components/ProductModal.tsx98
1 files changed, 98 insertions, 0 deletions
diff --git a/src/modules/result/components/ProductModal.tsx b/src/modules/result/components/ProductModal.tsx
new file mode 100644
index 0000000..a4ef49e
--- /dev/null
+++ b/src/modules/result/components/ProductModal.tsx
@@ -0,0 +1,98 @@
+import { Input, Modal, ModalBody, ModalContent, ModalHeader, Pagination, Skeleton, Table, TableBody, TableCell, TableColumn, TableHeader, TableRow } from '@nextui-org/react'
+import { Product } from '@prisma/client'
+import { useQuery } from '@tanstack/react-query'
+import React, { useEffect, useMemo, useState } from 'react'
+import { useDebounce } from 'usehooks-ts'
+
+type Props = {
+ modal: {
+ isOpen: boolean,
+ onOpenChange: () => void
+ }
+}
+
+const ProductModal = ({ modal }: Props) => {
+ const [page, setPage] = useState(1)
+ const [search, setSearch] = useState("")
+ const debouncedSearch = useDebounce(search, 500)
+
+ useEffect(() => {
+ setPage(1)
+ }, [debouncedSearch])
+
+ const { data } = useQuery({
+ queryKey: ['product', page, debouncedSearch],
+ queryFn: async () => {
+ const searchParams = new URLSearchParams({
+ page: page.toString(),
+ search: debouncedSearch,
+ type: 'all'
+ })
+ const response = await fetch(`/api/product?${searchParams}`)
+ const data: {
+ products: (Product & { company: { id: number, name: string } })[],
+ page: number,
+ totalPage: number
+ } = await response.json()
+
+ return data
+ }
+ })
+
+ const [totalPage, setTotalPage] = useState(1)
+
+ useEffect(() => {
+ if (data?.totalPage) setTotalPage(data?.totalPage)
+ }, [data?.totalPage])
+
+ return (
+ <Modal isOpen={modal.isOpen} onOpenChange={modal.onOpenChange} size='5xl'>
+ <ModalContent>
+ <ModalHeader>Product List</ModalHeader>
+ <ModalBody className='pb-6'>
+ <Input type='text' label="Search" value={search} onChange={(e) => setSearch(e.target.value)} />
+ {!data && (
+ <Skeleton isLoaded={!!data} className='rounded-lg h-[600px]' />
+ )}
+
+ {!!data && (
+ <Table className='max-h-[600px]' isHeaderSticky>
+ <TableHeader>
+ <TableColumn>NAME</TableColumn>
+ <TableColumn>ITEM CODE</TableColumn>
+ <TableColumn>BARCODE</TableColumn>
+ <TableColumn>ON-HAND QTY</TableColumn>
+ <TableColumn>DIFFERENCE QTY</TableColumn>
+ <TableColumn>COMPANY</TableColumn>
+ </TableHeader>
+ <TableBody items={data?.products || []}>
+ {(product) => (
+ <TableRow key={product.id}>
+ <TableCell>{product.name}</TableCell>
+ <TableCell>{product.itemCode}</TableCell>
+ <TableCell>{product.barcode}</TableCell>
+ <TableCell>{product.onhandQty}</TableCell>
+ <TableCell>{product.differenceQty}</TableCell>
+ <TableCell>{product.company.name}</TableCell>
+ </TableRow>
+ )}
+ </TableBody>
+ </Table>
+ )}
+
+ <Pagination
+ initialPage={1}
+ page={page}
+ total={totalPage}
+ onChange={(page) => setPage(page)}
+ className='mt-2'
+ />
+
+
+ </ModalBody>
+ </ModalContent>
+ </Modal>
+ )
+}
+
+export default ProductModal \ No newline at end of file