@@ -10,6 +10,7 @@ import {
1010} from '~/actions/bmdashboard/equipmentActions' ;
1111import { getHeaderData } from '~/actions/authActions' ;
1212import { getUserProfile } from '~/actions/userProfile' ;
13+ import { toast } from 'react-toastify' ;
1314
1415import styles from './EDailyActivityLog.module.css' ;
1516
@@ -44,7 +45,7 @@ const buildRows = list =>
4445 . filter ( l => l . type === 'Check Out' )
4546 . reduce ( ( s , l ) => s + ( l . quantity || 1 ) , 0 ) ;
4647
47- const usingQty = Math . max ( checkInQty - checkOutQty , 0 ) ;
48+ const usingQty = Math . max ( checkOutQty - checkInQty , 0 ) ;
4849 const availableQty = Math . max ( total - usingQty , 0 ) ;
4950
5051 const allNumbers = buildToolNumbers ( e . itemType ?. name , total ) ;
@@ -139,9 +140,15 @@ function EDailyActivityLog(props) {
139140
140141 const [ rows , setRows ] = useState ( [ ] ) ;
141142 const [ isLoading , setIsLoading ] = useState ( false ) ;
142- const [ toastMessage , setToastMessage ] = useState ( null ) ;
143143 const [ showConfirm , setShowConfirm ] = useState ( false ) ;
144144
145+ // Deriving validation states
146+ const isMissingProject = ! selectedProject ;
147+ const isInvalidDate = ! date || isNaN ( Date . parse ( date ) ) ;
148+ const hasNoEquipments = isMissingProject || rows . length === 0 ;
149+ const noEquipmentSelected = rows . length === 0 || rows . every ( r => r . selectedNumbers . length === 0 ) ;
150+ const isSubmitDisabled = isMissingProject || isInvalidDate || noEquipmentSelected ;
151+
145152 useEffect ( ( ) => {
146153 dispatch ( fetchBMProjects ( ) ) ;
147154 } , [ dispatch ] ) ;
@@ -159,8 +166,8 @@ function EDailyActivityLog(props) {
159166 const onToolSelect = ( rowIdx , selected ) => {
160167 setRows ( prev => {
161168 const row = prev [ rowIdx ] ;
162- const valid = logType === 'check-in' ? row . availableNumbers : row . inUseNumbers ;
163- const limit = logType === 'check-in' ? row . availableQty : row . usingQty ;
169+ const valid = logType === 'check-in' ? row . inUseNumbers : row . availableNumbers ;
170+ const limit = logType === 'check-in' ? row . usingQty : row . availableQty ;
164171
165172 const clean = selected
166173 . map ( o => o . value )
@@ -175,8 +182,8 @@ function EDailyActivityLog(props) {
175182 setLogType ( newType ) ;
176183 setRows ( prev =>
177184 prev . map ( r => {
178- const valid = newType === 'check-in' ? r . availableNumbers : r . inUseNumbers ;
179- const limit = newType === 'check-in' ? r . availableQty : r . usingQty ;
185+ const valid = newType === 'check-in' ? r . inUseNumbers : r . availableNumbers ;
186+ const limit = newType === 'check-in' ? r . usingQty : r . availableQty ;
180187 return {
181188 ...r ,
182189 selectedNumbers : r . selectedNumbers . filter ( n => valid . includes ( n ) ) . slice ( 0 , limit ) ,
@@ -193,6 +200,7 @@ function EDailyActivityLog(props) {
193200 } ;
194201
195202 const handleSubmit = ( ) => {
203+ if ( isSubmitDisabled ) return ;
196204 setShowConfirm ( true ) ;
197205 } ;
198206 const confirmSubmit = ( ) => {
@@ -210,7 +218,14 @@ function EDailyActivityLog(props) {
210218
211219 dispatch ( updateMultipleEquipmentLogs ( selectedProject . value , payload ) ) ;
212220 setShowConfirm ( false ) ;
213- setToastMessage ( 'Entry recorded.' ) ;
221+ toast . success (
222+ logType === 'check-in'
223+ ? 'Equipment checked in successfully'
224+ : 'Equipment checked out successfully' ,
225+ ) ;
226+
227+ // Clear selections immediately so UI responds while backend async request finishes
228+ setRows ( prev => prev . map ( r => ( { ...r , selectedNumbers : [ ] } ) ) ) ;
214229 } ;
215230
216231 const projectSelectStyles = getSelectStyles ( darkMode , false ) ;
@@ -298,8 +313,13 @@ function EDailyActivityLog(props) {
298313 }
299314 >
300315 < span > Are you sure? This will update equipment availability.</ span >
301- < div className = "d-flex gap-2" >
302- < Button size = "sm" color = "secondary" onClick = { ( ) => setShowConfirm ( false ) } >
316+ < div className = "d-flex" >
317+ < Button
318+ size = "sm"
319+ color = "secondary"
320+ className = "mr-2"
321+ onClick = { ( ) => setShowConfirm ( false ) }
322+ >
303323 Cancel
304324 </ Button >
305325 < Button size = "sm" color = "danger" onClick = { confirmSubmit } >
@@ -336,6 +356,9 @@ function EDailyActivityLog(props) {
336356 : { }
337357 }
338358 />
359+ { isInvalidDate && (
360+ < small className = "text-danger mt-1 d-block" > Please select a valid date.</ small >
361+ ) }
339362 { darkMode && (
340363 < small className = "text-muted mt-1 d-block" >
341364 Note: Calendar appearance depends on your browser and OS.
@@ -360,6 +383,9 @@ function EDailyActivityLog(props) {
360383 isClearable
361384 styles = { projectSelectStyles }
362385 />
386+ { isMissingProject && (
387+ < small className = "text-danger mt-1 d-block" > Project selection is required.</ small >
388+ ) }
363389 </ div >
364390
365391 < div className = "col-md-4" >
@@ -374,19 +400,32 @@ function EDailyActivityLog(props) {
374400 < div className = "d-flex" role = "group" aria-labelledby = "log-type-label" >
375401 < Button
376402 color = { logType === 'check-in' ? 'primary' : 'secondary' }
377- onClick = { ( ) => flipLogType ( 'check-in' ) }
403+ onClick = { ( ) => ! hasNoEquipments && flipLogType ( 'check-in' ) }
378404 className = { styles . checkInBtn }
405+ disabled = { hasNoEquipments }
406+ style = { hasNoEquipments ? { opacity : 0.65 , cursor : 'not-allowed' } : { } }
379407 >
380408 Check In
381409 </ Button >
382410 < Button
383411 color = { logType === 'check-out' ? 'primary' : 'secondary' }
384- onClick = { ( ) => flipLogType ( 'check-out' ) }
412+ onClick = { ( ) => ! hasNoEquipments && flipLogType ( 'check-out' ) }
385413 className = { styles . checkOutBtn }
414+ disabled = { hasNoEquipments }
415+ style = { hasNoEquipments ? { opacity : 0.65 , cursor : 'not-allowed' } : { } }
386416 >
387417 Check Out
388418 </ Button >
389419 </ div >
420+ < small
421+ className = { `mt-2 d-block ${ styles . helperText } ${
422+ darkMode ? 'text-light' : 'text-muted'
423+ } `}
424+ >
425+ < strong > Check In:</ strong > Report equipment as returned and available.
426+ < br />
427+ < strong > Check Out:</ strong > Assign equipment for current use.
428+ </ small >
390429 </ div >
391430 </ div >
392431
@@ -445,8 +484,8 @@ function EDailyActivityLog(props) {
445484 { selectedProject &&
446485 rows . length > 0 &&
447486 rows . map ( ( r , idx ) => {
448- const validList = logType === 'check-in' ? r . availableNumbers : r . inUseNumbers ;
449- const limit = logType === 'check-in' ? r . availableQty : r . usingQty ;
487+ const validList = logType === 'check-in' ? r . inUseNumbers : r . availableNumbers ;
488+ const limit = logType === 'check-in' ? r . usingQty : r . availableQty ;
450489
451490 return (
452491 < tr
@@ -479,7 +518,12 @@ function EDailyActivityLog(props) {
479518 < Button color = "secondary" onClick = { handleCancel } >
480519 Cancel
481520 </ Button >
482- < Button color = "primary" onClick = { handleSubmit } >
521+ < Button
522+ color = "primary"
523+ onClick = { handleSubmit }
524+ disabled = { isSubmitDisabled }
525+ style = { isSubmitDisabled ? { cursor : 'not-allowed' , opacity : 0.65 } : { } }
526+ >
483527 Submit
484528 </ Button >
485529 </ div >
0 commit comments