Make the Left side, where you currently have "Servers", a collapsible menu. Each menu should collapse when another menu item is expanded. With server, each titled connection should show how many active sessions there current are connected. above the terminal, there should be a horizontal scrolling tab of connections if more then 1 connect exists. The menu should include the following:
Browse files- index.html +92 -30
- script.js +50 -2
- style.css +62 -1
index.html
CHANGED
|
@@ -49,45 +49,107 @@
|
|
| 49 |
<div class="app-content flex-1 overflow-hidden">
|
| 50 |
<main class="container mx-auto px-4 py-8">
|
| 51 |
<div class="flex h-[calc(100vh-180px)] gap-6">
|
| 52 |
-
<!-- Left Sidebar -
|
| 53 |
<div class="w-64 bg-white dark:bg-gray-800 rounded-xl shadow-lg p-4 overflow-y-auto">
|
| 54 |
-
<div class="flex items-center justify-between mb-4">
|
| 55 |
-
<h2 class="text-lg font-semibold text-gray-800 dark:text-white">
|
| 56 |
-
<i data-feather="server" class="inline mr-2"></i>Servers
|
| 57 |
-
</h2>
|
| 58 |
-
<button class="p-1 bg-primary-500 hover:bg-primary-600 text-white rounded-md">
|
| 59 |
-
<i data-feather="plus" class="w-4 h-4"></i>
|
| 60 |
-
</button>
|
| 61 |
-
</div>
|
| 62 |
<div class="space-y-2">
|
| 63 |
-
<
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 67 |
</div>
|
| 68 |
-
<div class="text-xs text-gray-500 dark:text-gray-400 mt-1">prod.example.com</div>
|
| 69 |
</div>
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 74 |
</div>
|
| 75 |
-
<div class="text-xs text-gray-500 dark:text-gray-400 mt-1">ec2-54-123-45-678</div>
|
| 76 |
</div>
|
| 77 |
</div>
|
| 78 |
</div>
|
| 79 |
-
|
| 80 |
-
<!-- Main Terminal Area -->
|
| 81 |
<div class="flex-1 bg-white dark:bg-gray-800 rounded-xl shadow-lg overflow-hidden flex flex-col">
|
| 82 |
-
<!-- Terminal Header -->
|
| 83 |
-
<div class="flex
|
| 84 |
-
<div class="flex items-center">
|
| 85 |
-
<
|
| 86 |
-
<
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
|
|
|
| 91 |
<button class="p-2 bg-gray-100 hover:bg-gray-200 dark:bg-gray-700 dark:hover:bg-gray-600 rounded-md">
|
| 92 |
<i data-feather="settings" class="w-4 h-4"></i>
|
| 93 |
</button>
|
|
|
|
| 49 |
<div class="app-content flex-1 overflow-hidden">
|
| 50 |
<main class="container mx-auto px-4 py-8">
|
| 51 |
<div class="flex h-[calc(100vh-180px)] gap-6">
|
| 52 |
+
<!-- Left Sidebar - Collapsible Menu -->
|
| 53 |
<div class="w-64 bg-white dark:bg-gray-800 rounded-xl shadow-lg p-4 overflow-y-auto">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 54 |
<div class="space-y-2">
|
| 55 |
+
<!-- Servers Menu -->
|
| 56 |
+
<div class="menu-section" data-section="servers">
|
| 57 |
+
<div class="menu-header flex items-center justify-between p-2 rounded-lg cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-700">
|
| 58 |
+
<div class="flex items-center">
|
| 59 |
+
<i data-feather="server" class="w-4 h-4 mr-2"></i>
|
| 60 |
+
<span class="font-medium">Servers</span>
|
| 61 |
+
<span class="ml-2 px-1.5 py-0.5 text-xs bg-primary-500 text-white rounded-full">2</span>
|
| 62 |
+
</div>
|
| 63 |
+
<i data-feather="chevron-down" class="w-4 h-4 transform transition-transform duration-200"></i>
|
| 64 |
+
</div>
|
| 65 |
+
<div class="menu-content hidden pl-6 mt-1 space-y-1">
|
| 66 |
+
<div class="server-item p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-700 cursor-pointer flex justify-between items-center">
|
| 67 |
+
<div>
|
| 68 |
+
<div class="flex items-center">
|
| 69 |
+
<i data-feather="server" class="w-3 h-3 text-primary-500 mr-2"></i>
|
| 70 |
+
<span class="text-sm">Production</span>
|
| 71 |
+
</div>
|
| 72 |
+
<div class="text-xs text-gray-500 dark:text-gray-400 mt-1">prod.example.com</div>
|
| 73 |
+
</div>
|
| 74 |
+
<span class="px-1.5 py-0.5 text-xs bg-green-500 text-white rounded-full">1</span>
|
| 75 |
+
</div>
|
| 76 |
+
<div class="server-item p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-700 cursor-pointer flex justify-between items-center">
|
| 77 |
+
<div>
|
| 78 |
+
<div class="flex items-center">
|
| 79 |
+
<i data-feather="cloud" class="w-3 h-3 text-blue-500 mr-2"></i>
|
| 80 |
+
<span class="text-sm">AWS Instance</span>
|
| 81 |
+
</div>
|
| 82 |
+
<div class="text-xs text-gray-500 dark:text-gray-400 mt-1">ec2-54-123-45-678</div>
|
| 83 |
+
</div>
|
| 84 |
+
<span class="px-1.5 py-0.5 text-xs bg-green-500 text-white rounded-full">1</span>
|
| 85 |
+
</div>
|
| 86 |
+
<button class="w-full mt-2 text-xs flex items-center text-primary-500 hover:text-primary-700">
|
| 87 |
+
<i data-feather="plus" class="w-3 h-3 mr-1"></i> Add Server
|
| 88 |
+
</button>
|
| 89 |
</div>
|
|
|
|
| 90 |
</div>
|
| 91 |
+
|
| 92 |
+
<!-- File Transfer Menu -->
|
| 93 |
+
<div class="menu-section" data-section="transfer">
|
| 94 |
+
<div class="menu-header flex items-center justify-between p-2 rounded-lg cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-700">
|
| 95 |
+
<div class="flex items-center">
|
| 96 |
+
<i data-feather="upload" class="w-4 h-4 mr-2"></i>
|
| 97 |
+
<span class="font-medium">File Transfer</span>
|
| 98 |
+
</div>
|
| 99 |
+
<i data-feather="chevron-down" class="w-4 h-4 transform transition-transform duration-200"></i>
|
| 100 |
+
</div>
|
| 101 |
+
<div class="menu-content hidden pl-6 mt-1 space-y-1">
|
| 102 |
+
<div class="p-2 text-sm">Quick Transfer</div>
|
| 103 |
+
<div class="p-2 text-sm">Recent Files</div>
|
| 104 |
+
<div class="p-2 text-sm">Scheduled</div>
|
| 105 |
+
</div>
|
| 106 |
+
</div>
|
| 107 |
+
|
| 108 |
+
<!-- Vaults Menu -->
|
| 109 |
+
<div class="menu-section" data-section="vaults">
|
| 110 |
+
<div class="menu-header flex items-center justify-between p-2 rounded-lg cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-700">
|
| 111 |
+
<div class="flex items-center">
|
| 112 |
+
<i data-feather="lock" class="w-4 h-4 mr-2"></i>
|
| 113 |
+
<span class="font-medium">Vaults</span>
|
| 114 |
+
</div>
|
| 115 |
+
<i data-feather="chevron-down" class="w-4 h-4 transform transition-transform duration-200"></i>
|
| 116 |
+
</div>
|
| 117 |
+
<div class="menu-content hidden pl-6 mt-1 space-y-1">
|
| 118 |
+
<div class="p-2 text-sm">Credentials</div>
|
| 119 |
+
<div class="p-2 text-sm">SSH Keys</div>
|
| 120 |
+
<div class="p-2 text-sm">Certificates</div>
|
| 121 |
+
</div>
|
| 122 |
+
</div>
|
| 123 |
+
|
| 124 |
+
<!-- Settings Menu -->
|
| 125 |
+
<div class="menu-section" data-section="settings">
|
| 126 |
+
<div class="menu-header flex items-center justify-between p-2 rounded-lg cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-700">
|
| 127 |
+
<div class="flex items-center">
|
| 128 |
+
<i data-feather="settings" class="w-4 h-4 mr-2"></i>
|
| 129 |
+
<span class="font-medium">Settings</span>
|
| 130 |
+
</div>
|
| 131 |
+
<i data-feather="chevron-down" class="w-4 h-4 transform transition-transform duration-200"></i>
|
| 132 |
+
</div>
|
| 133 |
+
<div class="menu-content hidden pl-6 mt-1 space-y-1">
|
| 134 |
+
<div class="p-2 text-sm">Appearance</div>
|
| 135 |
+
<div class="p-2 text-sm">Connections</div>
|
| 136 |
+
<div class="p-2 text-sm">Security</div>
|
| 137 |
</div>
|
|
|
|
| 138 |
</div>
|
| 139 |
</div>
|
| 140 |
</div>
|
| 141 |
+
<!-- Main Terminal Area -->
|
|
|
|
| 142 |
<div class="flex-1 bg-white dark:bg-gray-800 rounded-xl shadow-lg overflow-hidden flex flex-col">
|
| 143 |
+
<!-- Terminal Header with Connection Tabs -->
|
| 144 |
+
<div class="flex flex-col border-b border-gray-200 dark:border-gray-700">
|
| 145 |
+
<div class="flex items-center justify-between p-4">
|
| 146 |
+
<div class="flex items-center">
|
| 147 |
+
<h2 class="text-xl font-semibold text-gray-800 dark:text-white">
|
| 148 |
+
<i data-feather="terminal" class="inline mr-2"></i>SSH Terminal
|
| 149 |
+
</h2>
|
| 150 |
+
<span class="ml-4 px-2 py-1 text-xs bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200 rounded-full">Connected</span>
|
| 151 |
+
</div>
|
| 152 |
+
<div class="flex space-x-2">
|
| 153 |
<button class="p-2 bg-gray-100 hover:bg-gray-200 dark:bg-gray-700 dark:hover:bg-gray-600 rounded-md">
|
| 154 |
<i data-feather="settings" class="w-4 h-4"></i>
|
| 155 |
</button>
|
script.js
CHANGED
|
@@ -17,6 +17,54 @@ function toggleDarkMode() {
|
|
| 17 |
localStorage.setItem('darkMode', isDark);
|
| 18 |
document.dispatchEvent(new CustomEvent('darkModeChange', { detail: isDark }));
|
| 19 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 20 |
|
| 21 |
// Terminal simulation (simple demo)
|
| 22 |
function simulateTerminal() {
|
|
@@ -25,7 +73,6 @@ function simulateTerminal() {
|
|
| 25 |
terminal.scrollTop = terminal.scrollHeight;
|
| 26 |
}
|
| 27 |
}
|
| 28 |
-
|
| 29 |
// Drag and drop file handling
|
| 30 |
function initFileDrop() {
|
| 31 |
const dropArea = document.querySelector('.border-dashed');
|
|
@@ -103,10 +150,11 @@ function setupWindowControls() {
|
|
| 103 |
});
|
| 104 |
}
|
| 105 |
}
|
| 106 |
-
|
| 107 |
// Initialize everything when DOM is loaded
|
| 108 |
document.addEventListener('DOMContentLoaded', () => {
|
| 109 |
initDarkMode();
|
|
|
|
|
|
|
| 110 |
simulateTerminal();
|
| 111 |
initFileDrop();
|
| 112 |
setupWindowControls();
|
|
|
|
| 17 |
localStorage.setItem('darkMode', isDark);
|
| 18 |
document.dispatchEvent(new CustomEvent('darkModeChange', { detail: isDark }));
|
| 19 |
}
|
| 20 |
+
// Collapsible Menu Functionality
|
| 21 |
+
function setupCollapsibleMenu() {
|
| 22 |
+
const menuSections = document.querySelectorAll('.menu-section');
|
| 23 |
+
|
| 24 |
+
menuSections.forEach(section => {
|
| 25 |
+
const header = section.querySelector('.menu-header');
|
| 26 |
+
const content = section.querySelector('.menu-content');
|
| 27 |
+
const chevron = header.querySelector('i[data-feather="chevron-down"]');
|
| 28 |
+
|
| 29 |
+
header.addEventListener('click', () => {
|
| 30 |
+
// Close all other sections
|
| 31 |
+
menuSections.forEach(s => {
|
| 32 |
+
if (s !== section) {
|
| 33 |
+
s.querySelector('.menu-content').classList.remove('active');
|
| 34 |
+
s.querySelector('.menu-header').classList.remove('active');
|
| 35 |
+
}
|
| 36 |
+
});
|
| 37 |
+
|
| 38 |
+
// Toggle current section
|
| 39 |
+
content.classList.toggle('active');
|
| 40 |
+
header.classList.toggle('active');
|
| 41 |
+
|
| 42 |
+
// Update chevron icon
|
| 43 |
+
if (content.classList.contains('active')) {
|
| 44 |
+
chevron.setAttribute('data-feather', 'chevron-up');
|
| 45 |
+
} else {
|
| 46 |
+
chevron.setAttribute('data-feather', 'chevron-down');
|
| 47 |
+
}
|
| 48 |
+
feather.replace();
|
| 49 |
+
});
|
| 50 |
+
});
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
// Connection Tabs Functionality
|
| 54 |
+
function setupConnectionTabs() {
|
| 55 |
+
const tabsContainer = document.querySelector('.connection-tabs');
|
| 56 |
+
if (!tabsContainer) return;
|
| 57 |
+
|
| 58 |
+
const tabs = tabsContainer.querySelectorAll('.connection-tab');
|
| 59 |
+
|
| 60 |
+
tabs.forEach(tab => {
|
| 61 |
+
tab.addEventListener('click', () => {
|
| 62 |
+
tabs.forEach(t => t.classList.remove('active'));
|
| 63 |
+
tab.classList.add('active');
|
| 64 |
+
// Here you would switch the terminal view to the selected connection
|
| 65 |
+
});
|
| 66 |
+
});
|
| 67 |
+
}
|
| 68 |
|
| 69 |
// Terminal simulation (simple demo)
|
| 70 |
function simulateTerminal() {
|
|
|
|
| 73 |
terminal.scrollTop = terminal.scrollHeight;
|
| 74 |
}
|
| 75 |
}
|
|
|
|
| 76 |
// Drag and drop file handling
|
| 77 |
function initFileDrop() {
|
| 78 |
const dropArea = document.querySelector('.border-dashed');
|
|
|
|
| 150 |
});
|
| 151 |
}
|
| 152 |
}
|
|
|
|
| 153 |
// Initialize everything when DOM is loaded
|
| 154 |
document.addEventListener('DOMContentLoaded', () => {
|
| 155 |
initDarkMode();
|
| 156 |
+
setupCollapsibleMenu();
|
| 157 |
+
setupConnectionTabs();
|
| 158 |
simulateTerminal();
|
| 159 |
initFileDrop();
|
| 160 |
setupWindowControls();
|
style.css
CHANGED
|
@@ -69,6 +69,68 @@ body {
|
|
| 69 |
background-color: #4b5563;
|
| 70 |
border-radius: 4px;
|
| 71 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 72 |
|
| 73 |
/* Sidebar styles */
|
| 74 |
.w-64 {
|
|
@@ -78,7 +140,6 @@ body {
|
|
| 78 |
.w-80 {
|
| 79 |
width: 20rem;
|
| 80 |
}
|
| 81 |
-
|
| 82 |
/* File transfer area */
|
| 83 |
.border-dashed:hover {
|
| 84 |
border-color: #6366f1;
|
|
|
|
| 69 |
background-color: #4b5563;
|
| 70 |
border-radius: 4px;
|
| 71 |
}
|
| 72 |
+
/* Collapsible Menu Styles */
|
| 73 |
+
.menu-section {
|
| 74 |
+
border-radius: 0.5rem;
|
| 75 |
+
transition: all 0.2s ease;
|
| 76 |
+
}
|
| 77 |
+
|
| 78 |
+
.menu-header {
|
| 79 |
+
transition: all 0.2s ease;
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
.menu-header.active {
|
| 83 |
+
background-color: rgba(99, 102, 241, 0.1);
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
.dark .menu-header.active {
|
| 87 |
+
background-color: rgba(99, 102, 241, 0.2);
|
| 88 |
+
}
|
| 89 |
+
|
| 90 |
+
.menu-header.active i[data-feather="chevron-down"] {
|
| 91 |
+
transform: rotate(180deg);
|
| 92 |
+
}
|
| 93 |
+
|
| 94 |
+
.menu-content {
|
| 95 |
+
transition: all 0.3s ease;
|
| 96 |
+
max-height: 0;
|
| 97 |
+
overflow: hidden;
|
| 98 |
+
}
|
| 99 |
+
|
| 100 |
+
.menu-content.active {
|
| 101 |
+
max-height: 500px;
|
| 102 |
+
display: block;
|
| 103 |
+
}
|
| 104 |
+
|
| 105 |
+
/* Connection Tabs */
|
| 106 |
+
.connection-tabs {
|
| 107 |
+
display: flex;
|
| 108 |
+
overflow-x: auto;
|
| 109 |
+
scrollbar-width: none; /* Firefox */
|
| 110 |
+
-ms-overflow-style: none; /* IE and Edge */
|
| 111 |
+
}
|
| 112 |
+
|
| 113 |
+
.connection-tabs::-webkit-scrollbar {
|
| 114 |
+
display: none; /* Chrome, Safari, Opera */
|
| 115 |
+
}
|
| 116 |
+
|
| 117 |
+
.connection-tab {
|
| 118 |
+
flex: 0 0 auto;
|
| 119 |
+
white-space: nowrap;
|
| 120 |
+
padding: 0.5rem 1rem;
|
| 121 |
+
border-bottom: 2px solid transparent;
|
| 122 |
+
transition: all 0.2s ease;
|
| 123 |
+
}
|
| 124 |
+
|
| 125 |
+
.connection-tab.active {
|
| 126 |
+
border-bottom-color: #6366f1;
|
| 127 |
+
color: #6366f1;
|
| 128 |
+
}
|
| 129 |
+
|
| 130 |
+
.dark .connection-tab.active {
|
| 131 |
+
border-bottom-color: #818cf8;
|
| 132 |
+
color: #818cf8;
|
| 133 |
+
}
|
| 134 |
|
| 135 |
/* Sidebar styles */
|
| 136 |
.w-64 {
|
|
|
|
| 140 |
.w-80 {
|
| 141 |
width: 20rem;
|
| 142 |
}
|
|
|
|
| 143 |
/* File transfer area */
|
| 144 |
.border-dashed:hover {
|
| 145 |
border-color: #6366f1;
|