11
2- import { Box , Button , Skeleton , Stack , TextField , Typography } from "@mui/material" ;
2+ import { Button , Fab , Skeleton , Stack , TextField , Tooltip , Typography } from "@mui/material" ;
33import { useState } from "react" ;
44import { DateTimePicker , LocalizationProvider } from "@mui/x-date-pickers" ;
55import { AdapterDateFns } from "@mui/x-date-pickers/AdapterDateFnsV3" ;
66import CustomAutoComplete from "@/app/components/input/CustomAutocomplete" ;
77import CustomNumberInput from "@/app/components/input/CustomNumberInput" ;
88import prismaRequest from "@/app/middleware/prisma/prismaRequest" ;
99import locale from "date-fns/locale/en-GB" ;
10+ import { CalendarToday , PunchClock } from "@mui/icons-material" ;
1011
1112export default function workLogInput (
1213 session ,
@@ -17,8 +18,11 @@ export default function workLogInput(
1718 const [ registeredFor , setRegisteredFor ] = useState ( null ) ;
1819 const [ selectedGroup , setSelectedGroup ] = useState ( null ) ;
1920 const [ selectedDateTime , setSelectedDateTime ] = useState ( new Date ( ) ) ;
21+ const [ endDateTime , setEndDateTime ] = useState ( new Date ( ) ) ;
2022 const [ hours , setHours ] = useState ( 0 ) ;
2123 const [ description , setDescription ] = useState ( "" ) ;
24+ const [ shouldInputHours , setShouldInputHours ] = useState ( false ) ;
25+ const [ endInputMethodTooltip , setEndInputMethodTooltip ] = useState ( "Change to 'End of work'" ) ;
2226
2327 const [ registeredForError , setRegisteredForError ] = useState ( false ) ;
2428 const [ selectedGroupError , setSelectedGroupError ] = useState ( false ) ;
@@ -89,6 +93,21 @@ export default function workLogInput(
8993 } , 5000 ) ;
9094 } ;
9195
96+ const switchEndInputMethod = ( ) => {
97+ if ( ! shouldInputHours ) {
98+ setShouldInputHours ( true ) ;
99+ document . querySelector ( ".endDateTime" ) . setAttribute ( "style" , "display: inline" ) ;
100+ document . querySelector ( ".hours" ) . setAttribute ( "style" , "display: none" ) ;
101+ setEndInputMethodTooltip ( "Change to 'Hours worked'" ) ;
102+
103+ } else {
104+ setShouldInputHours ( false ) ;
105+ document . querySelector ( ".endDateTime" ) . setAttribute ( "style" , "display: none" ) ;
106+ document . querySelector ( ".hours" ) . setAttribute ( "style" , "display: inline" ) ;
107+ setEndInputMethodTooltip ( "Change to 'End of work'" ) ;
108+ }
109+ } ;
110+
92111 return (
93112 < Stack direction = "column" spacing = { 1 } >
94113 < Stack direction = "column" spacing = { 2 } >
@@ -116,15 +135,54 @@ export default function workLogInput(
116135 ampm = { false }
117136 disableOpenPicker
118137 onChange = { ( e ) => setSelectedDateTime ( e ) }
119- />
138+ />
120139 </ LocalizationProvider >
121- < CustomNumberInput
122- label = "Hours worked"
123- value = { hours }
124- setValue = { setHours }
125- check = { ( data ) => data . match ( / [ ^ 0 - 9 . ] / ) || data . match ( / [ . ] { 2 , } / g) }
126- error = { hoursError }
127- />
140+ < Stack
141+ direction = "row"
142+ alignItems = { "stretch" }
143+ >
144+ < LocalizationProvider dateAdapter = { AdapterDateFns } adapterLocale = { locale } >
145+ < DateTimePicker
146+ className = "endDateTime"
147+ sx = { { display : "none" } }
148+ slotProps = { { textField : { fullWidth : true } } }
149+ label = "End of work"
150+ value = { endDateTime } // Replacing defaultValue to make it synced with the actual value
151+ ampm = { false }
152+ disableOpenPicker
153+ onChange = { ( e ) => {
154+ if ( e < selectedDateTime ) return ; // Prevent endDateTime from being before startDateTime
155+ setEndDateTime ( e ) ;
156+ setHours ( Math . round ( ( ( e - selectedDateTime ) / 3600000 ) * 10 ) / 10 ) // Update hours
157+ } }
158+ />
159+ </ LocalizationProvider >
160+ < CustomNumberInput
161+ className = "hours"
162+ label = "Hours worked"
163+ value = { hours }
164+ setValue = { ( value ) => { setHours ( value ) ; } }
165+ check = { ( data ) => data . match ( / [ ^ 0 - 9 . ] / ) || data . match ( / [ . ] { 2 , } / g) }
166+ error = { hoursError }
167+ />
168+ < Tooltip
169+ className = "endInputMethodTooltip"
170+ title = { endInputMethodTooltip }
171+ >
172+ < Fab
173+ className = "endInputMethodChangeButton"
174+ size = "small"
175+ color = "primary"
176+ style = { {
177+ marginLeft : "10px" ,
178+ padding : "10px" ,
179+ } }
180+ onClick = { ( ) => { switchEndInputMethod ( ) ; } }
181+ >
182+ { shouldInputHours ? < PunchClock /> : < CalendarToday /> }
183+ </ Fab >
184+ </ Tooltip >
185+ </ Stack >
128186 < TextField
129187 label = "Description"
130188 size = "small"
@@ -171,7 +229,7 @@ function validateWorkLogRequest(
171229 registeredForError : registeredFor == null ,
172230 selectedGroupError : selectedGroup == null ,
173231 selectedDateTimeError : false , // TODO: add semester validation
174- hoursError : hours <= 0 || hours > 24 ,
232+ hoursError : Number . isNaN ( hours ) || hours <= 0 || hours > 24 ,
175233 descriptionError : description . length == 0 ,
176234 } ;
177235
0 commit comments