diff --git a/src/components/pages/inventory/movement/MovementTable.tsx b/src/components/pages/inventory/movement/MovementTable.tsx index c863a1a9..b39906d3 100644 --- a/src/components/pages/inventory/movement/MovementTable.tsx +++ b/src/components/pages/inventory/movement/MovementTable.tsx @@ -1,23 +1,22 @@ 'use client'; import { useState, useMemo } from 'react'; -import { CellContext, ColumnDef, SortingState } from '@tanstack/react-table'; +import { SortingState } from '@tanstack/react-table'; import { Icon } from '@iconify/react'; import Table from '@/components/Table'; -import DebouncedTextInput from '@/components/input/DebouncedTextInput'; -import Button from '@/components/Button'; import { useModal } from '@/components/Modal'; import ConfirmationModal from '@/components/modal/ConfirmationModal'; -import SelectInput, { OptionType } from '@/components/input/SelectInput'; -import RowDropdownOptions from '@/components/table/RowDropdownOptions'; -import RowCollapseOptions from '@/components/table/RowCollapseOptions'; -import { cn } from '@/lib/helper'; import { ROWS_OPTIONS } from '@/config/constant'; import { Movement } from '@/types/api/inventory/movement'; -import { BaseMetadata } from '@/types/api/api-general'; +import { TableToolbar } from '@/components/table/TableToolbar'; +import { TableRowSizeSelector } from '@/components/table/TableRowSizeSelector'; +import { TableRowOptions } from '@/components/table/TableRowOptions'; +import { OptionType } from '@/components/input/SelectInput'; +import Button from '@/components/Button'; +import { cn } from '@/lib/helper'; // Dummy data -const baseMetadata: BaseMetadata = { +const baseMetadata = { created_user: { id: 1, id_user: 1, @@ -339,159 +338,17 @@ const dummyMovements: Movement[] = [ }, ]; - -const RowOptionsMenu = ({ - type = 'dropdown', - props, - deleteClickHandler, -}: { - type: 'dropdown' | 'collapse'; - props: CellContext; - deleteClickHandler: () => void; -}) => ( -
- - - -
-); - const MovementTable = () => { const [search, setSearch] = useState(''); const [page, setPage] = useState(1); const [pageSize, setPageSize] = useState(10); const [sorting, setSorting] = useState([]); - const [selectedMovement, setSelectedMovement] = useState< - Movement | undefined - >(undefined); + const [, setSelectedMovement] = useState(undefined); const [isDeleteLoading, setIsDeleteLoading] = useState(false); - const paginatedData = useMemo(() => { - const start = (page - 1) * pageSize; - return dummyMovements.slice(start, start + pageSize); - }, [page, pageSize]); - - const movementsColumns: ColumnDef[] = [ - { - header: '#', - cell: (props) => pageSize * (page - 1) + props.row.index + 1, - }, - { - accessorKey: 'warehouse_asal', - header: 'Gudang Asal', - cell: (props) => props.row.original.warehouse_asal.name, - }, - { - accessorKey: 'warehouse_tujuan', - header: 'Gudang Tujuan', - cell: (props) => props.row.original.warehouse_tujuan.name, - }, - { - accessorKey: 'product', - header: 'Nama Produk', - cell: (props) => props.row.original.product.map((p) => p.product.name), - }, - { - accessorKey: 'alasan_transfer', - header: 'Catatan', - }, - { - accessorKey: 'biaya_ekspedisi', - header: 'Biaya Ekspedisi', - cell: (props) => - props.row.original.ekspedisi.map((e) => e.biaya_ekspedisi), - }, - { - 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 = () => { - setSelectedMovement(props.row.original); - deleteModal.openModal(); - }; - - return ( - <> - {currentPageSize > 2 && ( - - - - )} - {currentPageSize <= 2 && ( - - - - )} - - ); - }, - }, - ]; - const deleteModal = useModal(); - const confirmationModalDeleteClickHandler = async () => { - setIsDeleteLoading(true); - setTimeout(() => { - setIsDeleteLoading(false); - deleteModal.closeModal(); - }, 1000); - }; - const searchChangeHandler: React.ChangeEventHandler = ( - e - ) => { + const searchChangeHandler = (e: React.ChangeEvent) => { setSearch(e.target.value); setPage(1); }; @@ -502,67 +359,119 @@ const MovementTable = () => { setPage(1); }; + const confirmationModalDeleteClickHandler = async () => { + setIsDeleteLoading(true); + setTimeout(() => { + setIsDeleteLoading(false); + deleteModal.closeModal(); + }, 1000); + }; + + const paginatedData = useMemo(() => { + const start = (page - 1) * pageSize; + return dummyMovements.slice(start, start + pageSize); + }, [page, pageSize]); + return ( - <> -
-
-
-
- -
- -
-
- -
-
- - data={paginatedData} - columns={movementsColumns} - pageSize={pageSize} - page={page} - totalItems={dummyMovements.length} - onPageChange={setPage} - isLoading={false} - sorting={sorting} - setSorting={setSorting} - className={{ - containerClassName: cn({ - 'mb-20': paginatedData.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', +
+
+ +
+ + pageSize * (page - 1) + props.row.index + 1, + }, + { + accessorKey: 'warehouse_asal', + header: 'Gudang Asal', + cell: (props) => props.row.original.warehouse_asal.name, + }, + { + accessorKey: 'warehouse_tujuan', + header: 'Gudang Tujuan', + cell: (props) => props.row.original.warehouse_tujuan.name, + }, + { + accessorKey: 'product', + header: 'Nama Produk', + cell: (props) => + props.row.original.product.map((p) => p.product.name), + }, + { + accessorKey: 'alasan_transfer', + header: 'Catatan', + }, + { + accessorKey: 'biaya_ekspedisi', + header: 'Biaya Ekspedisi', + cell: (props) => + props.row.original.ekspedisi.map((e) => e.biaya_ekspedisi), + }, + { + id: 'actions', + cell: (props) => ( +
+ + { + setSelectedMovement(props.row.original); + deleteModal.openModal(); + }} + /> +
+ ), + }, + ]} + pageSize={pageSize} + page={page} + totalItems={dummyMovements.length} + onPageChange={setPage} + isLoading={false} + sorting={sorting} + setSorting={setSorting} + className={{ + containerClassName: cn({ + 'mb-20': paginatedData.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', + }} + /> + { onClick: confirmationModalDeleteClickHandler, }} /> - + ); }; diff --git a/src/components/table/TableRowOptions.tsx b/src/components/table/TableRowOptions.tsx new file mode 100644 index 00000000..61332b4f --- /dev/null +++ b/src/components/table/TableRowOptions.tsx @@ -0,0 +1,62 @@ +import { Icon } from '@iconify/react'; +import Button from '../Button'; +import { cn } from '@/lib/helper'; + +interface TableRowOptionsProps { + type?: 'dropdown' | 'collapse'; + recordId: string | number; + basePath: string; + onDelete?: () => void; +} + +export const TableRowOptions = ({ + type = 'dropdown', + recordId, + basePath, + onDelete, +}: TableRowOptionsProps) => ( +
+ + + {onDelete && ( + + )} +
+); diff --git a/src/components/table/TableRowSizeSelector.tsx b/src/components/table/TableRowSizeSelector.tsx new file mode 100644 index 00000000..a6fd039d --- /dev/null +++ b/src/components/table/TableRowSizeSelector.tsx @@ -0,0 +1,33 @@ +import SelectInput from '../input/SelectInput'; + +export interface OptionType { + label: string; + value: string | number; +} + +interface TableRowSizeSelectorProps { + value: number; + onChange: (val: OptionType | OptionType[] | null) => void; + options: OptionType[]; +} + +export const TableRowSizeSelector = ({ + value, + onChange, + options, +}: TableRowSizeSelectorProps) => { + return ( +
+ +
+ ); +}; diff --git a/src/components/table/TableToolbar.tsx b/src/components/table/TableToolbar.tsx new file mode 100644 index 00000000..e3b385b1 --- /dev/null +++ b/src/components/table/TableToolbar.tsx @@ -0,0 +1,37 @@ +import { Icon } from '@iconify/react'; +import Button from '../Button'; +import DebouncedTextInput from '../input/DebouncedTextInput'; + +interface TableToolbarProps { + addButton?: { + href: string; + label: string; + }; + search: { + value: string; + onChange: (e: React.ChangeEvent) => void; + placeholder?: string; + }; +} + +export const TableToolbar = ({ addButton, search }: TableToolbarProps) => { + return ( +
+ {addButton && ( +
+ +
+ )} + +
+ ); +};