mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 13:32:00 +00:00
428 lines
13 KiB
TypeScript
428 lines
13 KiB
TypeScript
'use client';
|
|
|
|
import { useState } from 'react';
|
|
import toast from 'react-hot-toast';
|
|
|
|
import { Icon } from '@iconify/react';
|
|
import Button from '@/components/Button';
|
|
import Dropdown from '@/components/dropdown/Dropdown';
|
|
import SelectInput, {
|
|
OptionType,
|
|
useSelect,
|
|
} from '@/components/input/SelectInput';
|
|
import Menu from '@/components/menu/Menu';
|
|
import MenuItem from '@/components/menu/MenuItem';
|
|
import Card from '@/components/Card';
|
|
import ProductionResultProjectFlockKandangTable from '@/components/pages/report/production-result/ProductionResultProjectFlockKandangTable';
|
|
|
|
import { BaseKandang } from '@/types/api/master-data/kandang';
|
|
import { AreaApi, LocationApi } from '@/services/api/master-data';
|
|
import {
|
|
ProjectFlockApi,
|
|
ProjectFlockKandangApi,
|
|
} from '@/services/api/production';
|
|
import { ProjectFlockKandang } from '@/types/api/production/project-flock-kandang';
|
|
import { isResponseError } from '@/lib/api-helper';
|
|
import Pagination from '@/components/Pagination';
|
|
import { ProductionResultReportApi } from '@/services/api/report/production-result';
|
|
|
|
const ProductionResultContent = () => {
|
|
const [projectFlockKandangs, setProjectFlockKandangs] = useState<
|
|
ProjectFlockKandang[] | null
|
|
>(null);
|
|
const [projectFlockKandangMetadata, setProjectFlockKandangMetadata] =
|
|
useState<
|
|
| {
|
|
page: number;
|
|
limit: number;
|
|
total_pages: number;
|
|
total_results: number;
|
|
}
|
|
| undefined
|
|
>(undefined);
|
|
|
|
const [page, setPage] = useState(1);
|
|
const [pageSize, setPageSize] = useState(10);
|
|
|
|
const [isLoadingSearch, setIsLoadingSearch] = useState(false);
|
|
|
|
const [isLoadingExportingToExcel, setIsLoadingExportingToExcel] =
|
|
useState(false);
|
|
|
|
const [selectedArea, setSelectedArea] = useState<OptionType | null>(null);
|
|
const [selectedLocation, setSelectedLocation] = useState<OptionType | null>(
|
|
null
|
|
);
|
|
const [selectedProjectFlock, setSelectedProjectFlock] =
|
|
useState<OptionType | null>(null);
|
|
const [selectedProjectFlockKandang, setSelectedProjectFlockKandang] =
|
|
useState<OptionType | null>(null);
|
|
|
|
const {
|
|
setInputValue: setAreaInputValue,
|
|
options: areaOptions,
|
|
isLoadingOptions: isLoadingAreaOptions,
|
|
loadMore: loadMoreAreas,
|
|
} = useSelect<BaseKandang>(AreaApi.basePath, 'id', 'name');
|
|
|
|
const areaChangeHandler = (val: OptionType | OptionType[] | null) => {
|
|
setSelectedArea(val as OptionType);
|
|
|
|
setSelectedLocation(null);
|
|
|
|
setSelectedProjectFlock(null);
|
|
|
|
setSelectedProjectFlockKandang(null);
|
|
};
|
|
|
|
const {
|
|
setInputValue: setLocationInputValue,
|
|
options: locationOptions,
|
|
isLoadingOptions: isLoadingLocationOptions,
|
|
loadMore: loadMoreLocations,
|
|
} = useSelect<BaseKandang>(LocationApi.basePath, 'id', 'name', 'search', {
|
|
area_id: selectedArea ? ((selectedArea as OptionType).value as string) : '',
|
|
});
|
|
|
|
const locationChangeHandler = (val: OptionType | OptionType[] | null) => {
|
|
setSelectedLocation(val as OptionType);
|
|
|
|
setSelectedProjectFlock(null);
|
|
|
|
setSelectedProjectFlockKandang(null);
|
|
};
|
|
|
|
const {
|
|
setInputValue: setProjectFlockInputValue,
|
|
options: projectFlockOptions,
|
|
isLoadingOptions: isLoadingProjectFlockOptions,
|
|
loadMore: loadMoreProjectFlocks,
|
|
} = useSelect<BaseKandang>(
|
|
ProjectFlockApi.basePath,
|
|
'id',
|
|
'flock_name',
|
|
'search',
|
|
{
|
|
area_id: selectedArea
|
|
? ((selectedArea as OptionType).value as string)
|
|
: '',
|
|
location_id: selectedLocation
|
|
? ((selectedLocation as OptionType).value as string)
|
|
: '',
|
|
category: 'LAYING',
|
|
}
|
|
);
|
|
|
|
const projectFlockChangeHandler = (val: OptionType | OptionType[] | null) => {
|
|
setSelectedProjectFlock(val as OptionType);
|
|
|
|
setSelectedProjectFlockKandang(null);
|
|
};
|
|
|
|
const {
|
|
setInputValue: setProjectFlockKandangInputValue,
|
|
options: projectFlockKandangOptions,
|
|
isLoadingOptions: isLoadingProjectFlockKandangOptions,
|
|
loadMore: loadMoreProjectFlockKandangs,
|
|
} = useSelect<BaseKandang>(
|
|
ProjectFlockKandangApi.basePath,
|
|
'id',
|
|
'kandang.name',
|
|
'search',
|
|
{
|
|
area_id: selectedArea
|
|
? ((selectedArea as OptionType).value as string)
|
|
: '',
|
|
location_id: selectedLocation
|
|
? ((selectedLocation as OptionType).value as string)
|
|
: '',
|
|
project_flock_id: selectedProjectFlock
|
|
? ((selectedProjectFlock as OptionType).value as string)
|
|
: '',
|
|
}
|
|
);
|
|
|
|
const projectFlockKandangChangeHandler = (
|
|
val: OptionType | OptionType[] | null
|
|
) => {
|
|
setSelectedProjectFlockKandang(val as OptionType);
|
|
};
|
|
|
|
const exportToExcelHandler = async () => {
|
|
setIsLoadingExportingToExcel(true);
|
|
|
|
await ProductionResultReportApi.exportProductionResultToExcel(
|
|
projectFlockKandangs
|
|
);
|
|
|
|
setIsLoadingExportingToExcel(false);
|
|
};
|
|
|
|
const searchHandler = async () => {
|
|
setProjectFlockKandangs(null);
|
|
setIsLoadingSearch(true);
|
|
|
|
try {
|
|
if (selectedProjectFlockKandang) {
|
|
const projectFlockKandangResponse =
|
|
await ProjectFlockKandangApi.getSingle(
|
|
selectedProjectFlockKandang?.value as number
|
|
);
|
|
|
|
if (
|
|
!projectFlockKandangResponse ||
|
|
isResponseError(projectFlockKandangResponse)
|
|
) {
|
|
throw new Error();
|
|
}
|
|
|
|
setProjectFlockKandangs([projectFlockKandangResponse.data]);
|
|
setProjectFlockKandangMetadata(projectFlockKandangResponse.meta);
|
|
setIsLoadingSearch(false);
|
|
return;
|
|
}
|
|
|
|
const projectFlockKandangsResponse = await ProjectFlockKandangApi.getAll({
|
|
area_id: selectedArea?.value,
|
|
project_flock_id: selectedProjectFlock?.value,
|
|
});
|
|
|
|
if (
|
|
!projectFlockKandangsResponse ||
|
|
isResponseError(projectFlockKandangsResponse)
|
|
) {
|
|
throw new Error();
|
|
}
|
|
|
|
setProjectFlockKandangs(projectFlockKandangsResponse.data);
|
|
setProjectFlockKandangMetadata(projectFlockKandangsResponse.meta);
|
|
setIsLoadingSearch(false);
|
|
} catch (error) {
|
|
toast.error('Gagal mencari data! Coba lagi.');
|
|
setProjectFlockKandangs(null);
|
|
setProjectFlockKandangMetadata(undefined);
|
|
setIsLoadingSearch(false);
|
|
}
|
|
};
|
|
|
|
const resetHandler = () => {
|
|
setProjectFlockKandangs(null);
|
|
setSelectedArea(null);
|
|
setSelectedLocation(null);
|
|
setSelectedProjectFlock(null);
|
|
setSelectedProjectFlockKandang(null);
|
|
// resetFilter();
|
|
};
|
|
|
|
return (
|
|
<div className='w-full p-4'>
|
|
<Card
|
|
variant='bordered'
|
|
className={{
|
|
wrapper: 'w-full',
|
|
}}
|
|
>
|
|
<div>
|
|
<h2 className='text-xl font-bold text-center'>
|
|
Laporan Hasil Produksi
|
|
</h2>
|
|
</div>
|
|
|
|
{/* Filters */}
|
|
<div className='flex flex-col gap-4 mb-6 mt-4'>
|
|
<div className='grid grid-cols-12 gap-4'>
|
|
<SelectInput
|
|
label='Area'
|
|
placeholder='Pilih Area'
|
|
options={areaOptions}
|
|
isLoading={isLoadingAreaOptions}
|
|
value={selectedArea}
|
|
onChange={areaChangeHandler}
|
|
onInputChange={setAreaInputValue}
|
|
onMenuScrollToBottom={loadMoreAreas}
|
|
isClearable
|
|
className={{
|
|
wrapper: 'col-span-12 sm:col-span-6 lg:col-span-4',
|
|
}}
|
|
/>
|
|
|
|
<SelectInput
|
|
label='Lokasi'
|
|
placeholder={
|
|
selectedArea ? 'Pilih Lokasi' : 'Pilih Area terlebih dahulu'
|
|
}
|
|
options={locationOptions}
|
|
isLoading={isLoadingLocationOptions}
|
|
value={selectedLocation}
|
|
onChange={locationChangeHandler}
|
|
onInputChange={setLocationInputValue}
|
|
onMenuScrollToBottom={loadMoreLocations}
|
|
isClearable
|
|
isDisabled={!selectedArea}
|
|
className={{
|
|
wrapper: 'col-span-12 sm:col-span-6 lg:col-span-4',
|
|
}}
|
|
/>
|
|
|
|
<SelectInput
|
|
label='Project Flock'
|
|
placeholder={
|
|
selectedArea && selectedLocation
|
|
? 'Pilih Project Flock'
|
|
: 'Pilih Area dan Lokasi terlebih dahulu'
|
|
}
|
|
options={projectFlockOptions}
|
|
isLoading={isLoadingProjectFlockOptions}
|
|
value={selectedProjectFlock}
|
|
onChange={projectFlockChangeHandler}
|
|
onInputChange={setProjectFlockInputValue}
|
|
onMenuScrollToBottom={loadMoreProjectFlocks}
|
|
isClearable
|
|
isDisabled={!selectedArea || !selectedLocation}
|
|
className={{
|
|
wrapper: 'col-span-12 sm:col-span-6 lg:col-span-4',
|
|
}}
|
|
/>
|
|
|
|
<SelectInput
|
|
label='Project Flock Kandang'
|
|
placeholder={
|
|
selectedProjectFlock
|
|
? 'Pilih Project Flock Kandang'
|
|
: 'Pilih Project Flock terlebih dahulu'
|
|
}
|
|
options={projectFlockKandangOptions}
|
|
isLoading={isLoadingProjectFlockKandangOptions}
|
|
value={selectedProjectFlockKandang}
|
|
onChange={projectFlockKandangChangeHandler}
|
|
onInputChange={setProjectFlockKandangInputValue}
|
|
onMenuScrollToBottom={loadMoreProjectFlockKandangs}
|
|
isClearable
|
|
isDisabled={!selectedProjectFlock}
|
|
className={{
|
|
wrapper: 'col-span-12 sm:col-span-6 lg:col-span-4',
|
|
}}
|
|
/>
|
|
</div>
|
|
|
|
<div className='grid grid-cols-12 gap-4'>
|
|
<div className='col-span-12 flex flex-wrap sm:justify-end items-end gap-2'>
|
|
<Button
|
|
onClick={searchHandler}
|
|
isLoading={isLoadingSearch}
|
|
disabled={
|
|
!selectedArea || !selectedLocation || !selectedProjectFlock
|
|
}
|
|
className='flex-1 sm:flex-none'
|
|
>
|
|
<Icon icon='heroicons-outline:search' width={20} height={20} />
|
|
Cari
|
|
</Button>
|
|
<Button
|
|
color='warning'
|
|
onClick={resetHandler}
|
|
className='flex-1 sm:flex-none'
|
|
>
|
|
<Icon icon='heroicons-outline:refresh' width={20} height={20} />
|
|
Reset
|
|
</Button>
|
|
|
|
<Dropdown
|
|
align='end'
|
|
direction='bottom'
|
|
trigger={
|
|
<Button
|
|
disabled={
|
|
!selectedArea ||
|
|
!selectedLocation ||
|
|
!selectedProjectFlock
|
|
}
|
|
>
|
|
Export{' '}
|
|
<Icon
|
|
icon='heroicons-outline:download'
|
|
width={20}
|
|
height={20}
|
|
/>
|
|
</Button>
|
|
}
|
|
>
|
|
<Menu>
|
|
<MenuItem
|
|
title='Export to Excel'
|
|
icon='icon-park-outline:excel'
|
|
isLoading={isLoadingExportingToExcel}
|
|
onClick={exportToExcelHandler}
|
|
className='text-nowrap'
|
|
/>
|
|
</Menu>
|
|
</Dropdown>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</Card>
|
|
|
|
<div className='mt-4'>
|
|
{isLoadingSearch && (
|
|
<span className='loading loading-dots loading-xl block mx-auto text-gray-400' />
|
|
)}
|
|
|
|
{!isLoadingSearch && !projectFlockKandangs && (
|
|
<p className='text-center text-gray-500'>
|
|
Silakan pilih filter dan klik tombol Cari untuk menampilkan data.
|
|
</p>
|
|
)}
|
|
|
|
{!isLoadingSearch && projectFlockKandangs?.length === 0 && (
|
|
<p className='text-center text-gray-500'>
|
|
Tidak ada data kandang project flock yang dapat ditampilkan.
|
|
</p>
|
|
)}
|
|
|
|
{!isLoadingSearch && projectFlockKandangs && (
|
|
<Card
|
|
variant='bordered'
|
|
className={{
|
|
wrapper: 'w-full',
|
|
}}
|
|
>
|
|
{projectFlockKandangs.map((projectFlockKandang) => (
|
|
<ProductionResultProjectFlockKandangTable
|
|
key={projectFlockKandang.id}
|
|
projectFlockKandangId={projectFlockKandang.id}
|
|
kandangName={projectFlockKandang.kandang.name}
|
|
/>
|
|
))}
|
|
|
|
<div className='max-w-sm ml-auto mt-5'>
|
|
<Pagination
|
|
totalItems={projectFlockKandangMetadata?.total_results || 0}
|
|
itemsPerPage={projectFlockKandangMetadata?.limit || 0}
|
|
currentPage={projectFlockKandangMetadata?.page || 0}
|
|
onPrevPage={() =>
|
|
setPage((currPage) =>
|
|
currPage > 1 ? currPage - 1 : currPage
|
|
)
|
|
}
|
|
onNextPage={() =>
|
|
setPage((currPage) =>
|
|
projectFlockKandangMetadata?.total_pages &&
|
|
currPage < projectFlockKandangMetadata.total_pages
|
|
? currPage + 1
|
|
: currPage
|
|
)
|
|
}
|
|
onPageChange={(pageNumber) => setPage(pageNumber)}
|
|
rowOptions={[10, 20, 50, 100]}
|
|
onRowChange={setPageSize}
|
|
/>
|
|
</div>
|
|
</Card>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default ProductionResultContent;
|