feat(FE-170,175): add toast notification for grading exceeding available eggs and enhance UI for grading information

This commit is contained in:
rstubryan
2025-11-06 14:53:21 +07:00
parent 501222a4ee
commit de9ec716f5
@@ -307,6 +307,21 @@ const GradingForm = ({ type = 'add', initialValues }: GradingFormProps) => {
setFormSteps(steps); setFormSteps(steps);
}, []); }, []);
// Show toast when grading exceeds available eggs
useEffect(() => {
if (isGradingExceedsAvailable && currentGradingTotal > 0) {
toast.error(
`Total grading (${currentGradingTotal}) melebihi telur yang tersedia (${totalKonsumsiBaikEggs})!`,
{
id: 'grading-exceeds',
duration: 3000,
}
);
} else {
toast.dismiss('grading-exceeds');
}
}, [isGradingExceedsAvailable, currentGradingTotal, totalKonsumsiBaikEggs]);
useEffect(() => { useEffect(() => {
if (formik.values.eggs_grading && formik.values.eggs_grading.length === 0) { if (formik.values.eggs_grading && formik.values.eggs_grading.length === 0) {
let recordingEggId: number | undefined = initialValues?.id; let recordingEggId: number | undefined = initialValues?.id;
@@ -404,54 +419,115 @@ const GradingForm = ({ type = 'add', initialValues }: GradingFormProps) => {
<Card <Card
title='Informasi Grading' title='Informasi Grading'
className={{ className={{
wrapper: 'w-full mb-4 shadow', wrapper: 'w-full mb-6 shadow-sm',
body: 'flex flex-col gap-6', body: 'p-6',
}} }}
> >
<div <div
className={ className={
type === 'detail' type === 'detail'
? 'flex flex-col gap-6' ? 'space-y-6'
: 'grid grid-cols-2 gap-4' : 'grid grid-cols-1 md:grid-cols-2 gap-6'
} }
> >
{type === 'detail' && initialValues ? ( {/* Recording Egg ID */}
<> <div className='bg-gray-50 rounded-lg p-4 border border-gray-200'>
<span>Recording Egg ID</span>#{initialValues.id} <div className='flex items-center justify-between'>
</> <div>
) : ( <p className='text-sm font-medium text-gray-600 mb-1'>Recording ID</p>
<> <p className='text-xl font-bold text-gray-900'>
<span>Recording Egg ID</span># #{type === 'detail' && initialValues ?
{formik.values.eggs_grading?.[0]?.recording_egg_id || '-'} initialValues.id :
</> (formik.values.eggs_grading?.[0]?.recording_egg_id || '-')
)} }
</p>
</div>
<div className='bg-blue-100 rounded-full p-2'>
<Icon
icon='material-symbols:info'
width={20}
height={20}
className='text-blue-600'
/>
</div>
</div>
</div>
{/* Total Telur Konsumsi Baik Info */} {/* Total Telur Konsumsi Baik Info */}
<div className={`rounded-lg p-4 border-2 ${
isGradingExceedsAvailable
? 'bg-red-50 border-red-200'
: 'bg-green-50 border-green-200'
}`}>
<div className='flex items-center justify-between mb-3'>
<div> <div>
<span className='text-sm text-gray-600'> <p className='text-sm font-medium text-gray-600 mb-1'>
Total Telur Konsumsi Baik Total Telur Konsumsi Baik
</span> </p>
<div className='flex items-center gap-2'> <div className='flex items-baseline gap-2'>
<p className='font-semibold text-lg'> <p className='text-2xl font-bold text-gray-900'>
{totalKonsumsiBaikEggs} {totalKonsumsiBaikEggs}
</p> </p>
<span className='text-sm text-gray-500'>telur</span> <span className='text-sm text-gray-500 font-medium'>
telur
</span>
</div> </div>
<div className='flex items-center gap-2 mt-1'> </div>
<span className='text-sm'>Total yang digrading:</span> <div className={`rounded-full p-2 ${
<span isGradingExceedsAvailable
className={`font-semibold ${isGradingExceedsAvailable ? 'text-error' : 'text-success'}`} ? 'bg-red-100'
> : 'bg-green-100'
}`}>
<Icon
icon={isGradingExceedsAvailable ?
'material-symbols:error' :
'material-symbols:check-circle'
}
width={20}
height={20}
className={isGradingExceedsAvailable ?
'text-red-600' :
'text-green-600'
}
/>
</div>
</div>
{/* Progress Bar */}
<div className='space-y-2'>
<div className='flex items-center justify-between text-sm'>
<span className='text-gray-600'>Total yang digrading:</span>
<span className={`font-semibold ${
isGradingExceedsAvailable ? 'text-red-600' : 'text-green-600'
}`}>
{currentGradingTotal} / {totalKonsumsiBaikEggs} {currentGradingTotal} / {totalKonsumsiBaikEggs}
</span> </span>
</div> </div>
<div className='w-full bg-gray-200 rounded-full h-2 overflow-hidden'>
<div
className={`h-full transition-all duration-300 ${
isGradingExceedsAvailable
? 'bg-red-500'
: 'bg-green-500'
}`}
style={{
width: `${Math.min((currentGradingTotal / totalKonsumsiBaikEggs) * 100, 100)}%`
}}
/>
</div>
{isGradingExceedsAvailable && ( {isGradingExceedsAvailable && (
<div className='text-error text-sm mt-1'> <div className='flex items-center gap-1 text-xs text-red-600 mt-1'>
Total grading melebihi available telur! <Icon
icon='material-symbols:warning'
width={12}
height={12}
/>
<span>Melebihi batas tersedia</span>
</div> </div>
)} )}
</div> </div>
</div> </div>
</div>
</Card> </Card>
{/* Grading Table */} {/* Grading Table */}
@@ -596,7 +672,7 @@ const GradingForm = ({ type = 'add', initialValues }: GradingFormProps) => {
isRepeaterInputError('eggs_grading', 'qty', idx) isRepeaterInputError('eggs_grading', 'qty', idx)
.errorMessage || .errorMessage ||
(isGradingExceedsAvailable (isGradingExceedsAvailable
? `Total grading melebihi available telur (${totalKonsumsiBaikEggs})` ? `Total grading melebihi telur yang tersedia (${totalKonsumsiBaikEggs})`
: undefined) : undefined)
} }
readOnly={type === 'detail'} readOnly={type === 'detail'}
@@ -723,12 +799,6 @@ const GradingForm = ({ type = 'add', initialValues }: GradingFormProps) => {
> >
Submit Submit
</Button> </Button>
{isGradingExceedsAvailable && (
<div className='text-error text-sm mt-2 text-right'>
Total grading ({currentGradingTotal}) melebihi available
telur ({totalKonsumsiBaikEggs})
</div>
)}
</div> </div>
)} )}
</div> </div>