Update UI for palettes, presets, and patterns

This commit is contained in:
2026-01-16 22:31:36 +13:00
parent 9c43a0a22b
commit df37f15f73
8 changed files with 3649 additions and 11 deletions

View File

@@ -1,14 +1,295 @@
<!doctype html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>RGB Slider Tabs</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<div class="tabs"></div>
<div class="tab-content"></div>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LED Controller - Tab Mode</title>
<link rel="stylesheet" href="/static/style.css">
<script src="/static/htmx.min.js"></script>
</head>
<body>
<div class="app-container">
<header>
<h1>LED Controller - Tab Mode</h1>
<div class="header-actions">
<button class="btn btn-primary"
hx-get="/tabs/create-form-fragment"
hx-target="#add-tab-modal .modal-content"
hx-swap="innerHTML"
onclick="document.getElementById('add-tab-modal').classList.add('active')">
+ Add Tab
</button>
<button class="btn btn-secondary" id="edit-tab-btn">Edit Tab</button>
<button class="btn btn-danger"
hx-delete="/tabs/current"
hx-target="#tabs-list"
hx-swap="innerHTML"
hx-headers='{"Accept": "text/html"}'
hx-confirm="Are you sure you want to delete this tab?">
Delete Tab
</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>
</div>
</header>
<script type="module" src="main.js"></script>
</body>
<div class="main-content">
<div class="tabs-container">
<div id="tabs-list"
hx-get="/tabs/list-fragment"
hx-trigger="load, tabs-updated from:body"
hx-swap="innerHTML">
Loading tabs...
</div>
</div>
<div id="tab-content"
class="tab-content"
hx-get="/tabs/current"
hx-trigger="load, tabs-updated from:body"
hx-swap="innerHTML"
hx-headers='{"Accept": "text/html"}'>
<div style="padding: 2rem; text-align: center; color: #aaa;">
Select a tab to get started
</div>
</div>
</div>
</div>
<!-- Add Tab Modal -->
<div id="add-tab-modal" class="modal">
<div class="modal-content">
<h2>Add New Tab</h2>
<form hx-post="/tabs"
hx-target="#tabs-list"
hx-swap="innerHTML"
hx-headers='{"Accept": "text/html"}'
hx-on::after-request="if(event.detail.successful) { document.getElementById('add-tab-modal').classList.remove('active'); document.body.dispatchEvent(new Event('tabs-updated')); }">
<label>Tab Name:</label>
<input type="text" name="name" placeholder="Enter tab name" required>
<label>Device IDs (comma-separated):</label>
<input type="text" name="ids" placeholder="1,2,3" value="1">
<div class="modal-actions">
<button type="submit" class="btn btn-primary">Add</button>
<button type="button" class="btn btn-secondary" onclick="document.getElementById('add-tab-modal').classList.remove('active')">Cancel</button>
</div>
</form>
</div>
</div>
<!-- Edit Tab Modal (placeholder for now) -->
<div id="edit-tab-modal" class="modal">
<div class="modal-content">
<h2>Edit Tab</h2>
<p>Edit functionality coming soon...</p>
<div class="modal-actions">
<button class="btn btn-secondary" onclick="document.getElementById('edit-tab-modal').classList.remove('active')">Close</button>
</div>
</div>
</div>
<!-- Profiles Modal -->
<div id="profiles-modal" class="modal">
<div class="modal-content">
<h2>Profiles</h2>
<div class="profiles-actions">
<input type="text" id="new-profile-name" placeholder="Profile name">
<button class="btn btn-primary" id="create-profile-btn">Create</button>
</div>
<div id="profiles-list" class="profiles-list"></div>
<div class="modal-actions">
<button class="btn btn-secondary" id="profiles-close-btn">Close</button>
</div>
</div>
</div>
<!-- Presets Modal -->
<div id="presets-modal" class="modal">
<div class="modal-content">
<h2>Presets</h2>
<div class="modal-actions">
<button class="btn btn-primary" id="preset-add-btn">Add</button>
</div>
<div id="presets-list" class="profiles-list"></div>
<div class="modal-actions">
<button class="btn btn-secondary" id="presets-close-btn">Close</button>
</div>
</div>
</div>
<!-- Preset Editor Modal -->
<div id="preset-editor-modal" class="modal">
<div class="modal-content">
<h2>Preset</h2>
<div class="profiles-actions">
<input type="text" id="preset-name-input" placeholder="Preset name">
<select id="preset-pattern-input">
<option value="">Pattern</option>
</select>
</div>
<label>Colors (comma-separated hex)</label>
<div class="profiles-actions">
<input type="text" id="preset-colors-input" placeholder="#FF0000,#00FF00,#0000FF">
<button class="btn btn-secondary" id="preset-add-from-palette-btn">Add from Palette</button>
</div>
<div class="profiles-actions">
<input type="number" id="preset-brightness-input" placeholder="Brightness" min="0" max="255" value="0">
<input type="number" id="preset-delay-input" placeholder="Delay" min="0" max="10000" value="0">
</div>
<div class="n-params-grid">
<div class="n-param-group">
<label for="preset-n1-input" id="preset-n1-label">n1:</label>
<input type="number" id="preset-n1-input" min="0" max="255" value="0" class="n-input">
</div>
<div class="n-param-group">
<label for="preset-n2-input" id="preset-n2-label">n2:</label>
<input type="number" id="preset-n2-input" min="0" max="255" value="0" class="n-input">
</div>
<div class="n-param-group">
<label for="preset-n3-input" id="preset-n3-label">n3:</label>
<input type="number" id="preset-n3-input" min="0" max="255" value="0" class="n-input">
</div>
<div class="n-param-group">
<label for="preset-n4-input" id="preset-n4-label">n4:</label>
<input type="number" id="preset-n4-input" min="0" max="255" value="0" class="n-input">
</div>
<div class="n-param-group">
<label for="preset-n5-input" id="preset-n5-label">n5:</label>
<input type="number" id="preset-n5-input" min="0" max="255" value="0" class="n-input">
</div>
<div class="n-param-group">
<label for="preset-n6-input" id="preset-n6-label">n6:</label>
<input type="number" id="preset-n6-input" min="0" max="255" value="0" class="n-input">
</div>
<div class="n-param-group">
<label for="preset-n7-input" id="preset-n7-label">n7:</label>
<input type="number" id="preset-n7-input" min="0" max="255" value="0" class="n-input">
</div>
<div class="n-param-group">
<label for="preset-n8-input" id="preset-n8-label">n8:</label>
<input type="number" id="preset-n8-input" min="0" max="255" value="0" class="n-input">
</div>
</div>
<div class="modal-actions">
<button class="btn btn-primary" id="preset-save-btn">Save</button>
<button class="btn btn-secondary" id="preset-clear-btn">Clear</button>
<button class="btn btn-secondary" id="preset-editor-close-btn">Close</button>
</div>
</div>
</div>
<!-- Patterns Modal -->
<div id="patterns-modal" class="modal">
<div class="modal-content">
<h2>Patterns</h2>
<div id="patterns-list" class="profiles-list"></div>
<div class="modal-actions">
<button class="btn btn-secondary" id="patterns-close-btn">Close</button>
</div>
</div>
</div>
<!-- Color Palette Modal -->
<div id="color-palette-modal" class="modal">
<div class="modal-content">
<h2>Color Palette</h2>
<p class="muted-text">Profile: <span id="palette-current-profile-name">None</span></p>
<div id="palette-container" class="profiles-list"></div>
<div class="profiles-actions">
<input type="color" id="palette-new-color" value="#ffffff">
<button class="btn btn-primary" id="palette-add-color-btn">Add Color</button>
</div>
<div class="modal-actions">
<button class="btn btn-secondary" id="color-palette-close-btn">Close</button>
</div>
</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;
}
.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;
}
</style>
<script src="/static/color_palette.js"></script>
<script src="/static/profiles.js"></script>
<script src="/static/tab_palette.js"></script>
<script src="/static/patterns.js"></script>
<script src="/static/presets.js"></script>
</body>
</html>