From be0f537dc4fe384eef09436833c6407e6482c16d Mon Sep 17 00:00:00 2001
From: Rafi Zadanly <zadanlyr@gmail.com>
Date: Thu, 9 Nov 2023 15:40:16 +0700
Subject: Initial commit

---
 src/modules/result/components/ProductModal.tsx | 98 ++++++++++++++++++++++++++
 1 file changed, 98 insertions(+)
 create mode 100644 src/modules/result/components/ProductModal.tsx

(limited to 'src/modules/result/components/ProductModal.tsx')

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
-- 
cgit v1.2.3

