Skip to content

Commit 9881ea3

Browse files
CopilotSteake
andcommitted
Fix start button and add deployment UI to admin console
Co-authored-by: Steake <530040+Steake@users.noreply.github.com>
1 parent af73ea3 commit 9881ea3

1 file changed

Lines changed: 94 additions & 3 deletions

File tree

crates/bitcell-admin/src/web/dashboard.rs

Lines changed: 94 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -771,12 +771,41 @@ pub async fn index() -> impl IntoResponse {
771771
772772
<!-- Nodes Section -->
773773
<div class="card" style="margin-top: 2rem;">
774-
<h2>🖥️ Registered Nodes</h2>
774+
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem;">
775+
<h2 style="margin: 0;">🖥️ Registered Nodes</h2>
776+
<button class="btn" onclick="showDeployDialog()">+ Deploy Nodes</button>
777+
</div>
775778
<div id="nodes-list" class="node-list">
776779
<div class="loading">Loading nodes...</div>
777780
</div>
778781
</div>
779782
783+
<!-- Deploy Dialog -->
784+
<div id="deploy-overlay" class="wizard-overlay">
785+
<div class="wizard-container" style="max-width: 500px;">
786+
<div class="wizard-header">
787+
<h2>Deploy New Nodes</h2>
788+
<p>Deploy new BitCell nodes to your network</p>
789+
</div>
790+
<div class="form-group">
791+
<label>Node Type</label>
792+
<select id="deploy-node-type" class="btn" style="width: 100%; padding: 0.75rem;">
793+
<option value="Validator">Validator</option>
794+
<option value="Miner">Miner</option>
795+
<option value="FullNode">Full Node</option>
796+
</select>
797+
</div>
798+
<div class="form-group">
799+
<label>Number of Nodes</label>
800+
<input type="number" id="deploy-count" value="1" min="1" max="10" style="width: 100%; padding: 0.75rem;">
801+
</div>
802+
<div class="wizard-actions">
803+
<button class="btn btn-secondary" onclick="closeDeployDialog()">Cancel</button>
804+
<button class="btn" onclick="deployNodes()">Deploy</button>
805+
</div>
806+
</div>
807+
</div>
808+
780809
<!-- Battle Visualization Section -->
781810
<div class="card" style="margin-top: 2rem;">
782811
<h2>⚔️ Cellular Automata Battle Visualization</h2>
@@ -1006,6 +1035,50 @@ pub async fn index() -> impl IntoResponse {
10061035
window.location.reload();
10071036
}
10081037
1038+
function showDeployDialog() {
1039+
document.getElementById('deploy-overlay').classList.add('active');
1040+
}
1041+
1042+
function closeDeployDialog() {
1043+
document.getElementById('deploy-overlay').classList.remove('active');
1044+
}
1045+
1046+
async function deployNodes() {
1047+
const nodeType = document.getElementById('deploy-node-type').value;
1048+
const count = parseInt(document.getElementById('deploy-count').value);
1049+
1050+
if (count < 1 || count > 10) {
1051+
alert('Please enter a number between 1 and 10');
1052+
return;
1053+
}
1054+
1055+
try {
1056+
const response = await fetch('/api/deployment/deploy', {
1057+
method: 'POST',
1058+
headers: { 'Content-Type': 'application/json' },
1059+
body: JSON.stringify({
1060+
node_type: nodeType,
1061+
count: count
1062+
})
1063+
});
1064+
1065+
if (!response.ok) {
1066+
const error = await response.text();
1067+
throw new Error(error);
1068+
}
1069+
1070+
const data = await response.json();
1071+
alert(`Successfully deployed ${data.nodes_deployed} ${nodeType} node(s)`);
1072+
closeDeployDialog();
1073+
1074+
// Refresh nodes list after a short delay
1075+
setTimeout(updateNodes, 1000);
1076+
} catch (error) {
1077+
console.error('Deployment failed:', error);
1078+
alert('Deployment failed: ' + error.message);
1079+
}
1080+
}
1081+
10091082
// Fetch and update metrics
10101083
async function updateMetrics() {
10111084
try {
@@ -1072,19 +1145,37 @@ pub async fn index() -> impl IntoResponse {
10721145
10731146
async function startNode(id) {
10741147
try {
1075-
await fetch(`/api/nodes/${id}/start`, { method: 'POST' });
1148+
const response = await fetch(`/api/nodes/${id}/start`, {
1149+
method: 'POST',
1150+
headers: { 'Content-Type': 'application/json' },
1151+
body: JSON.stringify({ config: null })
1152+
});
1153+
1154+
if (!response.ok) {
1155+
const error = await response.json();
1156+
throw new Error(error.error || 'Failed to start node');
1157+
}
1158+
10761159
updateNodes();
10771160
} catch (error) {
10781161
console.error('Failed to start node:', error);
1162+
alert('Failed to start node: ' + error.message);
10791163
}
10801164
}
10811165
10821166
async function stopNode(id) {
10831167
try {
1084-
await fetch(`/api/nodes/${id}/stop`, { method: 'POST' });
1168+
const response = await fetch(`/api/nodes/${id}/stop`, { method: 'POST' });
1169+
1170+
if (!response.ok) {
1171+
const error = await response.json();
1172+
throw new Error(error.error || 'Failed to stop node');
1173+
}
1174+
10851175
updateNodes();
10861176
} catch (error) {
10871177
console.error('Failed to stop node:', error);
1178+
alert('Failed to stop node: ' + error.message);
10881179
}
10891180
}
10901181

0 commit comments

Comments
 (0)