@@ -13,6 +13,12 @@ import { ADD_EVENT, GET_EVENTS } from '../Mutations/event';
1313import moment from 'moment' ;
1414/* istanbul ignore next */
1515
16+ type Trainee = {
17+ id : number ;
18+ name : string ;
19+ role : 'admin' | 'manager' | 'trainee' ;
20+ } ;
21+
1622const Calendar = ( ) => {
1723 useDocumentTitle ( 'Calendar' ) ;
1824 const [ addEventModel , setAddEventModel ] = useState ( false ) ;
@@ -27,6 +33,21 @@ const Calendar = () => {
2733 const [ data , setData ] = useState < EventInput [ ] > ( [ ] ) ;
2834 const [ getEvents ] = useLazyQuery ( GET_EVENTS ) ;
2935 const [ createEvent ] = useMutation ( ADD_EVENT ) ;
36+ const [ showTraineeDropdown , setShowTraineeDropdown ] = useState ( false ) ;
37+ const [ trainees , setTrainees ] = useState < Trainee [ ] > ( [
38+ { id : 1 , name : 'John Doe' , role : 'admin' } ,
39+ { id : 2 , name : 'Jane Smith' , role : 'manager' } ,
40+ { id : 3 , name : 'Bob Johnson' , role : 'trainee' } ,
41+ { id : 4 , name : 'Alice Brown' , role : 'trainee' } ,
42+ { id : 5 , name : 'Charlie Green' , role : 'manager' } ,
43+ { id : 6 , name : 'Diana White' , role : 'trainee' } ,
44+ { id : 7 , name : 'Ethan Black' , role : 'admin' } ,
45+ { id : 8 , name : 'Fiona Blue' , role : 'manager' } ,
46+ { id : 9 , name : 'George Gray' , role : 'trainee' } ,
47+ { id : 10 , name : 'Hannah Purple' , role : 'trainee' } ,
48+ ] ) ;
49+ const [ selectedTrainees , setSelectedTrainees ] = useState < number [ ] > ( [ ] ) ;
50+
3051 useEffect ( ( ) => {
3152 const fetchData = async ( ) => {
3253 /* istanbul ignore next */
@@ -52,26 +73,24 @@ const Calendar = () => {
5273 } ;
5374 fetchData ( ) ;
5475 } , [ ] ) ;
76+
5577 const { t } = useTranslation ( ) ;
56- const renderEvent =
57- /* istanbul ignore next */
5878
59- ( e : EventContentArg ) => (
60- /* istanbul ignore next */
61- < div
62- data-html = { true }
63- data-tip = { `<div>${ e . event . title } <br> ${ e . event . extendedProps . hostName } <br> ${ e . event . extendedProps . timeToStart } - ${ e . event . extendedProps . timeToFinish } </div> ` }
64- className = "bg-primary text-white max-w-full min-w-full overflow-auto text-xs md:text-sm"
65- >
66- < p className = "px-3 py-1 " > { e . event . title } </ p >
67- < p className = "px-3 py-1 " > { e . event . extendedProps . hostName } </ p >
68- < p className = "px-3 py-1 " >
69- { e . event . extendedProps . timeToStart } -{ ' ' }
70- { e . event . extendedProps . timeToFinish }
71- </ p >
72- < ReactTooltip data-html = { true } />
73- </ div >
74- ) ;
79+ const renderEvent = ( e : EventContentArg ) => (
80+ < div
81+ data-html = { true }
82+ data-tip = { `<div>${ e . event . title } <br> ${ e . event . extendedProps . hostName } <br> ${ e . event . extendedProps . timeToStart } - ${ e . event . extendedProps . timeToFinish } </div> ` }
83+ className = "bg-primary text-white max-w-full min-w-full overflow-auto text-xs md:text-sm"
84+ >
85+ < p className = "px-3 py-1 " > { e . event . title } </ p >
86+ < p className = "px-3 py-1 " > { e . event . extendedProps . hostName } </ p >
87+ < p className = "px-3 py-1 " >
88+ { e . event . extendedProps . timeToStart } -{ ' ' }
89+ { e . event . extendedProps . timeToFinish }
90+ </ p >
91+ < ReactTooltip data-html = { true } />
92+ </ div >
93+ ) ;
7594
7695 const removeModel = ( e : any ) => {
7796 e . preventDefault ( ) ;
@@ -83,7 +102,6 @@ const Calendar = () => {
83102 const newState = ! addEventModel ;
84103 setAddEventModel ( newState ) ;
85104 } ;
86- /* istanbul ignore next */
87105
88106 const handleAddEvent = ( e : any ) => {
89107 e . preventDefault ( ) ;
@@ -104,12 +122,33 @@ const Calendar = () => {
104122 } , 1000 ) ;
105123 } ;
106124
125+ const handleAddGuest = ( traineeId : number ) => {
126+ setSelectedTrainees ( ( prev ) =>
127+ prev . includes ( traineeId )
128+ ? prev . filter ( ( id ) => id !== traineeId )
129+ : [ ...prev , traineeId ] ,
130+ ) ;
131+ } ;
132+
133+ const getRoleClass = ( role : Trainee [ 'role' ] ) => {
134+ switch ( role ) {
135+ case 'admin' :
136+ return 'bg-red-500' ;
137+ case 'manager' :
138+ return 'bg-yellow-500' ;
139+ case 'trainee' :
140+ return 'bg-green-500' ;
141+ default :
142+ return 'bg-gray-500' ;
143+ }
144+ } ;
145+
107146 return (
108147 < >
109- { /* =========================== Start:: RegisterTraineeModel =========================== */ }
110148 < div
111- className = { `font-serif h-screen w-screen bg-black bg-opacity-30 backdrop-blur-sm fixed top-0 left-0 z-20 flex items-center justify-center px-4 ${ addEventModel === true ? 'block' : 'hidden'
112- } `}
149+ className = { `font-serif h-screen w-screen bg-black bg-opacity-30 backdrop-blur-sm fixed top-0 left-0 z-20 flex items-center justify-center px-4 ${
150+ addEventModel === true ? 'block' : 'hidden'
151+ } `}
113152 >
114153 < div className = "bg-indigo-100 dark:bg-dark-bg w-full sm:w-3/4 md:w-1/2 xl:w-4/12 rounded-lg p-4 pb-8" >
115154 < div className = "card-title w-full flex flex-wrap justify-center items-center " >
@@ -119,14 +158,10 @@ const Calendar = () => {
119158 < hr className = " bg-primary border-gray-300 my-3 w-full" />
120159 </ div >
121160 < div className = "card-body" >
122- { /* istanbul ignore next */ }
123161 < form
124162 data-testid = "handleAddEvent"
125- className = " py-3 px-8"
126- onSubmit /* istanbul ignore next */ = { ( e ) =>
127- /* istanbul ignore next */
128- handleAddEvent ( e )
129- }
163+ className = " py-3 px-8 overflow-y-auto h-full "
164+ onSubmit = { ( e ) => handleAddEvent ( e ) }
130165 >
131166 < div className = "input my-3 h-9 " >
132167 < div className = "grouped-input flex items-center h-full w-full rounded-md" >
@@ -137,7 +172,6 @@ const Calendar = () => {
137172 className = " dark:bg-dark-tertiary border dark:text-white border-primary rounded outline-none px-5 font-sans text-xs py-2 w-full"
138173 placeholder = { t ( 'Event title' ) }
139174 value = { newEvent . title }
140- // eslint-disable-next-line prettier/prettier
141175 onChange = { ( e ) =>
142176 setNewEvent ( { ...newEvent , title : e . target . value } )
143177 }
@@ -153,11 +187,11 @@ const Calendar = () => {
153187 className = " dark:bg-dark-tertiary dark:text-white border border-primary rounded outline-none px-5 font-sans text-xs py-2 w-full"
154188 placeholder = { t ( 'Host name' ) }
155189 value = { newEvent . hostName }
156- onChange /* istanbul ignore next */ = { ( e ) =>
157- /* istanbul ignore next */ setNewEvent ( {
158- ...newEvent ,
159- hostName : e . target . value ,
160- } )
190+ onChange = { ( e ) =>
191+ setNewEvent ( {
192+ ...newEvent ,
193+ hostName : e . target . value ,
194+ } )
161195 }
162196 />
163197 </ div >
@@ -170,11 +204,11 @@ const Calendar = () => {
170204 placeholderText = { t ( 'Start Date' ) }
171205 style = { { marginRight : '10px' } }
172206 selected = { newEvent . start }
173- onChange /* istanbul ignore next */ = { ( start : any ) =>
174- /* istanbul ignore next */ setNewEvent ( {
175- ...newEvent ,
176- start,
177- } )
207+ onChange = { ( start : any ) =>
208+ setNewEvent ( {
209+ ...newEvent ,
210+ start,
211+ } )
178212 }
179213 />
180214 </ div >
@@ -187,43 +221,104 @@ const Calendar = () => {
187221 placeholderText = { t ( 'End Date' ) }
188222 style = { { marginRight : '10px' } }
189223 selected = { newEvent . end }
190- onChange = /* istanbul ignore next */ { ( end : any ) =>
191- /* istanbul ignore next */
192- setNewEvent ( { ...newEvent , end } )
193- }
224+ onChange = { ( end : any ) => setNewEvent ( { ...newEvent , end } ) }
194225 />
195226 </ div >
196227 </ div >
197228
198- < div className = "input my-3 h-9 " >
199- < div className = "grouped-input flex items-center h-full w-full rounded-md" >
200- < input
201- type = "time"
202- name = "hostName"
203- className = "dark:bg-dark-tertiary dark:text-white border border-primary rounded outline-none px-5 font-sans text-xs py-2 w-full"
204- placeholder = { t ( 'Start time' ) }
205- value = { newEvent . timeToStart }
206- onChange /* istanbul ignore next */ = { ( e ) =>
207- /* istanbul ignore next */
208- setNewEvent ( { ...newEvent , timeToStart : e . target . value } )
209- }
210- />
229+ < div className = "input my-3" >
230+ < div className = "flex space-x-2" >
231+ < div className = "w-1/2" >
232+ < input
233+ type = "time"
234+ name = "startTime"
235+ className = "dark:bg-dark-tertiary dark:text-white border border-primary rounded outline-none px-3 font-sans text-xs py-2 w-full"
236+ placeholder = { t ( 'Start time' ) }
237+ value = { newEvent . timeToStart }
238+ onChange = { ( e ) =>
239+ setNewEvent ( {
240+ ...newEvent ,
241+ timeToStart : e . target . value ,
242+ } )
243+ }
244+ />
245+ </ div >
246+ < div className = "w-1/2" >
247+ < input
248+ type = "time"
249+ name = "endTime"
250+ className = "dark:bg-dark-tertiary dark:text-white border border-primary rounded outline-none px-3 font-sans text-xs py-2 w-full"
251+ placeholder = { t ( 'End time' ) }
252+ value = { newEvent . timeToFinish }
253+ onChange = { ( e ) =>
254+ setNewEvent ( {
255+ ...newEvent ,
256+ timeToFinish : e . target . value ,
257+ } )
258+ }
259+ />
260+ </ div >
211261 </ div >
212262 </ div >
213263
214- < div className = "input my-3 h-9 " >
215- < div className = "grouped-input flex items-center h-full w-full rounded-md" >
216- < input
217- type = "time"
218- name = "hostName"
219- className = "dark:bg-dark-tertiary dark:text-white border border-primary rounded outline-none px-5 font-sans text-xs py-2 w-full"
220- placeholder = { t ( 'End time' ) }
221- value = { newEvent . timeToFinish }
222- onChange = /* istanbul ignore next */ { ( e ) =>
223- /* istanbul ignore next */
224- setNewEvent ( { ...newEvent , timeToFinish : e . target . value } )
225- }
226- />
264+ < div className = "input my-3" >
265+ < div className = "flex items-center justify-between" >
266+ < span className = "text-sm mb-2" > { t ( 'Add guests' ) } </ span >
267+ < button
268+ type = "button"
269+ className = "bg-primary text-white rounded-full w-6 h-6 flex items-center justify-center mb-2"
270+ onClick = { ( ) => setShowTraineeDropdown ( ! showTraineeDropdown ) }
271+ >
272+ { showTraineeDropdown ? '-' : '+' }
273+ </ button >
274+ </ div >
275+ { showTraineeDropdown && (
276+ < div className = "dark:bg-dark-tertiary dark:text-white mt-2 p-2 border border-primary rounded-md h-40 overflow-y-auto" >
277+ { trainees . map ( ( trainee ) => (
278+ < div key = { trainee . id } className = "flex items-center mb-2" >
279+ < input
280+ type = "checkbox"
281+ id = { `trainee-${ trainee . id } ` }
282+ checked = { selectedTrainees . includes ( trainee . id ) }
283+ onChange = { ( ) => handleAddGuest ( trainee . id ) }
284+ className = "mr-2"
285+ />
286+ < label
287+ htmlFor = { `trainee-${ trainee . id } ` }
288+ className = "flex items-center"
289+ >
290+ < span
291+ className = { `w-2 h-2 rounded-full ${ getRoleClass (
292+ trainee . role ,
293+ ) } mr-2`}
294+ > </ span >
295+ { trainee . name } ({ trainee . role } )
296+ </ label >
297+ </ div >
298+ ) ) }
299+ </ div >
300+ ) }
301+ < div className = "dark:bg-dark-tertiary dark:text-white mt-2 p-2 border border-primary rounded-md min-h-[40px] " >
302+ { selectedTrainees . map ( ( id ) => {
303+ const trainee = trainees . find ( ( t ) => t . id === id ) ;
304+ if ( ! trainee ) return null ;
305+ return (
306+ < span
307+ key = { id }
308+ className = { `inline-block ${ getRoleClass (
309+ trainee . role ,
310+ ) } text-white rounded-full px-2 py-1 text-xs mr-2 mb-2 relative`}
311+ >
312+ { trainee . name } ({ trainee . role } )
313+ < button
314+ onClick = { ( ) => handleAddGuest ( id ) }
315+ className = "absolute -top-1 -right-1 bg-red-500 text-white rounded-full w-4 h-4 flex items-center justify-center text-xs hover:bg-red-600 text-center font-extrabold"
316+ >
317+ ×
318+ </ button >
319+ </ span >
320+ ) ;
321+ } ) }
227322 </ div >
228323 </ div >
229324
@@ -243,7 +338,6 @@ const Calendar = () => {
243338 </ div >
244339 </ div >
245340 </ div >
246- { /* =========================== End:: RegisterTraineeModel =============================== */ }
247341
248342 < div className = "px-4 pb-20 w-full dark:bg-dark-frame-bg dark:text-white h-full overflow-y-scroll font-serif" >
249343 < div className = "w-full flex justify-center text-xl md:text-4xl dark:text-primary mb-10" >
0 commit comments