diff --git a/src/components/pages/master-data/area/AreasTable.tsx b/src/components/pages/master-data/area/AreasTable.tsx
new file mode 100644
index 00000000..4d0bec73
--- /dev/null
+++ b/src/components/pages/master-data/area/AreasTable.tsx
@@ -0,0 +1,276 @@
+'use client';
+
+import { ChangeEventHandler, useEffect, useState } from 'react';
+import useSWR from 'swr';
+import { CellContext, ColumnDef, SortingState } from '@tanstack/react-table';
+import toast from 'react-hot-toast';
+
+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 { Area } from '@/types/api/master-data/area';
+import { AreaApi } from '@/services/api/master-data';
+import { cn } from '@/lib/helper';
+import { isResponseSuccess } from '@/lib/api-helper';
+import { useTableFilter } from '@/services/hooks/useTableFilter';
+import { ROWS_OPTIONS } from '@/config/constant';
+
+const RowOptionsMenu = ({
+ type = 'dropdown',
+ props,
+ deleteClickHandler,
+}: {
+ type: 'dropdown' | 'collapse';
+ props: CellContext;
+ deleteClickHandler: () => void;
+}) => {
+ return (
+
+
+
+
+
+
+
+ );
+};
+
+const AreasTable = () => {
+ const {
+ state: tableFilterState,
+ updateFilter,
+ setPage,
+ setPageSize,
+ toQueryString: getTableFilterQueryString,
+ } = useTableFilter({
+ initial: { search: '', nameSort: '' },
+ paramMap: { page: 'page', pageSize: 'limit', nameSort: 'sort_name' },
+ });
+
+ const {
+ data: areas,
+ isLoading,
+ mutate: refreshAreas,
+ } = useSWR(
+ `${AreaApi.basePath}${getTableFilterQueryString()}`,
+ AreaApi.getAllFetcher
+ );
+
+ const deleteModal = useModal();
+
+ const [selectedArea, setSelectedArea] = useState(undefined);
+ const [isDeleteLoading, setIsDeleteLoading] = useState(false);
+
+ const [sorting, setSorting] = useState([]);
+
+ const areasColumns: ColumnDef[] = [
+ {
+ header: '#',
+ cell: (props) =>
+ tableFilterState.pageSize * (tableFilterState.page - 1) +
+ props.row.index +
+ 1,
+ },
+ {
+ accessorKey: 'name',
+ header: 'Nama',
+ },
+ {
+ 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 = () => {
+ setSelectedArea(props.row.original);
+ deleteModal.openModal();
+ };
+
+ return (
+ <>
+ {currentPageSize > 2 && (
+
+
+
+ )}
+
+ {currentPageSize <= 2 && (
+
+
+
+ )}
+ >
+ );
+ },
+ },
+ ];
+
+ const confirmationModalDeleteClickHandler = async () => {
+ setIsDeleteLoading(true);
+
+ await AreaApi.delete(selectedArea?.id as number);
+ refreshAreas();
+
+ deleteModal.closeModal();
+ toast.success('Successfully delete Area!');
+ setIsDeleteLoading(false);
+ };
+
+ const searchChangeHandler: ChangeEventHandler = (e) => {
+ updateFilter('search', e.target.value);
+ };
+
+ const pageSizeChangeHandler = (val: OptionType | OptionType[] | null) => {
+ const newVal = val as OptionType;
+
+ setPageSize(newVal.value as number);
+ };
+
+ // track sorting
+ useEffect(() => {
+ const isNameSorted = sorting.find((sortItem) => sortItem.id === 'name');
+
+ if (!isNameSorted) {
+ updateFilter('nameSort', '');
+ } else {
+ updateFilter('nameSort', isNameSorted.desc ? 'desc' : 'asc');
+ }
+ }, [sorting]);
+
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ data={isResponseSuccess(areas) ? areas?.data : []}
+ columns={areasColumns}
+ pageSize={tableFilterState.pageSize}
+ page={isResponseSuccess(areas) ? areas?.meta?.page : 0}
+ totalItems={isResponseSuccess(areas) ? areas?.meta?.total_results : 0}
+ onPageChange={setPage}
+ isLoading={isLoading}
+ sorting={sorting}
+ setSorting={setSorting}
+ className={{
+ containerClassName: cn({
+ 'mb-20': isResponseSuccess(areas) && areas?.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 AreasTable;