feat(FE-170,174,175): add tooltip for grading button based on consumable eggs validation

This commit is contained in:
rstubryan
2025-11-18 10:48:41 +07:00
parent 9164b985b1
commit 6022ff2dae
@@ -15,6 +15,7 @@ import SelectInput, { OptionType } from '@/components/input/SelectInput';
import CheckboxInput from '@/components/input/CheckboxInput';
import ConfirmationModal from '@/components/modal/ConfirmationModal';
import { useModal } from '@/components/Modal';
import Tooltip from '@/components/Tooltip';
import {
ProjectFlockKandangApi,
@@ -950,6 +951,54 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
);
}, [formik.values.stocks, getStockUsageError, type]);
const hasConsumableEggs = useMemo(() => {
if (!isLayingCategory) return false;
const layingValues = formik.values as RecordingLayingFormValues;
if (!layingValues.eggs || layingValues.eggs.length === 0) return false;
return layingValues.eggs.some((egg) => {
if (!egg.product_warehouse_id || Number(egg.qty) <= 0) return false;
const product = eggProducts.find(
(opt) => opt.value === egg.product_warehouse_id
);
if (!product) return false;
const productName = product.label.toLowerCase();
return (
productName.includes('konsumsi') &&
productName.includes('baik') &&
Number(egg.qty) > 0
);
});
}, [isLayingCategory, formik.values, eggProducts]);
const hasConsumableEggsInRecording = useCallback((recording?: Recording) => {
if (!recording || !recording.eggs || recording.eggs.length === 0)
return false;
return recording.eggs.some((egg) => {
if (!egg.product_warehouse || !egg.product_warehouse.product)
return false;
if (Number(egg.qty) <= 0) return false;
const productName = egg.product_warehouse.product.name.toLowerCase();
return (
productName.includes('konsumsi') &&
productName.includes('baik') &&
Number(egg.qty) > 0
);
});
}, []);
const hasConsumableEggsInCurrentRecording = useMemo(() => {
return (
hasConsumableEggsInRecording(initialValues) ||
hasConsumableEggsInRecording(newRecordingData || undefined)
);
}, [initialValues, newRecordingData, hasConsumableEggsInRecording]);
const isRepeaterInputError = (
arrayName: 'body_weights' | 'stocks' | 'depletions' | 'eggs',
column: string,
@@ -2606,29 +2655,42 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
</div>
<div className='flex flex-row justify-end gap-2'>
{type === 'detail' && isLayingCategory && (
<Button
type='button'
color='primary'
onClick={() => {
const recordingId =
newRecordingData?.id || initialValues?.id;
if (recordingId) {
router.push(
`/production/recording/grading/add?recording_id=${recordingId}`
);
} else {
toast.error(
'Recording ID tidak ditemukan. Silakan refresh halaman.'
);
}
}}
<Tooltip
content={
hasConsumableEggsInCurrentRecording
? 'Lanjut ke proses grading untuk telur konsumsi baik'
: 'Hanya bisa melanjutkan ke grading jika ada Telur Konsumsi Baik'
}
position='top'
color={
hasConsumableEggsInCurrentRecording ? 'info' : 'warning'
}
>
<Icon icon='material-symbols:egg' width={24} height={24} />
{hasGradingData(initialValues) ||
hasGradingData(newRecordingData || undefined)
? 'Edit Grading'
: 'Lanjut ke Grading'}
</Button>
<Button
type='button'
color='primary'
disabled={!hasConsumableEggsInCurrentRecording}
onClick={() => {
const recordingId =
newRecordingData?.id || initialValues?.id;
if (recordingId) {
router.push(
`/production/recording/grading/add?recording_id=${recordingId}`
);
} else {
toast.error(
'Recording ID tidak ditemukan. Silakan refresh halaman.'
);
}
}}
>
<Icon icon='material-symbols:egg' width={24} height={24} />
{hasGradingData(initialValues) ||
hasGradingData(newRecordingData || undefined)
? 'Edit Grading'
: 'Lanjut ke Grading'}
</Button>
</Tooltip>
)}
{type === 'edit' && (
@@ -2683,66 +2745,77 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
Submit
</Button>
{isLayingCategory && (
<Button
type='button'
color='info'
className='px-4'
isLoading={formik.isSubmitting}
disabled={
hasExceededStock ||
!formik.isValid ||
formik.isSubmitting
<Tooltip
content={
hasConsumableEggs
? 'Lanjut ke proses grading untuk telur konsumsi baik'
: 'Hanya bisa melanjutkan ke grading jika ada Telur Konsumsi Baik'
}
onClick={async () => {
if (!formik.isValid) {
await formik.validateForm();
return;
}
setRecordingFormErrorMessage('');
formik.setSubmitting(true);
try {
if (isLayingCategory) {
const layingValues =
formik.values as RecordingLayingFormValues;
const layingPayload =
createLayingPayload(layingValues);
const recordingData =
await createRecordingHandlerWithRedirect(
layingPayload as CreateLayingRecordingPayload,
true
);
if (recordingData?.id) {
toast.success(
'Recording berhasil disimpan! Mengalihkan ke form Grading...'
);
setTimeout(() => {
router.push(
`/production/recording/grading/add?recording_id=${recordingData.id}`
);
}, 1000);
}
}
} catch (error) {
console.error('Error creating recording:', error);
toast.error(
'Gagal membuat recording. Silakan coba lagi.'
);
} finally {
formik.setSubmitting(false);
}
}}
position='top'
color={hasConsumableEggs ? 'info' : 'warning'}
>
<Icon
icon='material-symbols:egg'
width={24}
height={24}
/>
Next Step: Grading
</Button>
<Button
type='button'
color='info'
className='px-4'
isLoading={formik.isSubmitting}
disabled={
hasExceededStock ||
!formik.isValid ||
formik.isSubmitting ||
!hasConsumableEggs
}
onClick={async () => {
if (!formik.isValid) {
await formik.validateForm();
return;
}
setRecordingFormErrorMessage('');
formik.setSubmitting(true);
try {
if (isLayingCategory) {
const layingValues =
formik.values as RecordingLayingFormValues;
const layingPayload =
createLayingPayload(layingValues);
const recordingData =
await createRecordingHandlerWithRedirect(
layingPayload as CreateLayingRecordingPayload,
true
);
if (recordingData?.id) {
toast.success(
'Recording berhasil disimpan! Mengalihkan ke form Grading...'
);
setTimeout(() => {
router.push(
`/production/recording/grading/add?recording_id=${recordingData.id}`
);
}, 1000);
}
}
} catch (error) {
console.error('Error creating recording:', error);
toast.error(
'Gagal membuat recording. Silakan coba lagi.'
);
} finally {
formik.setSubmitting(false);
}
}}
>
<Icon
icon='material-symbols:egg'
width={24}
height={24}
/>
Next Step: Grading
</Button>
</Tooltip>
)}
</>
)}