refactor(FE-84-87) refactor checkbox using reuseable component checkboxinput

This commit is contained in:
randy-ar
2025-10-25 13:58:46 +07:00
parent 4f3dfb4221
commit f0f6ec53cb
10 changed files with 476 additions and 275 deletions
@@ -1,6 +1,7 @@
'use client';
import Button from '@/components/Button';
import CheckboxInput from '@/components/input/CheckboxInput';
import DebouncedTextInput from '@/components/input/DebouncedTextInput';
import SelectInput, { OptionType } from '@/components/input/SelectInput';
import { useModal } from '@/components/Modal';
@@ -120,10 +121,15 @@ const ProjectFlockTable = () => {
periodFilter: 'period',
},
});
// State
const [rowSelection, setRowSelection] = useState<Record<string, boolean>>({});
const selectedRowIds = Object.keys(rowSelection)
.filter((id) => rowSelection[id])
.map((id) => parseInt(id));
const [locationSelectInputValue, setLocationSelectInputValue] = useState('');
const [areaSelectInputValue, setAreaSelectInputValue] = useState('');
const [kandangSelectInputValue, setKandangSelectInputValue] = useState('');
const [selectedArea, setSelectedArea] = useState<OptionType | null>(null);
const [selectedLocation, setSelectedLocation] = useState<OptionType | null>(
null
@@ -132,6 +138,14 @@ const ProjectFlockTable = () => {
null
);
const [periodInputValue, setPeriodInputValue] = useState<number | null>(null);
const [sorting, setSorting] = useState<SortingState>([]);
const [selectedProjectFlock, setSelectedProjectFlock] =
useState<ProjectFlock>();
const deleteModal = useModal();
const confirmModal = useModal();
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
const [selectedFlocks, setSelectedFlocks] = useState<ProjectFlock[]>([]);
const [isApproveLoading, setIsApproveLoading] = useState(false);
// Fetch Data
const {
@@ -193,16 +207,6 @@ const ProjectFlockTable = () => {
}))
: [];
// State
const [sorting, setSorting] = useState<SortingState>([]);
const [selectedProjectFlock, setSelectedProjectFlock] =
useState<ProjectFlock>();
const deleteModal = useModal();
const confirmModal = useModal();
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
const [selectedIds, setSelectedIds] = useState<number[]>([]);
const [selectedFlocks, setSelectedFlocks] = useState<ProjectFlock[]>([]);
const [isApproveLoading, setIsApproveLoading] = useState(false);
// Handler
const pageSizeChangeHandler = (val: OptionType | OptionType[] | null) => {
const newVal = val as OptionType;
@@ -221,40 +225,6 @@ const ProjectFlockTable = () => {
const searchChangeHandler: ChangeEventHandler<HTMLInputElement> = (e) => {
updateFilter('search', e.target.value);
};
const handleSelectAll = (checked: boolean) => {
if (checked && isResponseSuccess(projectFlocks)) {
const allIds = projectFlocks.data
.filter((item) => item.approval.step_name === 'Pengajuan')
.map((item) => item.id);
setSelectedIds(allIds);
setSelectedFlocks(
projectFlocks.data.filter(
(item) => item.approval.step_name === 'Pengajuan'
)
);
} else {
setSelectedIds([]);
setSelectedFlocks([]);
}
};
const handleSelectRow = (id: number, checked: boolean) => {
if (!isResponseSuccess(projectFlocks)) return;
const targetFlock = projectFlocks.data.find((item) => item.id === id);
if (!targetFlock) return;
if (checked) {
setSelectedIds((prev) => [...prev, id]);
setSelectedFlocks((prev) => [...(prev || []), targetFlock]);
} else {
setSelectedIds((prev) => prev.filter((val) => val !== id));
setSelectedFlocks((prev) =>
(prev || []).filter((flock) => flock.id !== id)
);
}
};
const confirmationModalApproveClickHandler = async () => {
setIsApproveLoading(true);
@@ -265,7 +235,7 @@ const ProjectFlockTable = () => {
method: 'POST',
payload: {
action: 'APPROVED',
approvable_ids: selectedFlocks.map((flock) => flock.id),
approvable_ids: selectedRowIds.map((id) => id),
},
});
@@ -277,8 +247,7 @@ const ProjectFlockTable = () => {
toast.error(approveProjectFlockRes?.message as string);
confirmModal.closeModal();
}
setSelectedIds([]);
setSelectedFlocks([]);
setRowSelection({});
refreshProjectFlocks();
setIsApproveLoading(false);
};
@@ -301,11 +270,9 @@ const ProjectFlockTable = () => {
variant='outline'
color='success'
onClick={() => {
if (selectedIds.length > 0) {
confirmModal.openModal();
}
confirmModal.openModal();
}}
disabled={!(selectedIds.length > 0)}
disabled={selectedRowIds.length === 0}
className='w-full sm:w-fit'
>
<Icon icon='material-symbols:check' width={24} height={24} />
@@ -400,33 +367,58 @@ const ProjectFlockTable = () => {
columns={[
{
id: 'select',
header: () => {
const allSelected =
isResponseSuccess(projectFlocks) &&
projectFlocks.data.length > 0 &&
selectedIds.length === projectFlocks.data.length;
return (
<input
type='checkbox'
className='checkbox checkbox-sm'
checked={allSelected}
onChange={(e) => handleSelectAll(e.target.checked)}
/>
header: ({ table }) => {
const allRows = table.getRowModel().rows;
const selectableRows = allRows.filter(
(row) => row.original?.approval?.step_number == 1
);
},
cell: (props) => {
const id = props.row.original.id;
const isChecked = selectedIds.includes(id);
const allSelected = selectableRows.every((row) =>
row.getIsSelected()
) && selectableRows.length != 0;
const someSelected =
selectableRows.some((row) => row.getIsSelected()) &&
!allSelected;
const toggleSelectableRows = () => {
const shouldSelect = !allSelected;
selectableRows.forEach((row) =>
row.toggleSelected(shouldSelect)
);
};
return (
<input
disabled={
props.row.original.approval.step_name != 'Pengajuan'
<div className='w-full flex flex-row justify-center'>
<CheckboxInput
name='allRow'
checked={allSelected}
indeterminate={someSelected}
onChange={toggleSelectableRows}
disabled={
isResponseSuccess(projectFlocks) &&
projectFlocks?.data?.filter(
(flock) => flock.approval.step_number == 1
).length == 0
}
/>
</div>
);
},
cell: ({ row }) => {
return (
<CheckboxInput
name='row'
checked={
row.getIsSelected() &&
row.original.approval.step_number == 1
}
type='checkbox'
className='checkbox checkbox-sm'
checked={isChecked}
onChange={(e) => handleSelectRow(id, e.target.checked)}
disabled={
!row.getCanSelect() ||
row.original.approval.step_number != 1
}
indeterminate={row.getIsSomeSelected()}
onChange={row.getToggleSelectedHandler()}
/>
);
},
@@ -541,6 +533,8 @@ const ProjectFlockTable = () => {
isLoading={isLoading}
sorting={sorting}
setSorting={setSorting}
rowSelection={rowSelection}
setRowSelection={setRowSelection}
className={{
containerClassName: cn({
'mb-20':
@@ -578,18 +572,19 @@ const ProjectFlockTable = () => {
<ConfirmationModal
ref={confirmModal.ref}
type='success'
text={
selectedFlocks.length > 0
? `Apakah anda yakin ingin approve Project Flock berikut? (${selectedFlocks
.map(
(flock) =>
`${flock.flock?.name ?? '(Tanpa nama)'} - ${
flock.area?.name ?? '-'
}`
)
.join(', ')})`
: 'Tidak ada Project Flock yang dipilih.'
}
text={`Apakah anda yakin ingin reject data transfer ke laying ini (${selectedRowIds.length} data)?`}
// text={
// selectedFlocks.length > 0
// ? `Apakah anda yakin ingin approve Project Flock berikut? (${selectedFlocks
// .map(
// (flock) =>
// `${flock.flock?.name ?? '(Tanpa nama)'} - ${
// flock.area?.name ?? '-'
// }`
// )
// .join(', ')})`
// : 'Tidak ada Project Flock yang dipilih.'
// }
secondaryButton={{
text: 'Tidak',
}}