Refresh tabs/presets UI and add a mobile menu.
This improves navigation and profile workflows on smaller screens. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -9,27 +9,39 @@
|
||||
<body>
|
||||
<div class="app-container">
|
||||
<header>
|
||||
<h1>LED Controller - Tab Mode</h1>
|
||||
<div class="header-actions">
|
||||
<button class="btn btn-secondary" id="tabs-btn">Tabs</button>
|
||||
<button class="btn btn-secondary" id="color-palette-btn">Color Palette</button>
|
||||
<button class="btn btn-secondary" id="presets-btn">Presets</button>
|
||||
<button class="btn btn-secondary" id="patterns-btn">Patterns</button>
|
||||
<button class="btn btn-secondary" id="profiles-btn">Profiles</button>
|
||||
<button class="btn btn-secondary" id="settings-btn">Settings</button>
|
||||
<button class="btn btn-secondary" id="help-btn">Help</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="main-content">
|
||||
<div class="tabs-container">
|
||||
<div id="tabs-list">
|
||||
Loading tabs...
|
||||
</div>
|
||||
</div>
|
||||
<div class="header-actions">
|
||||
<button class="btn btn-secondary" id="tabs-btn">Tabs</button>
|
||||
<button class="btn btn-secondary" id="color-palette-btn">Color Palette</button>
|
||||
<button class="btn btn-secondary" id="presets-btn">Presets</button>
|
||||
<button class="btn btn-secondary" id="send-profile-presets-btn">Send Presets</button>
|
||||
<button class="btn btn-secondary" id="patterns-btn">Patterns</button>
|
||||
<button class="btn btn-secondary" id="profiles-btn">Profiles</button>
|
||||
<button class="btn btn-secondary" id="settings-btn">Settings</button>
|
||||
<button class="btn btn-secondary" id="help-btn">Help</button>
|
||||
</div>
|
||||
<div class="header-menu-mobile">
|
||||
<button class="btn btn-secondary" id="main-menu-btn">Menu</button>
|
||||
<div id="main-menu-dropdown" class="main-menu-dropdown">
|
||||
<button type="button" data-target="tabs-btn">Tabs</button>
|
||||
<button type="button" data-target="color-palette-btn">Color Palette</button>
|
||||
<button type="button" data-target="presets-btn">Presets</button>
|
||||
<button type="button" data-target="send-profile-presets-btn">Send Presets</button>
|
||||
<button type="button" data-target="patterns-btn">Patterns</button>
|
||||
<button type="button" data-target="profiles-btn">Profiles</button>
|
||||
<button type="button" data-target="settings-btn">Settings</button>
|
||||
<button type="button" data-target="help-btn">Help</button>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="main-content">
|
||||
<div id="tab-content" class="tab-content">
|
||||
<div style="padding: 2rem; text-align: center; color: #aaa;">
|
||||
<div class="tab-content-placeholder">
|
||||
Select a tab to get started
|
||||
</div>
|
||||
</div>
|
||||
@@ -58,14 +70,16 @@
|
||||
<h2>Edit Tab</h2>
|
||||
<form id="edit-tab-form">
|
||||
<input type="hidden" id="edit-tab-id">
|
||||
<div class="modal-actions" style="margin-bottom: 1rem;">
|
||||
<button type="submit" class="btn btn-primary">Save</button>
|
||||
<button type="button" class="btn btn-secondary" onclick="document.getElementById('edit-tab-modal').classList.remove('active')">Close</button>
|
||||
</div>
|
||||
<label>Tab Name:</label>
|
||||
<input type="text" id="edit-tab-name" placeholder="Enter tab name" required>
|
||||
<label>Device IDs (comma-separated):</label>
|
||||
<input type="text" id="edit-tab-ids" placeholder="1,2,3" required>
|
||||
<div class="modal-actions">
|
||||
<button type="submit" class="btn btn-primary">Save</button>
|
||||
<button type="button" class="btn btn-secondary" onclick="document.getElementById('edit-tab-modal').classList.remove('active')">Cancel</button>
|
||||
</div>
|
||||
<label style="margin-top: 1rem;">Add presets to this tab</label>
|
||||
<div id="edit-tab-presets-list" class="profiles-list" style="max-height: 200px; overflow-y: auto; margin-bottom: 1rem;"></div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@@ -111,17 +125,17 @@
|
||||
</div>
|
||||
<label>Colors</label>
|
||||
<div id="preset-colors-container" class="preset-colors-container"></div>
|
||||
<div class="profiles-actions" style="margin-top: 0.5rem;">
|
||||
<div class="profiles-actions">
|
||||
<input type="color" id="preset-new-color" value="#ffffff">
|
||||
<button class="btn btn-secondary btn-small" id="preset-add-color-btn">Add Color</button>
|
||||
<button class="btn btn-secondary btn-small" id="preset-add-from-palette-btn">Add from Palette</button>
|
||||
</div>
|
||||
<div class="profiles-actions">
|
||||
<div style="flex: 1; display: flex; flex-direction: column;">
|
||||
<div class="preset-editor-field">
|
||||
<label for="preset-brightness-input">Brightness (0–255)</label>
|
||||
<input type="number" id="preset-brightness-input" placeholder="Brightness" min="0" max="255" value="0">
|
||||
</div>
|
||||
<div style="flex: 1; display: flex; flex-direction: column;">
|
||||
<div class="preset-editor-field">
|
||||
<label for="preset-delay-input">Delay (ms)</label>
|
||||
<input type="number" id="preset-delay-input" placeholder="Delay" min="0" max="10000" value="0">
|
||||
</div>
|
||||
@@ -207,7 +221,7 @@
|
||||
<ul>
|
||||
<li><strong>Select tab</strong>: left-click a tab button in the top bar.</li>
|
||||
<li><strong>Edit tab</strong>: right-click a tab button, or click <strong>Edit</strong> in the Tabs modal.</li>
|
||||
<li><strong>Send all presets</strong>: use the <strong>Send Presets</strong> button in the tab header to push every preset used in that tab to all devices.</li>
|
||||
<li><strong>Send all presets</strong>: open the <strong>Tabs</strong> menu and click <strong>Send Presets</strong> next to the tab to push every preset used in that tab to all devices.</li>
|
||||
</ul>
|
||||
|
||||
<h3>Presets in a tab</h3>
|
||||
@@ -233,11 +247,11 @@
|
||||
|
||||
<!-- Settings Modal -->
|
||||
<div id="settings-modal" class="modal">
|
||||
<div class="modal-content" style="max-width: 900px; max-height: 90vh; overflow-y: auto;">
|
||||
<div class="modal-content">
|
||||
<h2>Device Settings</h2>
|
||||
<p class="muted-text" style="margin-bottom: 1rem;">Configure WiFi and device settings.</p>
|
||||
<p class="muted-text">Configure WiFi and device settings.</p>
|
||||
|
||||
<div id="settings-message" class="message" style="display:none;"></div>
|
||||
<div id="settings-message" class="message"></div>
|
||||
|
||||
<!-- Device Name -->
|
||||
<div class="settings-section">
|
||||
@@ -297,7 +311,7 @@
|
||||
</div>
|
||||
|
||||
<!-- WiFi Access Point Settings -->
|
||||
<div class="settings-section" style="margin-top: 1.5rem;">
|
||||
<div class="settings-section ap-settings-section">
|
||||
<h3>WiFi Access Point</h3>
|
||||
|
||||
<div id="ap-status" class="status-info">
|
||||
@@ -336,180 +350,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.modal {
|
||||
display: none;
|
||||
position: fixed;
|
||||
z-index: 1000;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0,0,0,0.7);
|
||||
}
|
||||
.modal.active {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.modal-content {
|
||||
background-color: #2e2e2e;
|
||||
padding: 2rem;
|
||||
border-radius: 8px;
|
||||
min-width: 400px;
|
||||
max-width: 600px;
|
||||
}
|
||||
.modal-content label {
|
||||
display: block;
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
.modal-content input[type="text"] {
|
||||
width: 100%;
|
||||
padding: 0.5rem;
|
||||
background-color: #3a3a3a;
|
||||
border: 1px solid #4a4a4a;
|
||||
border-radius: 4px;
|
||||
color: white;
|
||||
}
|
||||
.profiles-actions {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
.profiles-actions input[type="text"] {
|
||||
flex: 1;
|
||||
}
|
||||
.profiles-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
margin-top: 1rem;
|
||||
max-height: 50vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.profiles-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 0.5rem;
|
||||
padding: 0.5rem;
|
||||
background-color: #3a3a3a;
|
||||
border-radius: 4px;
|
||||
}
|
||||
/* Hide any text content in palette rows - only show color swatches */
|
||||
#palette-container .profiles-row {
|
||||
font-size: 0; /* Hide any text nodes */
|
||||
}
|
||||
#palette-container .profiles-row > * {
|
||||
font-size: 1rem; /* Restore font size for buttons */
|
||||
}
|
||||
#palette-container .profiles-row > span:not(.btn),
|
||||
#palette-container .profiles-row > label,
|
||||
#palette-container .profiles-row::before,
|
||||
#palette-container .profiles-row::after {
|
||||
display: none !important;
|
||||
content: none !important;
|
||||
}
|
||||
/* Preset colors container */
|
||||
#preset-colors-container {
|
||||
min-height: 80px;
|
||||
padding: 0.5rem;
|
||||
background-color: #2a2a2a;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
#preset-colors-container .muted-text {
|
||||
color: #888;
|
||||
font-size: 0.9rem;
|
||||
padding: 1rem;
|
||||
text-align: center;
|
||||
}
|
||||
.muted-text {
|
||||
text-align: center;
|
||||
color: #888;
|
||||
}
|
||||
.modal-actions {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
margin-top: 1.5rem;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.error {
|
||||
color: #d32f2f;
|
||||
padding: 0.5rem;
|
||||
background-color: #3a1a1a;
|
||||
border-radius: 4px;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
/* Drag and drop styles for presets */
|
||||
.draggable-preset {
|
||||
cursor: move;
|
||||
transition: opacity 0.2s, transform 0.2s;
|
||||
}
|
||||
.draggable-preset.dragging {
|
||||
opacity: 0.5;
|
||||
transform: scale(0.95);
|
||||
}
|
||||
.draggable-preset:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
/* Drag and drop styles for color swatches */
|
||||
.draggable-color-swatch {
|
||||
transition: opacity 0.2s, transform 0.2s;
|
||||
}
|
||||
.draggable-color-swatch.dragging-color {
|
||||
opacity: 0.5;
|
||||
transform: scale(0.9);
|
||||
}
|
||||
.draggable-color-swatch.drag-over-color {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
.color-swatches-container {
|
||||
min-height: 80px;
|
||||
}
|
||||
/* Ensure presets list uses grid layout */
|
||||
#presets-list-tab {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
|
||||
gap: 0.75rem;
|
||||
width: 100%;
|
||||
}
|
||||
/* Help modal readability */
|
||||
#help-modal .modal-content {
|
||||
max-width: 720px;
|
||||
line-height: 1.6;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
#help-modal .modal-content h2 {
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
#help-modal .modal-content h3 {
|
||||
margin-top: 1.25rem;
|
||||
margin-bottom: 0.4rem;
|
||||
font-size: 1.05rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
#help-modal .modal-content p {
|
||||
text-align: left;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
#help-modal .modal-content ul {
|
||||
margin-top: 0.25rem;
|
||||
margin-left: 1.25rem;
|
||||
padding-left: 0;
|
||||
text-align: left;
|
||||
}
|
||||
#help-modal .modal-content li {
|
||||
margin: 0.2rem 0;
|
||||
line-height: 1.5;
|
||||
}
|
||||
#help-modal .muted-text {
|
||||
text-align: left;
|
||||
color: #bbb;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
</style>
|
||||
<!-- Styles moved to /static/style.css -->
|
||||
<script src="/static/tabs.js"></script>
|
||||
<script src="/static/help.js"></script>
|
||||
<script src="/static/color_palette.js"></script>
|
||||
|
||||
Reference in New Issue
Block a user