@@ -83,10 +83,10 @@ function triggerSearchIndexBuild() {
8383 searchIndexTriggered = true
8484 buildSearchIndex ( appData . anchors )
8585 . then ( ( ) => {
86- const searchInput = document . getElementById ( ' search-input')
87- if ( searchInput ) {
88- searchInput . placeholder = `${ i18n . t ( 'search.placeholder' ) } (full-text)`
89- }
86+ ; [ 'search-input' , 'header- search-input'] . forEach ( ( id ) => {
87+ const el = document . getElementById ( id )
88+ if ( el ) el . placeholder = `${ i18n . t ( 'search.placeholder' ) } (full-text)`
89+ } )
9090 } )
9191 . catch ( ( err ) => {
9292 console . warn ( 'Search index build failed:' , err )
@@ -128,9 +128,14 @@ function initApp() {
128128 showOnboarding ( )
129129 }
130130
131- ensureDataLoaded ( ) . catch ( ( err ) => {
132- console . error ( 'Failed to load app data:' , err )
133- } )
131+ ensureDataLoaded ( )
132+ . then ( ( ) => {
133+ populateHeaderRoleFilter ( )
134+ bindHeaderSearchInput ( )
135+ } )
136+ . catch ( ( err ) => {
137+ console . error ( 'Failed to load app data:' , err )
138+ } )
134139}
135140
136141function renderHomePage ( ) {
@@ -222,7 +227,66 @@ function initCardGridVisualization() {
222227}
223228
224229function bindRoleFilter ( ) {
225- const roleFilter = document . getElementById ( 'role-filter' )
230+ const roleFilterIds = [ 'role-filter' , 'header-role-filter' ]
231+
232+ roleFilterIds . forEach ( ( id ) => {
233+ const roleFilter = document . getElementById ( id )
234+ if ( ! roleFilter || ! appData ?. roles ) return
235+
236+ while ( roleFilter . options . length > 1 ) {
237+ roleFilter . remove ( 1 )
238+ }
239+
240+ appData . roles . forEach ( ( role ) => {
241+ const option = document . createElement ( 'option' )
242+ option . value = role . id
243+ option . textContent = role . name
244+ roleFilter . appendChild ( option )
245+ } )
246+
247+ roleFilter . onchange = ( e ) => {
248+ // Sync the other dropdown
249+ roleFilterIds . forEach ( ( otherId ) => {
250+ if ( otherId !== id ) {
251+ const other = document . getElementById ( otherId )
252+ if ( other ) other . value = e . target . value
253+ }
254+ } )
255+ const searchQuery = document . getElementById ( 'header-search-input' ) ?. value
256+ || document . getElementById ( 'search-input' ) ?. value || ''
257+ applyCardFilters ( e . target . value , searchQuery )
258+ }
259+ } )
260+ }
261+
262+ function bindSearchInput ( ) {
263+ const searchInputIds = [ 'search-input' , 'header-search-input' ]
264+
265+ searchInputIds . forEach ( ( id ) => {
266+ const searchInput = document . getElementById ( id )
267+ if ( ! searchInput ) return
268+
269+ searchInput . oninput = ( e ) => {
270+ const query = e . target . value
271+ // Sync the other search input
272+ searchInputIds . forEach ( ( otherId ) => {
273+ if ( otherId !== id ) {
274+ const other = document . getElementById ( otherId )
275+ if ( other ) other . value = query
276+ }
277+ } )
278+ if ( query . trim ( ) ) {
279+ triggerSearchIndexBuild ( )
280+ }
281+ const roleId = document . getElementById ( 'header-role-filter' ) ?. value
282+ || document . getElementById ( 'role-filter' ) ?. value || ''
283+ applyCardFilters ( roleId , query )
284+ }
285+ } )
286+ }
287+
288+ function populateHeaderRoleFilter ( ) {
289+ const roleFilter = document . getElementById ( 'header-role-filter' )
226290 if ( ! roleFilter || ! appData ?. roles ) return
227291
228292 while ( roleFilter . options . length > 1 ) {
@@ -237,22 +301,30 @@ function bindRoleFilter() {
237301 } )
238302
239303 roleFilter . onchange = ( e ) => {
240- const searchQuery = document . getElementById ( 'search-input' ) ?. value || ''
304+ // Sync the main content dropdown if it exists
305+ const mainFilter = document . getElementById ( 'role-filter' )
306+ if ( mainFilter ) mainFilter . value = e . target . value
307+
308+ const searchQuery = document . getElementById ( 'header-search-input' ) ?. value || ''
241309 applyCardFilters ( e . target . value , searchQuery )
242310 }
243311}
244312
245- function bindSearchInput ( ) {
246- const searchInput = document . getElementById ( 'search-input' )
313+ function bindHeaderSearchInput ( ) {
314+ const searchInput = document . getElementById ( 'header- search-input' )
247315 if ( ! searchInput ) return
248316
249317 searchInput . oninput = ( e ) => {
250318 const query = e . target . value
319+ // Sync the main content search input if it exists
320+ const mainSearch = document . getElementById ( 'search-input' )
321+ if ( mainSearch ) mainSearch . value = query
322+
251323 if ( query . trim ( ) ) {
252324 triggerSearchIndexBuild ( )
253325 }
254326
255- const roleId = document . getElementById ( 'role-filter' ) ?. value || ''
327+ const roleId = document . getElementById ( 'header- role-filter' ) ?. value || ''
256328 applyCardFilters ( roleId , query )
257329 }
258330}
0 commit comments