@@ -7,6 +7,12 @@ function DropOffTracking() {
77 const [ selectedEvent , setSelectedEvent ] = useState ( 'All Events' ) ;
88 const [ selectedTime , setSelectedTime ] = useState ( 'All Time' ) ;
99
10+ const [ isModalOpen , setIsModalOpen ] = useState ( false ) ;
11+ const [ activeEvent , setActiveEvent ] = useState ( null ) ;
12+ const [ selectedUsers , setSelectedUsers ] = useState ( [ ] ) ;
13+
14+ const darkMode = useSelector ( state => state . theme . darkMode ) ;
15+
1016 const getDateRange = ( ) => {
1117 const today = new Date ( ) ;
1218 let startDate , endDate ;
@@ -44,7 +50,17 @@ function DropOffTracking() {
4450 return true ;
4551 } ) ;
4652
47- const darkMode = useSelector ( state => state . theme . darkMode ) ;
53+ const handleOpenList = event => {
54+ setActiveEvent ( event ) ;
55+ setSelectedUsers ( [ ] ) ;
56+ setIsModalOpen ( true ) ;
57+ } ;
58+
59+ const handleCloseModal = ( ) => {
60+ setIsModalOpen ( false ) ;
61+ setActiveEvent ( null ) ;
62+ setSelectedUsers ( [ ] ) ;
63+ } ;
4864
4965 return (
5066 < div
@@ -103,23 +119,126 @@ function DropOffTracking() {
103119 < thead >
104120 < tr >
105121 < th > Event name</ th >
106- < th > No-show rate</ th >
107- < th > Drop-off rate</ th >
108- < th > Attendees</ th >
122+
123+ < th >
124+ No-show rate
125+ < span
126+ className = { styles . infoIcon }
127+ title = "Percentage of registered participants who did not attend the event. Calculated per event based on total registrations."
128+ >
129+ ℹ️
130+ </ span >
131+ </ th >
132+
133+ < th >
134+ Drop-off rate
135+ < span
136+ className = { styles . infoIcon }
137+ title = "Percentage of participants who joined the event but left before it was completed. Calculated per event based on total registrations."
138+ >
139+ ℹ️
140+ </ span >
141+ </ th >
142+
143+ < th >
144+ Get list
145+ < span
146+ className = { styles . infoIcon }
147+ title = "View the list of no-show participants for this event and send follow-up emails."
148+ >
149+ ℹ️
150+ </ span >
151+ </ th >
109152 </ tr >
110153 </ thead >
154+
111155 < tbody >
112156 { filteredEvents . map ( event => (
113157 < tr key = { event . id } >
114158 < td > { event . eventName } </ td >
115159 < td className = { styles . trackingRateGreen } > { event . noShowRate } </ td >
116160 < td className = { styles . trackingRateRed } > { event . dropOffRate } </ td >
117- < td > { event . attendees } </ td >
161+ < td >
162+ < button
163+ type = "button"
164+ className = { styles . getListBtn }
165+ aria-label = "Get no-show list"
166+ onClick = { ( ) => handleOpenList ( event ) }
167+ >
168+ 👥
169+ </ button >
170+ </ td >
118171 </ tr >
119172 ) ) }
120173 </ tbody >
121174 </ table >
122175 </ div >
176+
177+ { isModalOpen && activeEvent && (
178+ < div className = { styles . modalOverlay } >
179+ < div className = { `${ styles . modalContent } ${ darkMode ? styles . modalContentDark : '' } ` } >
180+ < div className = { styles . modalHeader } >
181+ < h4 > No-show list</ h4 >
182+ < button type = "button" className = { styles . closeBtn } onClick = { handleCloseModal } >
183+ ✕
184+ </ button >
185+ </ div >
186+
187+ < div className = { styles . modalSubHeader } >
188+ { activeEvent . eventName } | { activeEvent . eventTime }
189+ </ div >
190+
191+ < div className = { styles . modalList } >
192+ < label className = { styles . selectAll } >
193+ < input
194+ type = "checkbox"
195+ checked = {
196+ selectedUsers . length > 0 &&
197+ selectedUsers . length === mockEvents . slice ( 0 , 8 ) . length
198+ }
199+ onChange = { e =>
200+ setSelectedUsers ( e . target . checked ? mockEvents . slice ( 0 , 8 ) . map ( u => u . id ) : [ ] )
201+ }
202+ />
203+ Select all
204+ </ label >
205+
206+ { mockEvents . slice ( 0 , 8 ) . map ( user => (
207+ < label key = { user . id } className = { styles . userRow } >
208+ < input
209+ type = "checkbox"
210+ checked = { selectedUsers . includes ( user . id ) }
211+ onChange = { ( ) =>
212+ setSelectedUsers ( prev =>
213+ prev . includes ( user . id )
214+ ? prev . filter ( id => id !== user . id )
215+ : [ ...prev , user . id ] ,
216+ )
217+ }
218+ />
219+ < span className = { styles . userAvatar } > 👤</ span >
220+ < span className = { styles . userName } > No-show person { user . id } </ span >
221+ < span className = { styles . userEmail } > user{ user . id } @example.com</ span >
222+ </ label >
223+ ) ) }
224+ </ div >
225+
226+ < div className = { styles . modalFooter } >
227+ < button
228+ type = "button"
229+ className = { styles . sendEmailBtn }
230+ disabled = { selectedUsers . length === 0 }
231+ onClick = { ( ) => {
232+ console . log ( 'Send email to:' , selectedUsers ) ;
233+ handleCloseModal ( ) ;
234+ } }
235+ >
236+ Send Email
237+ </ button >
238+ </ div >
239+ </ div >
240+ </ div >
241+ ) }
123242 </ div >
124243 ) ;
125244}
0 commit comments