@@ -1455,11 +1455,12 @@ async function renderAdminEggsSettings() {
14551455 <th>Name</th>
14561456 <th>Description</th>
14571457 <th>Panel Nest ID</th>
1458+ <th>Status</th>
14581459 <th>Actions</th>
14591460 </tr>
14601461 </thead>
14611462 <tbody id="admin-nests-tbody">
1462- <tr><td colspan="6 " style="text-align:center;padding:32px;color:var(--text-secondary)"><span class="spinner"></span> Loading...</td></tr>
1463+ <tr><td colspan="7 " style="text-align:center;padding:32px;color:var(--text-secondary)"><span class="spinner"></span> Loading...</td></tr>
14631464 </tbody>
14641465 </table>
14651466 </div>
@@ -1484,13 +1485,40 @@ async function renderAdminEggsSettings() {
14841485 <td><a href="/admin/settings/eggs/${ n . ptero_nest_id } " onclick="event.preventDefault();adminNavigateTo('settings/eggs/${ n . ptero_nest_id } ')" style="font-weight:600;cursor:pointer">${ n . name } </a></td>
14851486 <td style="color:var(--text-secondary);font-size:0.85rem;max-width:250px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">${ n . description || '—' } </td>
14861487 <td><span class="server-detail-tag">${ n . ptero_nest_id } </span></td>
1488+ <td>
1489+ <label class="toggle-switch" style="position:relative;display:inline-block;width:44px;height:24px;flex-shrink:0">
1490+ <input type="checkbox" class="nest-unavailable-toggle" data-id="${ n . id } " ${ n . unavailable ? 'checked' : '' } style="opacity:0;width:0;height:0">
1491+ <span class="toggle-slider" style="position:absolute;cursor:pointer;inset:0;background:var(--bg-secondary);border:1px solid var(--border);border-radius:24px;transition:0.2s"></span>
1492+ </label>
1493+ <span class="nest-status-label" data-id="${ n . id } " style="margin-left:8px;font-size:0.82rem;${ n . unavailable ? 'color:var(--accent-red)' : 'color:var(--accent-green)' } ">${ n . unavailable ? 'Unavailable' : 'Available' } </span>
1494+ </td>
14871495 <td style="display:flex;gap:6px">
14881496 <button class="btn btn-ghost btn-sm btn-rename-nest" data-id="${ n . id } " data-name="${ n . name } " data-logo="${ n . logo || '' } " data-description="${ ( n . description || '' ) . replace ( / " / g, '"' ) } " style="width:auto">Edit</button>
14891497 <button class="btn btn-danger btn-sm btn-delete-nest" data-id="${ n . id } " data-name="${ n . name } " style="width:auto">Delete</button>
14901498 </td>
14911499 </tr>
14921500 ` ) . join ( '' ) ;
14931501
1502+ tbody . querySelectorAll ( '.nest-unavailable-toggle' ) . forEach ( toggle => {
1503+ toggle . addEventListener ( 'change' , async ( ) => {
1504+ const nestId = parseInt ( toggle . dataset . id , 10 ) ;
1505+ const label = tbody . querySelector ( `.nest-status-label[data-id="${ nestId } "]` ) ;
1506+ try {
1507+ await adminApi ( `/settings/nests/${ nestId } ` , {
1508+ method : 'PUT' ,
1509+ body : JSON . stringify ( { unavailable : toggle . checked } ) ,
1510+ } ) ;
1511+ if ( label ) {
1512+ label . textContent = toggle . checked ? 'Unavailable' : 'Available' ;
1513+ label . style . color = toggle . checked ? 'var(--accent-red)' : 'var(--accent-green)' ;
1514+ }
1515+ } catch ( err ) {
1516+ toggle . checked = ! toggle . checked ;
1517+ showToast ( err . message , 'error' ) ;
1518+ }
1519+ } ) ;
1520+ } ) ;
1521+
14941522 tbody . querySelectorAll ( '.btn-rename-nest' ) . forEach ( btn => {
14951523 btn . addEventListener ( 'click' , ( ) => {
14961524 showRenameNestModal ( btn . dataset . id , btn . dataset . name , btn . dataset . logo , btn . dataset . description ) ;
@@ -1531,11 +1559,12 @@ async function renderAdminNestEggs(nestId) {
15311559 <th>Name</th>
15321560 <th>Description</th>
15331561 <th>Resources</th>
1562+ <th>Status</th>
15341563 <th>Actions</th>
15351564 </tr>
15361565 </thead>
15371566 <tbody id="admin-eggs-tbody">
1538- <tr><td colspan="6 " style="text-align:center;padding:32px;color:var(--text-secondary)"><span class="spinner"></span> Loading...</td></tr>
1567+ <tr><td colspan="7 " style="text-align:center;padding:32px;color:var(--text-secondary)"><span class="spinner"></span> Loading...</td></tr>
15391568 </tbody>
15401569 </table>
15411570 </div>
@@ -1556,19 +1585,48 @@ async function renderAdminNestEggs(nestId) {
15561585 const resStr = res
15571586 ? `CPU: ${ res . cpu_limit ?? 'default' } % / RAM: ${ res . memory_limit ?? 'default' } MB / Disk: ${ res . disk_limit ?? 'default' } MB`
15581587 : 'Defaults' ;
1588+ const isUnavailable = res ?. unavailable ;
15591589 return ahtml `
15601590 <tr>
15611591 <td>${ e . id } </td>
15621592 <td>${ res ?. logo ? `<img src="${ res . logo } " alt="" style="width:28px;height:28px;object-fit:contain;border-radius:4px">` : '<span style="color:var(--text-secondary);font-size:0.75rem">—</span>' } </td>
15631593 <td><strong>${ e . name } </strong></td>
15641594 <td style="color:var(--text-secondary);font-size:0.85rem;max-width:300px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">${ e . description || '—' } </td>
15651595 <td><span class="server-detail-tag" style="font-size:0.75rem">${ resStr } </span></td>
1596+ <td>
1597+ <label class="toggle-switch" style="position:relative;display:inline-block;width:44px;height:24px;flex-shrink:0">
1598+ <input type="checkbox" class="egg-unavailable-toggle" data-nest="${ nestId } " data-egg="${ e . id } " ${ isUnavailable ? 'checked' : '' } style="opacity:0;width:0;height:0">
1599+ <span class="toggle-slider" style="position:absolute;cursor:pointer;inset:0;background:var(--bg-secondary);border:1px solid var(--border);border-radius:24px;transition:0.2s"></span>
1600+ </label>
1601+ <span class="egg-status-label" data-nest="${ nestId } " data-egg="${ e . id } " style="margin-left:8px;font-size:0.82rem;${ isUnavailable ? 'color:var(--accent-red)' : 'color:var(--accent-green)' } ">${ isUnavailable ? 'Unavailable' : 'Available' } </span>
1602+ </td>
15661603 <td>
15671604 <a href="/admin/settings/eggs/${ nestId } /${ e . id } " onclick="event.preventDefault();adminNavigateTo('settings/eggs/${ nestId } /${ e . id } ')" class="btn btn-ghost btn-sm">Configure</a>
15681605 </td>
15691606 </tr>
15701607 ` ;
15711608 } ) . join ( '' ) ;
1609+
1610+ tbody . querySelectorAll ( '.egg-unavailable-toggle' ) . forEach ( toggle => {
1611+ toggle . addEventListener ( 'change' , async ( ) => {
1612+ const nId = parseInt ( toggle . dataset . nest , 10 ) ;
1613+ const eId = parseInt ( toggle . dataset . egg , 10 ) ;
1614+ const label = tbody . querySelector ( `.egg-status-label[data-nest="${ nId } "][data-egg="${ eId } "]` ) ;
1615+ try {
1616+ await adminApi ( `/settings/eggs/${ nId } /${ eId } ` , {
1617+ method : 'PUT' ,
1618+ body : JSON . stringify ( { unavailable : toggle . checked } ) ,
1619+ } ) ;
1620+ if ( label ) {
1621+ label . textContent = toggle . checked ? 'Unavailable' : 'Available' ;
1622+ label . style . color = toggle . checked ? 'var(--accent-red)' : 'var(--accent-green)' ;
1623+ }
1624+ } catch ( err ) {
1625+ toggle . checked = ! toggle . checked ;
1626+ showToast ( err . message , 'error' ) ;
1627+ }
1628+ } ) ;
1629+ } ) ;
15721630 } catch ( err ) {
15731631 const tbody = $a ( '#admin-eggs-tbody' ) ;
15741632 if ( tbody ) tbody . innerHTML = `<tr><td colspan="6" style="text-align:center;padding:32px;color:var(--accent-red)">Error: ${ err . message } </td></tr>` ;
0 commit comments