From 35c809193ba2bab5295db28f2be8ac37b8b2d931 Mon Sep 17 00:00:00 2001 From: ValdiANS Date: Thu, 2 Oct 2025 12:01:14 +0700 Subject: [PATCH] feat(FE-40): create NonstocksTable component --- .../master-data/nonstock/NonstocksTable.tsx | 243 ++++++++++++++++++ 1 file changed, 243 insertions(+) create mode 100644 src/components/pages/master-data/nonstock/NonstocksTable.tsx diff --git a/src/components/pages/master-data/nonstock/NonstocksTable.tsx b/src/components/pages/master-data/nonstock/NonstocksTable.tsx new file mode 100644 index 00000000..4a2dbc5b --- /dev/null +++ b/src/components/pages/master-data/nonstock/NonstocksTable.tsx @@ -0,0 +1,243 @@ +'use client'; + +import { ChangeEventHandler, useState } from 'react'; +import useSWR from 'swr'; +import { CellContext, ColumnDef } from '@tanstack/react-table'; + +import { Icon } from '@iconify/react'; +import Table from '@/components/Table'; +import TextInput from '@/components/input/TextInput'; +import Button from '@/components/Button'; +import Collapse from '@/components/Collapse'; + +import { httpClientFetcher } from '@/services/http/client'; +import { Nonstock, NonstocksResponse } from '@/types/api/master-data/nonstock'; +import { cn } from '@/lib/helper'; +import { deleteNonstock } from '@/services/api/master-data/nonstock'; +import { isResponseSuccess } from '@/lib/api-helper'; + +const RowOptionsMenu = ({ + type = 'dropdown', + props, + deleteClickHandler, +}: { + type: 'dropdown' | 'collapse'; + props: CellContext; + deleteClickHandler: () => Promise; +}) => { + return ( +
+ + + + + +
+ ); +}; + +const RowDropdownOptions = ({ + props, + isLast2Rows, + deleteClickHandler, +}: { + props: CellContext; + isLast2Rows: boolean; + deleteClickHandler: () => Promise; +}) => { + return ( +
+ + + +
+ ); +}; + +const RowCollapseOptions = ({ + props, + deleteClickHandler, +}: { + props: CellContext; + deleteClickHandler: () => Promise; +}) => { + return ( + + + + } + className='w-fit' + titleClassName='p-0! justify-self-end' + > + + + ); +}; + +const NonstocksTable = () => { + const { + data: nonstocks, + isLoading, + mutate: refreshNonstocks, + } = useSWR('/master-data/nonstocks', httpClientFetcher); + + const [searchValue, setSearchValue] = useState(''); + + const nonstocksColumns: ColumnDef[] = [ + { + header: '#', + cell: (props) => props.row.index + 1, + }, + { + header: 'Nama', + accessorKey: 'name', + }, + { + header: 'Aksi', + cell: (props) => { + const currentPageSize = props.table.getPaginationRowModel().rows.length; + const currentPageRows = props.table.getPaginationRowModel().flatRows; + const currentRowRelativeIndex = + currentPageRows.findIndex((r) => r.id === props.row.id) + 1; + + const isLast2Rows = currentRowRelativeIndex > currentPageSize - 2; + + const deleteClickHandler = async () => { + const confirmation = confirm( + 'Apakah anda yakin untuk menghapus non stock ini?' + ); + + if (confirmation) { + await deleteNonstock(props.row.original.id); + refreshNonstocks(); + alert('Nonstock berhasil dihapus!'); + } + }; + + return ( + <> + {currentPageSize > 2 && ( + + )} + + {currentPageSize <= 2 && ( + + )} + + ); + }, + }, + ]; + + const searchChangeHandler: ChangeEventHandler = (e) => { + setSearchValue(e.target.value); + }; + + return ( +
+
+
+ +
+ + +
+ + + data={isResponseSuccess(nonstocks) ? nonstocks?.data : []} + columns={nonstocksColumns} + pageSize={10} + fuzzySearchValue={searchValue} + onFuzzySearchValueChange={setSearchValue} + isLoading={isLoading} + className={{ + containerClassName: cn({ + 'mb-20': + isResponseSuccess(nonstocks) && nonstocks?.data?.length === 0, + }), + tableWrapperClassName: 'overflow-x-auto min-h-full!', + tableClassName: 'font-inter w-full table-auto min-h-full!', + headerRowClassName: 'border-b border-b-gray-200', + headerColumnClassName: + 'px-6 py-3 text-xs font-semibold text-gray-500 last:flex last:flex-row last:justify-end', + bodyRowClassName: 'border-b border-b-gray-200', + bodyColumnClassName: + 'px-6 py-3 last:flex last:flex-row last:justify-end', + }} + /> +
+ ); +}; + +export default NonstocksTable;