diff options
Diffstat (limited to 'src/modules/result/components/Table.tsx')
| -rw-r--r-- | src/modules/result/components/Table.tsx | 83 |
1 files changed, 70 insertions, 13 deletions
diff --git a/src/modules/result/components/Table.tsx b/src/modules/result/components/Table.tsx index d2e5af4..021dfef 100644 --- a/src/modules/result/components/Table.tsx +++ b/src/modules/result/components/Table.tsx @@ -1,7 +1,7 @@ "use client"; import { useResultStore } from "@/common/stores/useResultStore"; import { StockOpnameRes } from "@/common/types/stockOpname"; -import { Badge, Pagination, Spacer } from "@nextui-org/react" +import { Button, Pagination, Skeleton, Spacer, Spinner } from "@nextui-org/react" import { useQuery } from "@tanstack/react-query"; import { useSearchParams } from "next/navigation"; import { useRouter } from "next/navigation"; @@ -9,31 +9,68 @@ import styles from "./table.module.css" import clsxm from "@/common/libs/clsxm"; import DetailRow from "./DetailRow"; import { useDebounce } from "usehooks-ts"; +import getClientCredential from "@/common/libs/getClientCredential"; +import { SHOWING_SELECTIONS } from "@/common/constants/result"; +import Link from "next/link"; +import { useState } from "react"; const Table = () => { + const credential = getClientCredential() + const params = useSearchParams() const router = useRouter() const page = params.get('page') ?? '1' - const { filter: { company, search } } = useResultStore() + const { filter: { company, search, show } } = useResultStore() const debouncedSearch = useDebounce(search, 500) const stockOpnames = useQuery({ - queryKey: ['stockOpnames', company, debouncedSearch, page], + queryKey: ['stockOpnames', company, debouncedSearch, page, show], queryFn: async () => { const searchParams = new URLSearchParams() if (!company) return null searchParams.set('companyId', company) - searchParams.set('page', page); + + const showValue = SHOWING_SELECTIONS.find((item) => item.key === show)?.value || '' + searchParams.set('show', showValue); + if (debouncedSearch) searchParams.set('search', debouncedSearch) + searchParams.set('page', page); + return await fetch(`/api/stock-opname?${searchParams}`) .then(res => res.json()) }, }) + const { filter } = useResultStore() + + const [exportLoad, setExportLoad] = useState<boolean>(false) + + const exportResult = async () => { + setExportLoad(true) + const response = await fetch(`/api/stock-opname/export?companyId=${filter.company}`) + const buffer = await response.arrayBuffer() + + const blob = new Blob([buffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }) + const url = window.URL.createObjectURL(blob) + const a = document.createElement('a') + a.href = url + a.download = 'export.xlsx' + document.body.appendChild(a) + a.click() + document.body.removeChild(a) + setExportLoad(false) + } + return ( <> + <div className="flex"> + <Button type="button" onPress={exportResult} disabled={exportLoad} variant="flat" className="ml-auto mb-4"> + {exportLoad ? <><Spinner size="sm" />Exporting...</> : 'Export'} + </Button> + </div> + <div className="w-full overflow-auto pb-4"> <table className="w-full"> <thead className={styles.thead}> @@ -41,6 +78,7 @@ const Table = () => { <th className={clsxm(styles.th, '!text-left')}>NAMA PRODUK</th> <th className={styles.th}>TIM HITUNG 1</th> <th className={styles.th}>TIM HITUNG 2</th> + <th className={styles.th}>TIM HITUNG 3</th> <th className={styles.th}>TIM VERIFIKASI</th> <th className={styles.th}>ON-HAND QTY</th> <th className={styles.th}>GUDANG SELISIH</th> @@ -48,13 +86,17 @@ const Table = () => { <tbody className={styles.tbody}> {stockOpnames.data?.result.map((stockOpname: StockOpnameRes['result']) => ( <> - <tr key={stockOpname.id} className="border-t border-neutral-200"> + <tr key={stockOpname.id} className={clsxm("border-t border-neutral-200", { + "text-danger-600": stockOpname.isDifferent, + "text-success-600": !stockOpname.isDifferent + })} + > <td className={styles.td}> - <div className={clsxm("w-full rounded-lg mr-1 mt-1.5 p-1 text-xs text-white whitespace-nowrap", { + <div className={clsxm("w-full rounded-lg mr-1 p-1 text-xs text-white whitespace-nowrap", { "bg-danger-600": stockOpname.isDifferent, "bg-success-600": !stockOpname.isDifferent, })}> - {stockOpname.isDifferent ? 'Tidak Sesuai' : 'Sesuai'} + {stockOpname.isDifferent ? 'Selisih' : 'Aman'} </div> </td> <td className={clsxm(styles.td, '!text-left flex min-w-[250px]')}> @@ -63,19 +105,22 @@ const Table = () => { {stockOpname.barcode ? ` [${stockOpname.barcode}]` : ''} </td> <td className={styles.td}> - {stockOpname.quantity.COUNT1 || '-'} + {credential?.team == 'VERIFICATION' && typeof stockOpname.quantity.COUNT1 === 'number' ? stockOpname.quantity.COUNT1 : '-'} + </td> + <td className={styles.td}> + {credential?.team == 'VERIFICATION' && typeof stockOpname.quantity.COUNT2 === 'number' ? stockOpname.quantity.COUNT2 : '-'} </td> <td className={styles.td}> - {stockOpname.quantity.COUNT2 || '-'} + {credential?.team == 'VERIFICATION' && typeof stockOpname.quantity.COUNT3 === 'number' ? stockOpname.quantity.COUNT3 : '-'} </td> <td className={styles.td}> - {stockOpname.quantity.VERIFICATION || '-'} + {credential?.team == 'VERIFICATION' && typeof stockOpname.quantity.VERIFICATION === 'number' ? stockOpname.quantity.VERIFICATION : '-'} </td> <td className={styles.td}> - {stockOpname.onhandQty} + {credential?.team == 'VERIFICATION' ? stockOpname.onhandQty : '-'} </td> <td className={styles.td}> - {stockOpname.differenceQty} + {credential?.team == 'VERIFICATION' ? stockOpname.differenceQty : '-'} </td> </tr> @@ -85,7 +130,19 @@ const Table = () => { {stockOpnames.data?.result.length === 0 && ( <tr> - <td colSpan={7} className="text-center text-neutral-600 py-4">Belum ada data untuk ditampilkan</td> + <td colSpan={8} className="text-center text-neutral-600 py-4">Belum ada data untuk ditampilkan</td> + </tr> + )} + + {stockOpnames.isLoading && ( + <tr> + <td colSpan={8}> + <div className="flex flex-col gap-y-2"> + {Array.from({ length: 6 }, (_, i) => ( + <Skeleton className="h-8" key={i} /> + ))} + </div> + </td> </tr> )} </tbody> |
