@@ -2,12 +2,31 @@ import NERFormModal from '../../components/NERFormModal';
22import * as yup from 'yup' ;
33import { yupResolver } from '@hookform/resolvers/yup' ;
44import { Controller , useForm } from 'react-hook-form' ;
5- import { Box , FormControl , FormLabel , MenuItem , Select , SelectChangeEvent , TextField , Typography } from '@mui/material' ;
5+ import {
6+ Autocomplete ,
7+ Box ,
8+ FormControl ,
9+ FormLabel ,
10+ Grid ,
11+ MenuItem ,
12+ Select ,
13+ SelectChangeEvent ,
14+ TextField ,
15+ Typography
16+ } from '@mui/material' ;
617import { DatePicker } from '@mui/x-date-pickers' ;
718import { useToast } from '../../hooks/toasts.hooks' ;
819import { useState } from 'react' ;
9- import { meetingStartTimePipe } from '../../utils/pipes' ;
10- import { TeamType } from 'shared' ;
20+ import { meetingStartTimePipe , wbsNamePipe } from '../../utils/pipes' ;
21+ import { Project , TeamType , WbsNumber , WorkPackage , validateWBS , wbsPipe } from 'shared' ;
22+ import { useCreateDesignReviews } from '../../hooks/design-reviews.hooks' ;
23+ import { useAllUsers } from '../../hooks/users.hooks' ;
24+ import ErrorPage from '../ErrorPage' ;
25+ import LoadingIndicator from '../../components/LoadingIndicator' ;
26+ import { userToAutocompleteOption } from '../../utils/teams.utils' ;
27+ import { useQuery } from '../../hooks/utils.hooks' ;
28+ import NERAutocomplete from '../../components/NERAutocomplete' ;
29+ import { useAllProjects } from '../../hooks/projects.hooks' ;
1130
1231const schema = yup . object ( ) . shape ( {
1332 date : yup . date ( ) . required ( 'Date is required' ) ,
@@ -21,6 +40,9 @@ interface CreateDesignReviewFormInput {
2140 startTime : number ;
2241 endTime : number ;
2342 teamTypeId : string ;
43+ requiredMemberIds : number [ ] ;
44+ optionalMemberIds : number [ ] ;
45+ wbsNum : WbsNumber ;
2446}
2547
2648interface DesignReviewCreateModalProps {
@@ -31,15 +53,35 @@ interface DesignReviewCreateModalProps {
3153
3254export const DesignReviewCreateModal : React . FC < DesignReviewCreateModalProps > = ( { showModal, handleClose, teamTypes } ) => {
3355 const HOURS : number [ ] = [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 ] ;
56+ const query = useQuery ( ) ;
3457
3558 const toast = useToast ( ) ;
3659 const [ datePickerOpen , setDatePickerOpen ] = useState ( false ) ;
60+ const [ requiredMembers , setRequiredMembers ] = useState ( [ ] . map ( userToAutocompleteOption ) ) ;
61+ const [ optionalMembers , setOptionalMembers ] = useState ( [ ] . map ( userToAutocompleteOption ) ) ;
62+ const [ wbsNum , setWbsNum ] = useState ( query . get ( 'wbsNum' ) || '' ) ;
63+ const { isLoading : allUsersIsLoading , isError : allUsersIsError , error : allUsersError , data : users } = useAllUsers ( ) ;
64+ const { data : projects } = useAllProjects ( ) ;
3765
38- // create design review hook
66+ const { mutateAsync } = useCreateDesignReviews ( ) ;
3967
4068 const onSubmit = async ( data : CreateDesignReviewFormInput ) => {
69+ const day = data . date . getDay ( ) ;
70+ console . log ( 'Day: ' + day ) ;
71+ const times = [ ] ;
72+ for ( let i = day * 12 + data . startTime ; i <= day * 12 + data . endTime ; i ++ ) {
73+ times . push ( i ) ;
74+ }
75+ console . log ( 'times: ' + times ) ;
4176 try {
42- // await mutateAsync(data);
77+ await mutateAsync ( {
78+ dateScheduled : data . date ,
79+ teamTypeId : data . teamTypeId ,
80+ requiredMemberIds : requiredMembers . map ( ( member ) => parseInt ( member . id ) ) ,
81+ optionalMemberIds : optionalMembers . map ( ( member ) => parseInt ( member . id ) ) ,
82+ wbsNum : validateWBS ( wbsNum ) ,
83+ meetingTimes : times
84+ } ) ;
4385 } catch ( error : unknown ) {
4486 if ( error instanceof Error ) {
4587 toast . error ( error . message ) ;
@@ -63,6 +105,43 @@ export const DesignReviewCreateModal: React.FC<DesignReviewCreateModalProps> = (
63105 }
64106 } ) ;
65107
108+ if ( allUsersIsError ) return < ErrorPage message = { allUsersError ?. message } /> ;
109+ if ( allUsersIsLoading || ! users || ! projects ) return < LoadingIndicator /> ;
110+
111+ const memberOptions = users . map ( userToAutocompleteOption ) ;
112+
113+ const projectOptions : { label : string ; id : string } [ ] = [ ] ;
114+
115+ const wbsDropdownOptions : { label : string ; id : string } [ ] = [ ] ;
116+
117+ projects . forEach ( ( project : Project ) => {
118+ wbsDropdownOptions . push ( {
119+ label : `${ wbsNamePipe ( project ) } ` ,
120+ id : wbsPipe ( project . wbsNum )
121+ } ) ;
122+ projectOptions . push ( {
123+ label : `${ wbsNamePipe ( project ) } ` ,
124+ id : wbsPipe ( project . wbsNum )
125+ } ) ;
126+ project . workPackages . forEach ( ( workPackage : WorkPackage ) => {
127+ wbsDropdownOptions . push ( {
128+ label : `${ wbsNamePipe ( workPackage ) } ` ,
129+ id : wbsPipe ( workPackage . wbsNum )
130+ } ) ;
131+ } ) ;
132+ } ) ;
133+
134+ const wbsAutocompleteOnChange = (
135+ _event : React . SyntheticEvent < Element , Event > ,
136+ value : { label : string ; id : string } | null
137+ ) => {
138+ if ( value ) {
139+ setWbsNum ( value . id ) ;
140+ } else {
141+ setWbsNum ( '' ) ;
142+ }
143+ } ;
144+
66145 return (
67146 < NERFormModal
68147 open = { showModal }
@@ -224,6 +303,57 @@ export const DesignReviewCreateModal: React.FC<DesignReviewCreateModalProps> = (
224303 />
225304 </ FormControl >
226305 </ Box >
306+ < Box >
307+ < Typography sx = { { fontWeight : 'bold' } } display = "inline" >
308+ Required Members:
309+ </ Typography >
310+ < Grid container direction = { 'row' } >
311+ < Grid item xs = { 9 } md = { 10 } lg = { 11 } >
312+ < Autocomplete
313+ isOptionEqualToValue = { ( option , value ) => option . id === value . id }
314+ filterSelectedOptions
315+ multiple
316+ id = "tags-standard"
317+ options = { memberOptions }
318+ value = { requiredMembers }
319+ onChange = { ( _event , newValue ) => setRequiredMembers ( newValue ) }
320+ getOptionLabel = { ( option ) => option . label }
321+ renderInput = { ( params ) => < TextField { ...params } variant = "standard" placeholder = "Select A User" /> }
322+ />
323+ </ Grid >
324+ </ Grid >
325+ </ Box >
326+ < Box >
327+ < Typography sx = { { fontWeight : 'bold' } } display = "inline" >
328+ Optional Members:
329+ </ Typography >
330+ < Grid container direction = { 'row' } >
331+ < Grid item xs = { 9 } md = { 10 } lg = { 11 } >
332+ < Autocomplete
333+ isOptionEqualToValue = { ( option , value ) => option . id === value . id }
334+ filterSelectedOptions
335+ multiple
336+ id = "tags-standard"
337+ options = { memberOptions }
338+ value = { optionalMembers }
339+ onChange = { ( _event , newValue ) => setOptionalMembers ( newValue ) }
340+ getOptionLabel = { ( option ) => option . label }
341+ renderInput = { ( params ) => < TextField { ...params } variant = "standard" placeholder = "Select A User" /> }
342+ />
343+ </ Grid >
344+ </ Grid >
345+ </ Box >
346+ < Grid item xs = { 12 } >
347+ < FormLabel > WBS</ FormLabel >
348+ < NERAutocomplete
349+ id = "wbs-autocomplete"
350+ onChange = { wbsAutocompleteOnChange }
351+ options = { wbsDropdownOptions }
352+ size = "small"
353+ placeholder = "Select a project or work package"
354+ value = { wbsDropdownOptions . find ( ( element ) => element . id === wbsNum ) || null }
355+ />
356+ </ Grid >
227357 </ NERFormModal >
228358 ) ;
229359} ;
0 commit comments