feat(FE): Add stock availability badge to product dropdown

This commit is contained in:
rstubryan
2026-02-26 15:56:31 +07:00
parent b4d0ed1537
commit 47ee911852
@@ -28,6 +28,8 @@ import SelectInput, {
OptionType,
useSelect,
} from '@/components/input/SelectInput';
import { components as ReactSelectComponents, OptionProps } from 'react-select';
import StatusBadge from '@/components/helper/StatusBadge';
import TextArea from '@/components/input/TextArea';
import { useFormikErrorList } from '@/services/hooks/useFormikErrorList';
import AlertErrorList from '@/components/helper/form/FormErrors';
@@ -203,10 +205,36 @@ const InventoryAdjustmentForm = ({
? productWarehouses.data.map((pw) => ({
value: pw.product.id,
label: pw.product.name,
quantity: pw.quantity,
}))
: [];
}, [productWarehouses]);
const ProductOption = useMemo(() => {
const OptionComponent = (
props: OptionProps<OptionType & { quantity?: number }, boolean>
) => {
const { data, children } = props;
const quantity = data.quantity ?? 0;
const isAvailable = quantity > 0;
return (
<ReactSelectComponents.Option {...props}>
<div className='flex items-center justify-between gap-2'>
<span className='flex-1'>{children}</span>
<StatusBadge
color={isAvailable ? 'success' : 'error'}
text={isAvailable ? 'Tersedia' : 'Kosong'}
className={{ badge: 'whitespace-nowrap w-fit' }}
/>
</div>
</ReactSelectComponents.Option>
);
};
OptionComponent.displayName = 'ProductOption';
return OptionComponent;
}, []);
const kandangOptions = useMemo(() => {
let options: OptionType[] = [];
@@ -646,6 +674,7 @@ const InventoryAdjustmentForm = ({
onChange={productChangeHandler}
onInputChange={setProductInputValue}
options={productOptions}
optionComponent={ProductOption}
onMenuScrollToBottom={loadMoreProducts}
isLoading={isLoadingProductOptions}
isError={
@@ -658,6 +687,14 @@ const InventoryAdjustmentForm = ({
? 'Pilih Produk'
: 'Pilih Kandang terlebih dahulu'
}
inputPrefix={
selectedProduct
? 'Stock: ' +
(productOptions.find(
(opt) => opt.value === selectedProduct?.value
)?.quantity ?? 0)
: undefined
}
isClearable
isSearchable
/>