@@ -501,17 +501,23 @@ function updateAdminNav() {
501501}
502502
503503let adminServersPage = 1 ;
504+ let adminServersSearch = '' ;
504505
505506async function renderAdminServers ( ) {
506507 document . querySelectorAll ( '.admin-page' ) . forEach ( p => p . classList . remove ( 'active' ) ) ;
507508 const el = $a ( '#admin-page-servers' ) ;
508509 if ( ! el ) return ;
509510 el . classList . add ( 'active' ) ;
511+ adminServersSearch = '' ;
510512 el . innerHTML = ahtml `
511513 <div class="page-header">
512514 <h1 class="page-title">All Servers</h1>
513515 <p class="page-subtitle">All servers across all users</p>
514516 </div>
517+ <div class="search-wrapper" style="margin-bottom:16px;max-width:400px" id="admin-servers-search-wrapper">
518+ <span data-lucide="search"></span>
519+ <input type="text" id="admin-servers-search" placeholder="Search by server name or owner...">
520+ </div>
515521 <div class="table-container">
516522 <table>
517523 <thead>
@@ -531,6 +537,19 @@ async function renderAdminServers() {
531537 </div>
532538 ` ;
533539
540+ const searchInput = $a ( '#admin-servers-search' ) ;
541+ if ( searchInput ) {
542+ let searchTimer ;
543+ searchInput . addEventListener ( 'input' , ( ) => {
544+ clearTimeout ( searchTimer ) ;
545+ searchTimer = setTimeout ( ( ) => {
546+ adminServersSearch = searchInput . value . trim ( ) ;
547+ adminServersPage = 1 ;
548+ fetchAdminServers ( 1 ) ;
549+ } , 400 ) ;
550+ } ) ;
551+ }
552+
534553 await fetchAdminServers ( adminServersPage ) ;
535554}
536555
@@ -539,9 +558,11 @@ async function fetchAdminServers(pageNum) {
539558 const limit = 10 ;
540559 const offset = ( pageNum - 1 ) * limit ;
541560 const paginationEl = $a ( '#admin-servers-pagination' ) ;
561+ const params = new URLSearchParams ( { limit, offset } ) ;
562+ if ( adminServersSearch ) params . set ( 'search' , adminServersSearch ) ;
542563
543564 try {
544- const data = await adminApi ( `/servers?limit= ${ limit } &offset= ${ offset } ` ) ;
565+ const data = await adminApi ( `/servers?${ params . toString ( ) } ` ) ;
545566 const tbody = $a ( '#admin-servers-tbody' ) ;
546567 if ( ! tbody ) return ;
547568
@@ -589,7 +610,7 @@ async function fetchAdminServers(pageNum) {
589610 }
590611 } catch ( err ) {
591612 const tbody = $a ( '#admin-servers-tbody' ) ;
592- if ( tbody ) tbody . innerHTML = `<tr><td colspan="5" style="text-align:center;padding:32px;color:var(--accent-red)">Error: ${ err . message } </td></tr>` ;
613+ if ( tbody ) tbody . innerHTML = `<tr><td colspan="5" style="text-align:center;padding:32px;color:var(--accent-red)">Error: ${ escapeHtml ( err . message ) } </td></tr>` ;
593614 }
594615 initIcons ( ) ;
595616}
@@ -1151,7 +1172,7 @@ async function renderAdminDashboard() {
11511172 } ) ;
11521173 }
11531174 } catch ( err ) {
1154- el . innerHTML = `<div class="empty-state"><div class="empty-state-title">Error</div><div class="empty-state-desc">${ err . message } </div></div>` ;
1175+ el . innerHTML = `<div class="empty-state"><div class="empty-state-title">Error</div><div class="empty-state-desc">${ escapeHtml ( err . message ) } </div></div>` ;
11551176 }
11561177}
11571178
@@ -1212,7 +1233,7 @@ async function renderAdminUsers() {
12121233 ` ) . join ( '' ) ;
12131234 } catch ( err ) {
12141235 const tbody = $a ( '#admin-users-tbody' ) ;
1215- if ( tbody ) tbody . innerHTML = `<tr><td colspan="7" style="text-align:center;padding:32px;color:var(--accent-red)">Error: ${ err . message } </td></tr>` ;
1236+ if ( tbody ) tbody . innerHTML = `<tr><td colspan="7" style="text-align:center;padding:32px;color:var(--accent-red)">Error: ${ escapeHtml ( err . message ) } </td></tr>` ;
12161237 }
12171238 initIcons ( ) ;
12181239}
@@ -1639,7 +1660,7 @@ async function renderAdminEggsSettings() {
16391660 } ) ;
16401661 } catch ( err ) {
16411662 const tbody = $a ( '#admin-nests-tbody' ) ;
1642- if ( tbody ) tbody . innerHTML = `<tr><td colspan="4" style="text-align:center;padding:32px;color:var(--accent-red)">Error: ${ err . message } </td></tr>` ;
1663+ if ( tbody ) tbody . innerHTML = `<tr><td colspan="4" style="text-align:center;padding:32px;color:var(--accent-red)">Error: ${ escapeHtml ( err . message ) } </td></tr>` ;
16431664 }
16441665}
16451666
@@ -1737,7 +1758,7 @@ async function renderAdminNestEggs(nestId) {
17371758 } ) ;
17381759 } catch ( err ) {
17391760 const tbody = $a ( '#admin-eggs-tbody' ) ;
1740- if ( tbody ) tbody . innerHTML = `<tr><td colspan="5" style="text-align:center;padding:32px;color:var(--accent-red)">Error: ${ err . message } </td></tr>` ;
1761+ if ( tbody ) tbody . innerHTML = `<tr><td colspan="5" style="text-align:center;padding:32px;color:var(--accent-red)">Error: ${ escapeHtml ( err . message ) } </td></tr>` ;
17411762 }
17421763 initIcons ( ) ;
17431764}
@@ -1870,7 +1891,9 @@ async function renderAdminEggSettings(nestId, eggId) {
18701891 const val = $a ( '#egg-logo' ) . value ;
18711892 if ( val ) {
18721893 if ( preview ) preview . style . display = 'block' ;
1873- if ( img ) img . src = val ;
1894+ if ( img ) {
1895+ try { const u = new URL ( val ) ; if ( u . protocol === 'http:' || u . protocol === 'https:' || u . protocol === 'data:' || u . protocol === 'blob:' ) img . src = u . href ; else img . src = '' ; } catch { img . src = '' ; }
1896+ }
18741897 } else {
18751898 if ( preview ) preview . style . display = 'none' ;
18761899 }
@@ -2228,7 +2251,9 @@ function showRenameNestModal(nestId, currentName, currentLogo, currentDescriptio
22282251 const img = preview ?. querySelector ( 'img' ) ;
22292252 if ( logoInput . value ) {
22302253 if ( preview ) preview . style . display = 'block' ;
2231- if ( img ) img . src = logoInput . value ;
2254+ if ( img ) {
2255+ try { const u = new URL ( logoInput . value ) ; if ( u . protocol === 'http:' || u . protocol === 'https:' || u . protocol === 'data:' || u . protocol === 'blob:' ) img . src = u . href ; else img . src = '' ; } catch { img . src = '' ; }
2256+ }
22322257 } else {
22332258 if ( preview ) preview . style . display = 'none' ;
22342259 }
@@ -2381,7 +2406,7 @@ async function renderAdminNodes() {
23812406 } ) . join ( '' ) ;
23822407 } catch ( err ) {
23832408 const tbody = $a ( '#admin-nodes-tbody' ) ;
2384- if ( tbody ) tbody . innerHTML = `<tr><td colspan="8" style="text-align:center;padding:32px;color:var(--accent-red)">Error: ${ err . message } </td></tr>` ;
2409+ if ( tbody ) tbody . innerHTML = `<tr><td colspan="8" style="text-align:center;padding:32px;color:var(--accent-red)">Error: ${ escapeHtml ( err . message ) } </td></tr>` ;
23852410 }
23862411}
23872412
0 commit comments