@@ -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