|
41 | 41 | </dd>
|
42 | 42 | </div>
|
43 | 43 | </dl>
|
44 |
| - <div class="bg-neutral-700/10 rounded-xl pb-4 mt-5 shadow sm:p-6"> |
45 |
| - <script> |
46 |
| - fetch('// we dont have a version api yet') |
47 |
| - .then(response => response.json()) |
48 |
| - .then(data => { |
49 |
| - const currentVersion = '<%= airlinkVersion %>'; |
50 |
| - const latestVersion = data.airlink_canary.panel_latest; |
51 |
| - const versionSpan = document.getElementById('currentVersion'); |
52 |
| - const releaseSpan = document.getElementById('releaseInfo'); |
53 |
| - const versionStatusSpan = document.getElementById('versionStatus'); |
54 |
| - |
55 |
| - versionSpan.textContent = currentVersion; |
56 |
| - |
57 |
| - if (currentVersion === latestVersion) { |
58 |
| - versionStatusSpan.textContent = '<%= req.translations.runningLatestVersion %>'; |
59 |
| - } else { |
60 |
| - const link = document.createElement('a'); |
61 |
| - link.href = 'https://github.com/airlinklabs/panel/releases/tag/' + latestVersion; |
62 |
| - link.classList.add('text-amber-500', 'transition', 'hover:text-amber-600', 'font-medium'); |
63 |
| - link.textContent = '<%= req.translations.here %>'; |
64 |
| - |
65 |
| - const linkText = document.createTextNode(`<%= req.translations.newReleaseAirlink1 %> ${latestVersion} <%= req.translations.newReleaseAirlink2 %> `); |
66 |
| - versionStatusSpan.appendChild(linkText); |
67 |
| - versionStatusSpan.appendChild(link); |
68 |
| - versionStatusSpan.appendChild(document.createTextNode(' <%= req.translations.newReleaseAirlink3 %>')); |
69 |
| - versionStatusSpan.classList.add('text-amber-500', 'pt-2'); |
70 |
| - } |
71 |
| - }) |
72 |
| - .catch(error => { |
73 |
| - console.error('Error fetching latest version:', error); |
74 |
| - }); |
75 |
| - </script> |
76 |
| - <img src="// comming soon" class="h-24"> |
77 |
| - <p class="text-sm mt-1 font-normal text-neutral-300 mb-2"> |
78 |
| - <%= req.translations.sysInfoText %> <span id="currentVersion"></span>. <span id="versionStatus"></span> |
79 |
| - </p> |
| 44 | + <div class="bg-neutral-700/10 rounded-xl pb-4 mt-5 shadow sm:p-6"> |
| 45 | + <img src="// coming soon" class="h-24"> |
| 46 | + <p class="text-sm mt-1 font-normal text-neutral-300 mb-2"> |
| 47 | + <%= req.translations.sysInfoText %> <span id="currentVersion"></span> |
| 48 | + <span class="text-xs text-neutral-400">(<%= process.env.NODE_ENV %>)</span> |
| 49 | + </p> |
| 50 | + <div id="updateStatus" class="mb-4"></div> |
| 51 | + <div class="flex space-x-4"> |
| 52 | + <button id="checkUpdateBtn" class="bg-blue-600 text-white px-4 py-2 rounded-xl hover:bg-blue-700 transition"> |
| 53 | + Check for Updates |
| 54 | + </button> |
| 55 | + <button id="performUpdateBtn" class="hidden bg-green-600 text-white px-4 py-2 rounded-xl hover:bg-green-700 transition"> |
| 56 | + Install Update |
| 57 | + </button> |
80 | 58 | </div>
|
| 59 | + </div> |
| 60 | + |
| 61 | + <script> |
| 62 | + const currentVersion = '<%= airlinkVersion %>'; |
| 63 | + document.getElementById('currentVersion').textContent = currentVersion; |
| 64 | + |
| 65 | + document.getElementById('checkUpdateBtn').addEventListener('click', async () => { |
| 66 | + try { |
| 67 | + const response = await fetch('/admin/check-update'); |
| 68 | + const data = await response.json(); |
| 69 | + const statusDiv = document.getElementById('updateStatus'); |
| 70 | + const updateBtn = document.getElementById('performUpdateBtn'); |
| 71 | + const updateInfo = document.getElementById('updateInfo'); |
| 72 | + |
| 73 | + if (data.hasUpdate) { |
| 74 | + statusDiv.innerHTML = `A new version (${data.latestVersion}) is available. Current version: ${data.currentVersion}`; |
| 75 | + statusDiv.className = 'text-amber-500 mb-4'; |
| 76 | + updateBtn.classList.remove('hidden'); |
| 77 | + if (data.updateInfo) { |
| 78 | + updateInfo.textContent = data.updateInfo; |
| 79 | + updateInfo.classList.remove('hidden'); |
| 80 | + } |
| 81 | + } else { |
| 82 | + statusDiv.innerHTML = '<%= req.translations.runningLatestVersion %>'; |
| 83 | + statusDiv.className = 'text-green-400 mb-4'; |
| 84 | + updateBtn.classList.add('hidden'); |
| 85 | + updateInfo.classList.add('hidden'); |
| 86 | + } |
| 87 | + } catch (error) { |
| 88 | + console.error('Error:', error); |
| 89 | + } |
| 90 | + }); |
| 91 | + |
| 92 | + document.getElementById('performUpdateBtn').addEventListener('click', async () => { |
| 93 | + if (confirm('Do you want to perform the update? The server will restart automatically.')) { |
| 94 | + try { |
| 95 | + const response = await fetch('/admin/perform-update', { method: 'POST' }); |
| 96 | + const data = await response.json(); |
| 97 | + alert(data.message || 'Update completed. Server will restart.'); |
| 98 | + setTimeout(() => window.location.reload(), 5000); |
| 99 | + } catch (error) { |
| 100 | + console.error('Error:', error); |
| 101 | + alert('Error performing update'); |
| 102 | + } |
| 103 | + } |
| 104 | + }); |
| 105 | + </script> |
81 | 106 | <div class="mt-5 flex justify-between space-x-8">
|
82 | 107 | <a href="https://discord.gg/BybfXms7JZ" class="block rounded-xl bg-amber-500 px-3 py-2 text-center text-sm font-medium text-white shadow-lg hover:bg-amber-600 transition focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-amber-600 w-full">
|
83 | 108 | <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-5 h-5 inline-flex mr-1 mb-0.5">
|
|
0 commit comments