fix(FE-88-89) adjust category flock dengan API backend & set disabled input period

This commit is contained in:
randy-ar
2025-10-21 10:14:17 +07:00
parent 9964e1797a
commit 1672705464
10 changed files with 262 additions and 42 deletions
@@ -3,6 +3,7 @@
import Button from '@/components/Button';
import DebouncedTextInput from '@/components/input/DebouncedTextInput';
import SelectInput, { OptionType } from '@/components/input/SelectInput';
import TextInput from '@/components/input/TextInput';
import { useModal } from '@/components/Modal';
import ConfirmationModal from '@/components/modal/ConfirmationModal';
import Table from '@/components/Table';
@@ -11,6 +12,7 @@ import RowDropdownOptions from '@/components/table/RowDropdownOptions';
import { ROWS_OPTIONS } from '@/config/constant';
import { isResponseSuccess } from '@/lib/api-helper';
import { cn } from '@/lib/helper';
import { AreaApi, KandangApi, LocationApi } from '@/services/api/master-data';
import { ProjectFlockApi } from '@/services/api/production';
import { useTableFilter } from '@/services/hooks/useTableFilter';
import { Kandang } from '@/types/api/master-data/kandang';
@@ -92,12 +94,33 @@ const ProjectFlockTable = () => {
} = useTableFilter({
initial: {
search: '',
areaFilter: '',
locationFilter: '',
kandangFilter: '',
periodFilter: '',
},
paramMap: {
page: 'page',
pageSize: 'limit',
search: 'search',
areaFilter: 'area_id',
locationFilter: 'location_id',
kandangFilter: 'kandang_id',
periodFilter: 'period',
},
});
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
);
const [selectedKandang, setSelectedKandang] = useState<OptionType | null>(
null
);
const [periodInputValue, setPeriodInputValue] = useState<number | null>(null);
// Fetch Data
const {
@@ -109,6 +132,59 @@ const ProjectFlockTable = () => {
ProjectFlockApi.getAllFetcher
);
const areaUrl = `${AreaApi.basePath}?${new URLSearchParams({
search: areaSelectInputValue,
limit: '100',
}).toString()}`;
const {
data: areas,
isLoading: isLoadingAreas,
mutate: refreshAreas,
} = useSWR(areaUrl, AreaApi.getAllFetcher);
const locationUrl = `${LocationApi.basePath}?${new URLSearchParams({
search: locationSelectInputValue,
area_id: selectedArea != null ? selectedArea.value.toString() : '',
limit: '100',
}).toString()}`;
const {
data: locations,
isLoading: isLoadingLocations,
mutate: refreshLocations,
} = useSWR(locationUrl, LocationApi.getAllFetcher);
const kandangUrl = `${KandangApi.basePath}?${new URLSearchParams({
search: kandangSelectInputValue,
location_id:
selectedLocation != null ? selectedLocation.value.toString() : '',
limit: '100',
}).toString()}`;
const {
data: kandangs,
isLoading: isLoadingKandang,
mutate: refreshKandang,
} = useSWR(kandangUrl, KandangApi.getAllFetcher);
// Data to Options Mapping
const optionsArea = isResponseSuccess(areas)
? areas?.data.map((area) => ({
value: area.id,
label: area.name,
}))
: [];
const optionsKandang = isResponseSuccess(kandangs)
? kandangs?.data.map((kandang) => ({
value: kandang.id,
label: kandang.name,
}))
: [];
const optionsLocation = isResponseSuccess(locations)
? locations?.data.map((location) => ({
value: location.id,
label: location.name,
}))
: [];
// State
const [sorting, setSorting] = useState<SortingState>([]);
const [selectedProjectFlock, setSelectedProjectFlock] =
@@ -170,21 +246,23 @@ const ProjectFlockTable = () => {
header: 'FCR',
},
{
accessorKey: 'product_category.name',
header: 'Kategori Produk',
accessorKey: 'category',
header: 'Kategori',
},
{
header: 'Kandang',
cell: (props) => {
const kandang = props.row.original.kandangs;
const kandangNames = kandang.map((k: Kandang) => k.name);
console.log('kandang');
console.log(kandang);
return (
<div>
{kandangNames.length > 0 ? kandangNames.join(', ') : 'Tidak ada'}
</div>
);
if (kandang) {
const kandangNames = kandang.map((k: Kandang) => k.name);
return (
<div>
{kandangNames.length > 0 ? kandangNames.join(', ') : 'Tidak ada'}
</div>
);
}else{
return '-';
}
},
},
{
@@ -341,7 +419,60 @@ const ProjectFlockTable = () => {
/>
</div>
</div>
<div className='hidden sm:flex flex-row justify-end'>
<div className='hidden sm:flex flex-row justify-end gap-6 w-full'>
<SelectInput
label='Area'
options={optionsArea}
isLoading={isLoadingAreas}
value={selectedArea}
onChange={(val) => {
setSelectedArea(val as OptionType);
updateFilter(
'areaFilter',
(val as OptionType)?.value.toString()
);
}}
isClearable
/>
<SelectInput
label='Lokasi'
options={optionsLocation}
isLoading={isLoadingLocations}
value={selectedLocation}
onChange={(val) => {
setSelectedLocation(val as OptionType);
updateFilter(
'locationFilter',
(val as OptionType)?.value.toString()
);
}}
isClearable
/>
<SelectInput
label='Kandang'
options={optionsKandang}
isLoading={isLoadingKandang}
value={selectedKandang}
onChange={(val) => {
setSelectedKandang(val as OptionType);
updateFilter(
'kandangFilter',
(val as OptionType)?.value.toString()
);
}}
isClearable
/>
<DebouncedTextInput
name='period'
type='number'
label='Periode'
placeholder='Masukan periode'
value={periodInputValue ?? ''}
onChange={(e) => {
setPeriodInputValue(parseInt(e.target.value));
updateFilter('periodFilter', e.target.value);
}}
/>
<SelectInput
label='Baris'
options={ROWS_OPTIONS}
@@ -390,6 +521,21 @@ const ProjectFlockTable = () => {
</div>
</div>
<ConfirmationModal
ref={deleteModal.ref}
type='error'
text={`Apakah anda yakin ingin menghapus data Project Flock ini (${selectedProjectFlock?.flock?.name})?`}
secondaryButton={{
text: 'Tidak',
}}
primaryButton={{
text: 'Ya',
color: 'error',
isLoading: isDeleteLoading,
onClick: confirmationModalDeleteClickHandler,
}}
/>
<ConfirmationModal
ref={confirmModal.ref}
type='success'