@@ -29,11 +29,12 @@ export default function Home() {
2929 const [ error , setError ] = useState < string | null > ( null ) ;
3030 const [ lastUpdated , setLastUpdated ] = useState < Date | null > ( null ) ;
3131 const [ statusFilter , setStatusFilter ] = useState < 'all' | 'onboarded' | 'not_onboarded' > ( 'all' ) ;
32+ const [ roleFilter , setRoleFilter ] = useState < 'participants' | 'facilitators' > ( 'participants' ) ;
3233
3334 const fetchData = async ( ) => {
3435 try {
3536 setError ( null ) ;
36- const response = await fetch ( ' /onboarding/api/participants' , {
37+ const response = await fetch ( ` /onboarding/api/participants?role= ${ roleFilter } ` , {
3738 cache : 'no-store'
3839 } ) ;
3940
@@ -59,7 +60,7 @@ export default function Home() {
5960 const interval = setInterval ( fetchData , 30000 ) ;
6061
6162 return ( ) => clearInterval ( interval ) ;
62- } , [ ] ) ;
63+ } , [ roleFilter ] ) ;
6364
6465 if ( loading ) {
6566 return (
@@ -147,10 +148,10 @@ export default function Home() {
147148 { /* Header */ }
148149 < div className = "mb-8 animate-fade-in" >
149150 < h1 className = "text-4xl md:text-5xl font-bold text-slate-900 dark:text-white mb-2" >
150- Participant Onboarding Status
151+ Onboarding Status
151152 </ h1 >
152153 < p className = "text-slate-600 dark:text-slate-400" >
153- Track participant onboarding progress in real-time
154+ Track technical onboarding progress in real-time
154155 </ p >
155156 { lastUpdated && (
156157 < p className = "text-sm text-slate-500 dark:text-slate-500 mt-2" >
@@ -218,6 +219,34 @@ export default function Home() {
218219
219220 { /* Filter and Export Controls */ }
220221 < div className = "flex flex-col sm:flex-row gap-4 mb-6 animate-slide-up" style = { { animationDelay : '150ms' } } >
222+ < div className = "flex-1" >
223+ < label htmlFor = "role-filter" className = "block text-sm font-semibold text-slate-700 dark:text-slate-300 mb-2" >
224+ Filter by Role
225+ </ label >
226+ < div className = "relative" >
227+ < div className = "absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none" >
228+ < svg className = "h-5 w-5 text-slate-400 dark:text-slate-500" fill = "none" stroke = "currentColor" viewBox = "0 0 24 24" >
229+ < path strokeLinecap = "round" strokeLinejoin = "round" strokeWidth = { 2 } d = "M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z" />
230+ </ svg >
231+ </ div >
232+ < select
233+ id = "role-filter"
234+ value = { roleFilter }
235+ onChange = { ( e ) => setRoleFilter ( e . target . value as 'participants' | 'facilitators' ) }
236+ className = "w-full sm:w-72 pl-10 pr-4 py-3 rounded-xl border-2 border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-800 text-slate-900 dark:text-white font-medium shadow-sm hover:border-slate-300 dark:hover:border-slate-600 focus:ring-2 focus:ring-blue-500 focus:border-blue-500 dark:focus:ring-blue-400 dark:focus:border-blue-400 transition-all duration-200 appearance-none cursor-pointer"
237+ style = { {
238+ backgroundImage : `url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e")` ,
239+ backgroundPosition : 'right 0.5rem center' ,
240+ backgroundRepeat : 'no-repeat' ,
241+ backgroundSize : '1.5em 1.5em'
242+ } }
243+ >
244+ < option value = "participants" > Participants</ option >
245+ < option value = "facilitators" > Facilitators</ option >
246+ </ select >
247+ </ div >
248+ </ div >
249+
221250 < div className = "flex-1" >
222251 < label htmlFor = "status-filter" className = "block text-sm font-semibold text-slate-700 dark:text-slate-300 mb-2" >
223252 Filter by Status
0 commit comments