userbymahadi commited on
Commit
d0bd98c
·
verified ·
1 Parent(s): ce8ebe2

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +123 -109
index.html CHANGED
@@ -2,161 +2,175 @@
2
  <html lang="bn">
3
  <head>
4
  <meta charset="UTF-8">
5
- <title>DevOps Ultra Dashboard</title>
 
6
  <script src="https://cdn.tailwindcss.com"></script>
7
  <script src="https://unpkg.com/lucide@latest"></script>
8
  <style>
9
- @import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&display=swap');
10
- :root { --accent: #6366f1; --bg: #0b0f1a; }
11
- body { font-family: 'JetBrains Mono', monospace; background: var(--bg); color: #94a3b8; }
12
- .glass { background: rgba(23, 32, 53, 0.7); backdrop-filter: blur(12px); border: 1px solid rgba(255,255,255,0.05); }
13
- .active-tab { border-bottom: 2px solid var(--accent); color: white; }
14
- .file-item:hover { background: rgba(99, 102, 241, 0.1); }
15
  </style>
16
  </head>
17
- <body class="h-screen flex flex-col overflow-hidden">
18
 
19
- <!-- Auth Modal -->
20
- <div id="authBox" class="fixed inset-0 z-[100] flex items-center justify-center bg-black/80">
21
- <div class="glass p-8 rounded-2xl w-96 text-center">
22
- <div class="mb-4 inline-block p-4 bg-indigo-500/20 rounded-full text-indigo-400">
23
- <i data-lucide="shield-check" class="w-10 h-10"></i>
24
- </div>
25
- <h1 class="text-xl font-bold text-white mb-6">Enter Access Key</h1>
26
- <input type="password" id="key" class="w-full bg-slate-900 border border-slate-700 p-3 rounded-lg mb-4 outline-none focus:border-indigo-500 text-center" placeholder="••••••">
27
- <button onclick="initWS()" class="w-full bg-indigo-600 hover:bg-indigo-500 text-white py-3 rounded-lg font-bold transition-all">Unlock System</button>
28
- </div>
29
- </div>
30
 
31
- <!-- Top Navigation -->
32
- <nav class="h-14 border-b border-white/5 flex items-center justify-between px-6 glass">
33
- <div class="flex items-center gap-4">
34
- <div class="flex items-center gap-2 text-white font-bold">
35
- <div class="w-3 h-3 bg-indigo-500 rounded-full animate-pulse"></div>
36
- ULTRA-SHELL <span class="text-[10px] bg-indigo-500/20 px-2 py-0.5 rounded text-indigo-400">V3.5</span>
 
 
 
 
 
 
 
37
  </div>
38
- </div>
39
- <div class="flex gap-6 text-xs font-bold uppercase tracking-widest">
40
- <div class="flex items-center gap-2"><i data-lucide="cpu" class="w-4 h-4 text-rose-500"></i> CPU: <span id="cpu" class="text-white">--</span></div>
41
- <div class="flex items-center gap-2"><i data-lucide="layers" class="w-4 h-4 text-emerald-500"></i> RAM: <span id="ram" class="text-white">--</span></div>
42
- <div class="flex items-center gap-2"><i data-lucide="hard-drive" class="w-4 h-4 text-amber-500"></i> DISK: <span id="disk" class="text-white">--</span></div>
43
- </div>
44
- </nav>
45
-
46
- <div class="flex flex-1 overflow-hidden">
47
- <!-- Sidebar Explorer -->
48
- <aside class="w-72 border-r border-white/5 flex flex-col glass">
49
- <div class="p-4 flex items-center justify-between border-b border-white/5 text-xs font-bold uppercase">
50
- <span>File Explorer</span>
51
- <button onclick="loadFiles()" class="hover:rotate-180 transition-all duration-500"><i data-lucide="refresh-cw" class="w-4 h-4"></i></button>
52
- </div>
53
- <div id="explorer" class="flex-1 overflow-y-auto p-2 space-y-1"></div>
54
  </aside>
55
 
56
- <!-- Terminal Container -->
57
- <main class="flex-1 flex flex-col relative bg-black/20">
58
- <!-- Tabs -->
59
- <div class="flex bg-black/40 text-[10px] font-bold uppercase border-b border-white/5">
60
- <div class="px-6 py-3 active-tab cursor-pointer flex items-center gap-2">
61
- <i data-lucide="terminal" class="w-3 h-3"></i> Main Terminal
 
62
  </div>
63
- <div class="px-6 py-3 opacity-30 cursor-not-allowed hover:bg-white/5 transition-all">
64
- <i data-lucide="plus" class="w-3 h-3"></i>
 
65
  </div>
66
  </div>
67
 
68
- <!-- Terminal Screen -->
69
- <div id="output" class="flex-1 overflow-y-auto p-6 space-y-3 text-sm scroll-smooth">
70
- <div class="text-emerald-400 opacity-50">System ready. Type 'help' for instructions.</div>
 
 
 
 
 
 
 
71
  </div>
72
 
73
- <!-- Input Box -->
74
- <div class="p-4">
75
- <div class="glass flex items-center px-4 py-2 rounded-xl focus-within:ring-2 ring-indigo-500/50 transition-all">
76
- <span class="text-indigo-400 font-bold mr-3">❯</span>
77
- <input type="text" id="cmd" class="flex-1 bg-transparent border-none outline-none text-indigo-100 placeholder:text-slate-600" placeholder="Execute shell command..." autocomplete="off">
78
- <div class="flex gap-3 ml-3 text-slate-500">
79
- <i data-lucide="command" class="w-4 h-4"></i>
80
- <i data-lucide="history" class="w-4 h-4 cursor-pointer hover:text-white" onclick="showHistory()"></i>
81
- </div>
82
  </div>
 
83
  </div>
 
84
  </main>
85
  </div>
86
 
 
 
 
 
 
 
 
 
 
87
  <script>
88
  lucide.createIcons();
89
  let ws;
90
- const output = document.getElementById('output');
91
- const cmdInput = document.getElementById('cmd');
92
 
93
- function initWS() {
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  const key = document.getElementById('key').value;
95
  const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
96
  ws = new WebSocket(`${protocol}//${window.location.host}/ws`);
97
-
98
  ws.onopen = () => ws.send(key);
99
  ws.onmessage = (e) => {
100
- if (e.data === "[+] AUTH_SUCCESS") {
101
- document.getElementById('authBox').classList.add('hidden');
102
- startMonitoring();
103
- loadFiles();
104
- } else if (e.data === "[-] AUTH_FAILED") {
105
- alert("Invalid Key!");
106
- } else {
107
- writeToTerminal(e.data, 'msg');
108
- }
109
  };
110
- ws.onclose = () => { setTimeout(initWS, 3000); };
111
  }
112
 
113
- function writeToTerminal(text, type) {
114
- const el = document.createElement('div');
115
- if (type === 'cmd') {
116
- el.className = "text-white font-bold mt-4 flex items-center gap-2";
117
- el.innerHTML = `<span class="text-indigo-500">➜</span> ${text}`;
118
- } else {
119
- el.className = "bg-slate-800/30 p-4 rounded-lg border-l-4 border-indigo-500/50 whitespace-pre-wrap text-slate-300";
120
- el.innerText = text;
121
- }
122
- output.appendChild(el);
123
- output.scrollTop = output.scrollHeight;
124
  }
125
 
126
- cmdInput.addEventListener('keydown', (e) => {
127
- if (e.key === 'Enter' && cmdInput.value.trim()) {
128
- const command = cmdInput.value;
129
- writeToTerminal(command, 'cmd');
130
- ws.send(command);
131
- cmdInput.value = '';
132
  }
133
- });
134
-
135
- async function startMonitoring() {
136
- setInterval(async () => {
137
- const res = await fetch('/api/metrics');
138
- const data = await res.json();
139
- document.getElementById('cpu').innerText = data.cpu + '%';
140
- document.getElementById('ram').innerText = data.ram + '%';
141
- document.getElementById('disk').innerText = data.disk + '%';
142
- }, 3000);
143
  }
144
 
 
145
  async function loadFiles() {
146
  const res = await fetch('/api/files');
147
  const files = await res.json();
148
- const explorer = document.getElementById('explorer');
149
- explorer.innerHTML = files.map(f => `
150
- <div class="file-item flex items-center justify-between p-2 rounded cursor-pointer group">
151
- <div class="flex items-center gap-2 truncate">
152
- <i data-lucide="${f.is_dir ? 'folder' : 'file'}" class="w-4 h-4 ${f.is_dir ? 'text-amber-400' : 'text-slate-400'}"></i>
153
- <span class="text-xs ${f.is_dir ? 'text-slate-200' : 'text-slate-400'}">${f.name}</span>
154
  </div>
155
- <span class="text-[10px] hidden group-hover:block opacity-50">${f.size}</span>
156
  </div>
157
  `).join('');
158
  lucide.createIcons();
159
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
160
  </script>
161
  </body>
162
  </html>
 
2
  <html lang="bn">
3
  <head>
4
  <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>DevOps Mobile Pro</title>
7
  <script src="https://cdn.tailwindcss.com"></script>
8
  <script src="https://unpkg.com/lucide@latest"></script>
9
  <style>
10
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600&family=Fira+Code&display=swap');
11
+ body { font-family: 'Inter', sans-serif; background: #0f172a; color: #f8fafc; }
12
+ .sidebar { transition: transform 0.3s ease-in-out; }
13
+ .glass { background: rgba(30, 41, 59, 0.7); backdrop-filter: blur(10px); }
14
+ .terminal-font { font-family: 'Fira Code', monospace; }
 
15
  </style>
16
  </head>
17
+ <body class="overflow-hidden h-screen flex flex-col">
18
 
19
+ <!-- Mobile Header -->
20
+ <header class="h-16 glass border-b border-white/10 flex items-center justify-between px-4 z-40">
21
+ <button onclick="toggleSidebar()" class="p-2 hover:bg-white/10 rounded-lg">
22
+ <i data-lucide="menu"></i>
23
+ </button>
24
+ <h1 class="font-bold text-indigo-400">ULTRA DASHBOARD</h1>
25
+ <div class="w-8"></div> <!-- Spacer -->
26
+ </header>
 
 
 
27
 
28
+ <div class="flex flex-1 relative overflow-hidden">
29
+ <!-- Sidebar Menu -->
30
+ <aside id="sidebar" class="sidebar absolute inset-y-0 left-0 w-64 glass border-r border-white/10 z-50 -translate-x-full lg:translate-x-0">
31
+ <div class="p-6 space-y-4">
32
+ <button onclick="showPage('terminal')" class="w-full flex items-center gap-3 p-3 rounded-xl hover:bg-indigo-600 transition-all">
33
+ <i data-lucide="terminal"></i> Terminal
34
+ </button>
35
+ <button onclick="showPage('files')" class="w-full flex items-center gap-3 p-3 rounded-xl hover:bg-indigo-600 transition-all">
36
+ <i data-lucide="folder"></i> File Manager
37
+ </button>
38
+ <button onclick="showPage('proxy')" class="w-full flex items-center gap-3 p-3 rounded-xl hover:bg-indigo-600 transition-all">
39
+ <i data-lucide="globe"></i> Web Preview
40
+ </button>
41
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  </aside>
43
 
44
+ <!-- Main Content Area -->
45
+ <main class="flex-1 overflow-y-auto p-4 relative">
46
+
47
+ <!-- 1. Terminal Page -->
48
+ <div id="page-terminal" class="page-content space-y-4">
49
+ <div id="output" class="h-[60vh] glass rounded-2xl p-4 overflow-y-auto terminal-font text-xs leading-relaxed">
50
+ <div class="text-indigo-400">System Ready...</div>
51
  </div>
52
+ <div class="flex gap-2">
53
+ <input type="text" id="cmd" class="flex-1 bg-slate-900 border border-slate-700 rounded-xl p-3 outline-none focus:border-indigo-500" placeholder="Type command...">
54
+ <button onclick="runCmd()" class="bg-indigo-600 p-3 rounded-xl"><i data-lucide="play"></i></button>
55
  </div>
56
  </div>
57
 
58
+ <!-- 2. File Manager Page -->
59
+ <div id="page-files" class="page-content hidden">
60
+ <div class="flex justify-between items-center mb-4">
61
+ <h2 class="text-xl font-bold">Files</h2>
62
+ <input type="file" id="uploadInput" onchange="uploadFile()" class="hidden">
63
+ <button onclick="document.getElementById('uploadInput').click()" class="bg-emerald-600 px-4 py-2 rounded-lg text-sm">Upload</button>
64
+ </div>
65
+ <div id="file-list" class="glass rounded-2xl divide-y divide-white/5">
66
+ <!-- Files will load here -->
67
+ </div>
68
  </div>
69
 
70
+ <!-- 3. Web Preview Page -->
71
+ <div id="page-proxy" class="page-content hidden h-full flex flex-col">
72
+ <div class="flex gap-2 mb-4">
73
+ <input type="text" id="proxyUrl" value="http://localhost:8080" class="flex-1 bg-slate-900 border border-slate-700 rounded-lg p-2 text-sm">
74
+ <button onclick="loadProxy()" class="bg-indigo-600 px-4 py-2 rounded-lg text-sm">Load</button>
 
 
 
 
75
  </div>
76
+ <iframe id="proxyFrame" class="flex-1 w-full bg-white rounded-xl border-none"></iframe>
77
  </div>
78
+
79
  </main>
80
  </div>
81
 
82
+ <!-- Auth Modal (Overlay) -->
83
+ <div id="authBox" class="fixed inset-0 z-[100] flex items-center justify-center bg-black/90 p-6">
84
+ <div class="glass p-8 rounded-3xl w-full max-w-sm text-center">
85
+ <h2 class="text-xl font-bold mb-6">Enter Password</h2>
86
+ <input type="password" id="key" class="w-full bg-slate-900 border border-slate-700 p-4 rounded-xl mb-4 text-center outline-none focus:border-indigo-500">
87
+ <button onclick="initAuth()" class="w-full bg-indigo-600 py-4 rounded-xl font-bold">Login</button>
88
+ </div>
89
+ </div>
90
+
91
  <script>
92
  lucide.createIcons();
93
  let ws;
 
 
94
 
95
+ function toggleSidebar() {
96
+ const sidebar = document.getElementById('sidebar');
97
+ sidebar.classList.toggle('-translate-x-full');
98
+ }
99
+
100
+ function showPage(pageId) {
101
+ document.querySelectorAll('.page-content').forEach(p => p.classList.add('hidden'));
102
+ document.getElementById('page-' + pageId).classList.remove('hidden');
103
+ if (window.innerWidth < 1024) toggleSidebar();
104
+ if (pageId === 'files') loadFiles();
105
+ }
106
+
107
+ // --- Auth & Terminal ---
108
+ function initAuth() {
109
  const key = document.getElementById('key').value;
110
  const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
111
  ws = new WebSocket(`${protocol}//${window.location.host}/ws`);
 
112
  ws.onopen = () => ws.send(key);
113
  ws.onmessage = (e) => {
114
+ if(e.data === "AUTH_SUCCESS") document.getElementById('authBox').style.display = 'none';
115
+ else if(e.data === "AUTH_FAILED") alert("Wrong!");
116
+ else appendToTerminal(e.data);
 
 
 
 
 
 
117
  };
 
118
  }
119
 
120
+ function appendToTerminal(txt) {
121
+ const out = document.getElementById('output');
122
+ const div = document.createElement('div');
123
+ div.className = "bg-black/20 p-2 rounded mb-2 whitespace-pre-wrap border-l border-indigo-500";
124
+ div.innerText = txt;
125
+ out.appendChild(div);
126
+ out.scrollTop = out.scrollHeight;
 
 
 
 
127
  }
128
 
129
+ function runCmd() {
130
+ const input = document.getElementById('cmd');
131
+ if(input.value) {
132
+ ws.send(input.value);
133
+ input.value = '';
 
134
  }
 
 
 
 
 
 
 
 
 
 
135
  }
136
 
137
+ // --- File Manager ---
138
  async function loadFiles() {
139
  const res = await fetch('/api/files');
140
  const files = await res.json();
141
+ const list = document.getElementById('file-list');
142
+ list.innerHTML = files.map(f => `
143
+ <div class="flex items-center justify-between p-4 hover:bg-white/5">
144
+ <div class="flex items-center gap-3">
145
+ <i data-lucide="${f.is_dir ? 'folder' : 'file'}" class="w-5 h-5 text-indigo-400"></i>
146
+ <span class="text-sm">${f.name}</span>
147
  </div>
148
+ <button onclick="deleteFile('${f.path}')" class="text-red-400 p-2"><i data-lucide="trash-2" class="w-4 h-4"></i></button>
149
  </div>
150
  `).join('');
151
  lucide.createIcons();
152
  }
153
+
154
+ async function uploadFile() {
155
+ const file = document.getElementById('uploadInput').files[0];
156
+ const formData = new FormData();
157
+ formData.append('file', file);
158
+ await fetch('/api/upload', { method: 'POST', body: formData });
159
+ loadFiles();
160
+ }
161
+
162
+ async function deleteFile(path) {
163
+ if(confirm('Delete?')) {
164
+ await fetch(`/api/delete?path=${path}`, { method: 'DELETE' });
165
+ loadFiles();
166
+ }
167
+ }
168
+
169
+ // --- Proxy ---
170
+ function loadProxy() {
171
+ const url = document.getElementById('proxyUrl').value;
172
+ document.getElementById('proxyFrame').src = `/proxy?url=${encodeURIComponent(url)}`;
173
+ }
174
  </script>
175
  </body>
176
  </html>