Clean up dashboard ui and remove channels page

This commit is contained in:
2026-01-14 17:34:26 +01:00
parent 09810706bb
commit d43bd985c6
3 changed files with 207 additions and 209 deletions

View File

@@ -860,6 +860,17 @@ button:disabled:hover {
gap: 20px; gap: 20px;
} }
.dashboard-grid {
display: grid;
gap: 20px;
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
align-items: start;
}
.dashboard-span-full {
grid-column: 1 / -1;
}
.dashboard-topbar { .dashboard-topbar {
display: flex; display: flex;
align-items: center; align-items: center;
@@ -955,6 +966,77 @@ button:disabled:hover {
font-size: 12px; font-size: 12px;
} }
.dashboard-tile-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 12px;
margin-top: 12px;
}
.dashboard-tile {
display: flex;
flex-direction: column;
gap: 8px;
padding: 16px;
border-radius: 12px;
border: 1px solid rgba(148, 163, 184, 0.35);
background: rgba(15, 23, 42, 0.75);
color: #e2e8f0;
text-decoration: none;
min-height: 140px;
transition:
border-color 0.2s ease,
background-color 0.2s ease,
transform 0.2s ease;
}
.dashboard-tile:hover,
.dashboard-tile:focus-visible {
border-color: rgba(226, 232, 240, 0.7);
background: rgba(30, 41, 59, 0.8);
transform: translateY(-1px);
}
.dashboard-tile .tile-icon {
min-width: 44px;
height: 44px;
border-radius: 10px;
display: grid;
place-items: center;
background: rgba(124, 58, 237, 0.18);
color: #c4b5fd;
font-weight: 700;
font-size: 12px;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.dashboard-tile .tile-title {
font-weight: 600;
font-size: 15px;
}
.dashboard-tile .tile-subtitle {
color: #cbd5e1;
font-size: 12px;
line-height: 1.4;
}
.dashboard-toggle-tile {
cursor: pointer;
}
.dashboard-toggle-tile .tile-row {
display: flex;
align-items: center;
gap: 8px;
width: 100%;
}
.dashboard-toggle-tile input[type="checkbox"] {
margin-left: auto;
}
.user-display { .user-display {
font-weight: 700; font-weight: 700;
color: #e2e8f0; color: #e2e8f0;

View File

@@ -1,80 +0,0 @@
<!doctype html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8" />
<title>Browse channels - Imgfloat</title>
<link rel="icon" href="/favicon.ico" />
<link rel="stylesheet" href="/css/styles.css" />
</head>
<body class="channels-body">
<div class="channels-shell">
<header class="channels-header">
<div class="brand">
<img class="brand-mark" alt="brand" src="/img/brand.png" />
<div>
<div class="brand-title">Imgfloat</div>
<div class="brand-subtitle">Twitch overlay manager</div>
</div>
</div>
</header>
<main class="channels-main">
<section class="channel-card">
<p class="eyebrow subtle">Broadcast overlay</p>
<h1>Open a channel</h1>
<p class="muted">Type the channel name to jump straight to their overlay.</p>
<form id="channel-search-form" class="channel-form">
<label class="sr-only" for="channel-search">Channel name</label>
<input
id="channel-search"
name="channel"
class="text-input"
type="text"
list="channel-suggestions"
placeholder="Type a channel name"
autocomplete="off"
/>
<datalist id="channel-suggestions"></datalist>
<button type="submit" class="button block" onclick="onOpenOverlayButtonClick(event)">
Open overlay
</button>
</form>
</section>
</main>
<footer class="landing-meta">
<div class="build-chip">
<span class="muted">Legal</span>
<a class="version-badge version-link" href="/terms">Terms</a>
<a class="version-badge version-link" href="/privacy">Privacy</a>
<a class="version-badge version-link" href="/cookies">Cookies</a>
</div>
<div class="build-chip">
<span class="muted">License</span>
<span class="version-badge">MIT</span>
</div>
<div class="build-chip">
<span class="muted">Version</span>
<span class="version-badge" th:text="${version}">unknown</span>
</div>
<div class="build-chip" th:if="${showCommitChip}">
<span class="muted">Build</span>
<a
class="version-badge version-link"
th:if="${buildCommitUrl}"
th:href="${buildCommitUrl}"
th:text="${buildCommitShort}"
rel="noreferrer"
target="_blank"
>unknown</a
>
<span class="version-badge" th:unless="${buildCommitUrl}" th:text="${buildCommitShort}"
>unknown</span
>
</div>
</footer>
</div>
<script src="/js/cookie-consent.js"></script>
<script src="/js/channels.js"></script>
</body>
</html>

View File

@@ -29,142 +29,138 @@
</div> </div>
</header> </header>
<section class="card"> <div class="dashboard-grid">
<p class="eyebrow">Navigation</p> <section class="card">
<h3>Shortcuts</h3> <p class="eyebrow">Navigation</p>
<p class="muted">Jump into your overlay</p> <h3>Shortcuts</h3>
<div class="panel-actions"> <p class="muted">Jump into your overlay</p>
<a class="dashboard-action" th:href="@{'/view/' + ${channel} + '/broadcast'}"> <div class="dashboard-tile-grid">
<span class="dashboard-action-icon">Live</span> <a class="dashboard-tile" th:href="@{'/view/' + ${channel} + '/broadcast'}">
<span class="dashboard-action-copy"> <span class="tile-icon">Live</span>
<strong>Open broadcast overlay</strong> <span class="tile-title">Open broadcast overlay</span>
<small>Launch your live overlay view.</small> <span class="tile-subtitle">Launch your live overlay view.</span>
</span> </a>
</a> <a class="dashboard-tile" th:href="@{'/view/' + ${channel} + '/admin'}">
<a class="dashboard-action" th:href="@{'/view/' + ${channel} + '/admin'}"> <span class="tile-icon">Admin</span>
<span class="dashboard-action-icon">Admin</span> <span class="tile-title">Open admin console</span>
<span class="dashboard-action-copy"> <span class="tile-subtitle">Manage assets, scripts, and layout.</span>
<strong>Open admin console</strong> </a>
<small>Manage assets, scripts, and layout.</small> <a class="dashboard-tile" th:if="${isSystemAdmin}" href="/settings">
</span> <span class="tile-icon">App</span>
</a> <span class="tile-title">Application settings</span>
<a class="dashboard-action" th:if="${isSystemAdmin}" href="/settings"> <span class="tile-subtitle">Configure server-wide preferences.</span>
<span class="dashboard-action-icon">App</span> </a>
<span class="dashboard-action-copy"> </div>
<strong>Application settings</strong> </section>
<small>Configure server-wide preferences.</small>
</span>
</a>
<a class="dashboard-action" href="/channels">
<span class="dashboard-action-icon">Browse</span>
<span class="dashboard-action-copy">
<strong>Browse channels</strong>
<small>Find other overlays you manage.</small>
</span>
</a>
</div>
</section>
<section class="card"> <section class="card">
<p class="eyebrow">Settings</p> <p class="eyebrow">Settings</p>
<h3>Overlay dimensions</h3> <h3>Overlay dimensions</h3>
<p class="muted">Match these with your OBS resolution.</p> <p class="muted">Match these with your OBS resolution.</p>
<div class="control-grid"> <div class="control-grid">
<label> <label>
Width Width
<input id="canvas-width" type="number" min="100" step="10" /> <input id="canvas-width" type="number" min="100" step="10" />
</label> </label>
<label> <label>
Height Height
<input id="canvas-height" type="number" min="100" step="10" /> <input id="canvas-height" type="number" min="100" step="10" />
</label> </label>
</div> </div>
<div class="control-actions"> <div class="control-actions">
<button id="save-canvas-btn" type="button" onclick="saveCanvasSettings()">Save canvas size</button> <button id="save-canvas-btn" type="button" onclick="saveCanvasSettings()">Save canvas size</button>
<span id="canvas-status" class="muted" role="status" aria-live="polite"></span> <span id="canvas-status" class="muted" role="status" aria-live="polite"></span>
</div> </div>
</section> </section>
<section class="card"> <section class="card">
<p class="eyebrow">Script privacy</p> <p class="eyebrow">Script privacy</p>
<h3>Script asset access</h3> <h3>Script asset access</h3>
<p class="muted">Control what data scripts can access in your channel.</p> <p class="muted">Control what data scripts can access in your channel.</p>
<div class="control-grid"> <div class="dashboard-tile-grid">
<label class="checkbox-row"> <label class="dashboard-tile dashboard-toggle-tile">
<input id="allow-channel-emotes" type="checkbox" checked /> <div class="tile-row">
Allow script assets to use this channel's Twitch emotes. <span class="tile-title">Twitch emotes</span>
</label> <input id="allow-channel-emotes" type="checkbox" checked />
<label class="checkbox-row"> </div>
<input id="allow-7tv-emotes" type="checkbox" checked /> <span class="tile-subtitle">Allow script assets to use this channel's Twitch emotes.</span>
Allow script assets to use this channel's 7TV emotes. </label>
</label> <label class="dashboard-tile dashboard-toggle-tile">
<label class="checkbox-row"> <div class="tile-row">
<input id="allow-script-chat" type="checkbox" checked /> <span class="tile-title">7TV emotes</span>
Allow script assets to access this channel's Twitch chat log. <input id="allow-7tv-emotes" type="checkbox" checked />
</label> </div>
</div> <span class="tile-subtitle">Allow script assets to use this channel's 7TV emotes.</span>
<div class="control-actions"> </label>
<button id="save-script-settings-btn" type="button" onclick="saveScriptSettings()"> <label class="dashboard-tile dashboard-toggle-tile">
Save script settings <div class="tile-row">
</button> <span class="tile-title">Chat access</span>
<span id="script-settings-status" class="muted" role="status" aria-live="polite"></span> <input id="allow-script-chat" type="checkbox" checked />
</div> </div>
</section> <span class="tile-subtitle">Allow script assets to access this channel's Twitch chat log.</span>
</label>
</div>
<div class="control-actions">
<button id="save-script-settings-btn" type="button" onclick="saveScriptSettings()">
Save script settings
</button>
<span id="script-settings-status" class="muted" role="status" aria-live="polite"></span>
</div>
</section>
<section class="card-grid two-col"> <section class="card-grid two-col dashboard-span-full">
<div class="card"> <div class="card">
<div class="card-header">
<div>
<p class="eyebrow">Collaboration</p>
<h3>Channel admins</h3>
<p class="muted">Invite moderators to help manage assets.</p>
</div>
</div>
<div class="inline-form">
<div class="field-stack">
<input id="new-admin" placeholder="Twitch username" autocomplete="off" />
<span class="form-helper">Enter the username without the @ symbol.</span>
</div>
<button id="add-admin-btn" type="button" onclick="addAdmin()">Add admin</button>
</div>
<div class="card-section">
<div class="section-header">
<h4 class="list-title">Channel Admins</h4>
<p class="muted">Users who can currently modify your overlay.</p>
</div>
<ul id="admin-list" class="stacked-list"></ul>
</div>
<div class="card-section">
<div class="section-header">
<h4 class="list-title">Your Twitch moderators</h4>
<p class="muted">Add moderators who already help run your channel.</p>
</div>
<ul id="admin-suggestions" class="stacked-list"></ul>
</div>
</div>
</section>
<section th:if="${adminChannels != null}" class="card dashboard-span-full">
<div class="card-header"> <div class="card-header">
<div> <div>
<p class="eyebrow">Collaboration</p> <p class="eyebrow">Your access</p>
<h3>Channel admins</h3> <h3>Channels you administer</h3>
<p class="muted">Invite moderators to help manage assets.</p> <p class="muted">Jump into a teammate's overlay console.</p>
</div> </div>
</div> </div>
<div class="inline-form"> <p th:if="${#lists.isEmpty(adminChannels)}">No admin invitations yet.</p>
<div class="field-stack"> <ul th:if="${!#lists.isEmpty(adminChannels)}" class="stacked-list">
<input id="new-admin" placeholder="Twitch username" autocomplete="off" /> <li th:each="channelName : ${adminChannels}" class="stacked-list-item">
<span class="form-helper">Enter the username without the @ symbol.</span> <div>
</div> <p class="list-title" th:text="${channelName}">channel</p>
<button id="add-admin-btn" type="button" onclick="addAdmin()">Add admin</button> <p class="muted">Channel admin access</p>
</div> </div>
<div class="card-section"> <a class="button ghost" th:href="@{'/view/' + ${channelName} + '/admin'}">Open</a>
<div class="section-header"> </li>
<h4 class="list-title">Channel Admins</h4> </ul>
<p class="muted">Users who can currently modify your overlay.</p> </section>
</div> </div>
<ul id="admin-list" class="stacked-list"></ul>
</div>
<div class="card-section">
<div class="section-header">
<h4 class="list-title">Your Twitch moderators</h4>
<p class="muted">Add moderators who already help run your channel.</p>
</div>
<ul id="admin-suggestions" class="stacked-list"></ul>
</div>
</div>
</section>
<section th:if="${adminChannels != null}" class="card">
<div class="card-header">
<div>
<p class="eyebrow">Your access</p>
<h3>Channels you administer</h3>
<p class="muted">Jump into a teammate's overlay console.</p>
</div>
</div>
<p th:if="${#lists.isEmpty(adminChannels)}">No admin invitations yet.</p>
<ul th:if="${!#lists.isEmpty(adminChannels)}" class="stacked-list">
<li th:each="channelName : ${adminChannels}" class="stacked-list-item">
<div>
<p class="list-title" th:text="${channelName}">channel</p>
<p class="muted">Channel admin access</p>
</div>
<a class="button ghost" th:href="@{'/view/' + ${channelName} + '/admin'}">Open</a>
</li>
</ul>
</section>
<section class="card download-card-block" th:insert="~{fragments/downloads :: downloads}"></section>
</div> </div>
<script src="/js/cookie-consent.js"></script> <script src="/js/cookie-consent.js"></script>
<script src="/js/csrf.js"></script> <script src="/js/csrf.js"></script>