diff --git a/src/components/pages/inventory/adjustment/InventoryAdjustmentTable.tsx b/src/components/pages/inventory/adjustment/InventoryAdjustmentTable.tsx index f8bd4443..fb0270ad 100644 --- a/src/components/pages/inventory/adjustment/InventoryAdjustmentTable.tsx +++ b/src/components/pages/inventory/adjustment/InventoryAdjustmentTable.tsx @@ -8,7 +8,7 @@ import { useState, } from 'react'; import { usePathname } from 'next/navigation'; -import useSWR from 'swr'; +import useSWR, { mutate } from 'swr'; import { Icon } from '@iconify/react'; import { ColumnDef, ColumnSort, SortingState } from '@tanstack/react-table'; import { useFormik } from 'formik'; @@ -26,6 +26,10 @@ import { InventoryAdjustmentApi } from '@/services/api/inventory'; import { WarehouseApi, ProductApi } from '@/services/api/master-data'; import { useTableFilter } from '@/services/hooks/useTableFilter'; import { useUiStore } from '@/stores/ui/ui.store'; +import ConfirmationModal from '@/components/modal/ConfirmationModal'; +import PopoverButton from '@/components/popover/PopoverButton'; +import PopoverContent from '@/components/popover/PopoverContent'; +import toast from 'react-hot-toast'; import { InventoryAdjustment } from '@/types/api/inventory/adjustment'; import { Warehouse } from '@/types/api/master-data/warehouse'; import { TRANSACTION_SUBTYPE_OPTIONS } from '@/config/constant'; @@ -38,6 +42,62 @@ import { AdjustmentFilterType, } from '@/components/pages/inventory/adjustment/filter/AdjustmentFilter'; import SelectInputRadio from '@/components/input/SelectInputRadio'; +import { CellContext } from '@tanstack/react-table'; + +const RowOptionsMenu = ({ + popoverPosition = 'bottom', + props, + deleteClickHandler, +}: { + popoverPosition: 'bottom' | 'top'; + props: CellContext; + deleteClickHandler: () => void; +}) => { + const popoverId = `adjustment#${props.row.original.id}`; + const popoverAnchorName = `--anchor-adjustment#${props.row.original.id}`; + + const closePopover = () => { + document.getElementById(popoverId)?.hidePopover(); + }; + + return ( +
+ + + + + +
+ + + +
+
+
+ ); +}; const InventoryAdjustmentTable = () => { const { searchValue, setSearchValue, setTableState } = useUiStore(); @@ -182,12 +242,31 @@ const InventoryAdjustmentTable = () => { formik.validateForm(); }; - const { data: inventoryAdjustments, isLoading } = useSWR( + const { data: inventoryAdjustments, isLoading, mutate: refreshAdjustments } = useSWR( `${InventoryAdjustmentApi.basePath}${getTableFilterQueryString()}`, InventoryAdjustmentApi.getAllFetcher ); + const singleDeleteHandler = async () => { + setIsDeleteLoading(true); + + const response = await InventoryAdjustmentApi.delete(selectedAdjustment?.id as number); + + singleDeleteModal.closeModal(); + setIsDeleteLoading(false); + + if (isResponseSuccess(response)) { + toast.success(response?.message || 'Successfully delete Adjustment!'); + refreshAdjustments(); + } else { + toast.error(response?.message || 'Failed to delete Adjustment'); + } + }; + const [sorting, setSorting] = useState([]); + const [selectedAdjustment, setSelectedAdjustment] = useState(undefined); + const [isDeleteLoading, setIsDeleteLoading] = useState(false); + const singleDeleteModal = useModal(); useEffect(() => { updateFilter('search', searchValue); @@ -302,8 +381,32 @@ const InventoryAdjustmentTable = () => { header: 'Oleh', accessorFn: (row) => row.created_user?.name ?? '-', }, + { + id: 'actions', + header: 'Aksi', + cell: (props: CellContext) => { + 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 = () => { + setSelectedAdjustment(props.row.original); + singleDeleteModal.openModal(); + }; + + return ( + + ); + }, + }, ], - [tableFilterState.pageSize, tableFilterState.page] + [tableFilterState.pageSize, tableFilterState.page, singleDeleteModal, setSelectedAdjustment] ); const updateSortingFilter = useCallback( @@ -532,6 +635,21 @@ const InventoryAdjustmentTable = () => { + + ); }; diff --git a/src/components/pages/inventory/movement/MovementTable.tsx b/src/components/pages/inventory/movement/MovementTable.tsx index f953099d..1dfbb7ce 100644 --- a/src/components/pages/inventory/movement/MovementTable.tsx +++ b/src/components/pages/inventory/movement/MovementTable.tsx @@ -8,7 +8,7 @@ import { useState, } from 'react'; import { usePathname } from 'next/navigation'; -import useSWR from 'swr'; +import useSWR, { mutate } from 'swr'; import { SortingState, CellContext, ColumnDef } from '@tanstack/react-table'; import { useFormik } from 'formik'; @@ -21,6 +21,8 @@ import { cn } from '@/lib/helper'; import { isResponseSuccess } from '@/lib/api-helper'; import { useTableFilter } from '@/services/hooks/useTableFilter'; import { useUiStore } from '@/stores/ui/ui.store'; +import ConfirmationModal from '@/components/modal/ConfirmationModal'; +import toast from 'react-hot-toast'; import Button from '@/components/Button'; import DebouncedTextInput from '@/components/input/DebouncedTextInput'; import SelectInput, { useSelect } from '@/components/input/SelectInput'; @@ -41,9 +43,11 @@ import { const RowOptionsMenu = ({ popoverPosition = 'bottom', props, + deleteClickHandler, }: { popoverPosition: 'bottom' | 'top'; props: CellContext; + deleteClickHandler: () => void; }) => { const popoverId = `movement#${props.row.original.id}`; const popoverAnchorName = `--anchor-movement#${props.row.original.id}`; @@ -83,6 +87,20 @@ const RowOptionsMenu = ({ Detail + + + @@ -206,12 +224,31 @@ const MovementTable = () => { }; const [sorting, setSorting] = useState([]); + const [selectedMovement, setSelectedMovement] = useState(undefined); + const [isDeleteLoading, setIsDeleteLoading] = useState(false); + const singleDeleteModal = useModal(); - const { data: movements, isLoading } = useSWR( + const { data: movements, isLoading, mutate: refreshMovements } = useSWR( `${MovementApi.basePath}${getTableFilterQueryString()}`, MovementApi.getAllFetcher ); + const singleDeleteHandler = async () => { + setIsDeleteLoading(true); + + const response = await MovementApi.delete(selectedMovement?.id as number); + + singleDeleteModal.closeModal(); + setIsDeleteLoading(false); + + if (isResponseSuccess(response)) { + toast.success(response?.message || 'Successfully delete Movement!'); + refreshMovements(); + } else { + toast.error(response?.message || 'Failed to delete Movement'); + } + }; + useEffect(() => { updateFilter('search', searchValue); }, [searchValue, updateFilter]); @@ -275,16 +312,22 @@ const MovementTable = () => { const isLast2Rows = currentRowRelativeIndex > currentPageSize - 2; + const deleteClickHandler = () => { + setSelectedMovement(props.row.original); + singleDeleteModal.openModal(); + }; + return ( ); }, }, ], - [tableFilterState.pageSize, tableFilterState.page] + [tableFilterState.pageSize, tableFilterState.page, singleDeleteModal, setSelectedMovement] ); return ( @@ -455,6 +498,21 @@ const MovementTable = () => { + + ); };