commit 1adecb53033738b99c90ce5e029606f87c9edc60
parent dde33033343519bde55f6d2ab3c93d30aa7eb8ae
Author: David Eisinger <[email protected]>
Date: Mon, 6 Oct 2025 22:54:30 -0400
UI tweaks
Diffstat:
3 files changed, 28 insertions(+), 13 deletions(-)
diff --git a/internal/web/app.js b/internal/web/app.js
@@ -14,7 +14,7 @@ createApp({
me: null,
viewUser: '',
auth: { username: '', password: '' },
- api: { present: false, value: '', show: false, busy: false },
+ api: { present: false, value: '', show: false, busy: false, copied: false },
};
},
mounted() {
@@ -64,6 +64,7 @@ createApp({
this.api.present = true;
this.api.value = data.api_token || '';
this.api.show = true;
+ this.api.copied = false;
} catch {}
this.api.busy = false;
},
@@ -76,12 +77,22 @@ createApp({
this.api.present = true;
this.api.value = data.api_token || '';
this.api.show = true;
+ this.api.copied = false;
} catch {}
this.api.busy = false;
},
async regenerateApiKey() {
await this.generateApiKey();
},
+ async copyApiKey() {
+ try {
+ await navigator.clipboard.writeText(this.api.value || '');
+ this.api.copied = true;
+ setTimeout(() => { this.api.copied = false; }, 1500);
+ } catch (e) {
+ alert('Failed to copy token');
+ }
+ },
async login() {
this.error = '';
this.busy = true;
diff --git a/internal/web/index.html b/internal/web/index.html
@@ -16,9 +16,11 @@
</div>
<nav class="top-links">
<template v-if="me && me.username">
- <span>Logged in as {{ me.username }}</span>
- <span class="sep">|</span>
- <a href="#" @click.prevent="logout">Log out</a>
+ <div class="user-line">
+ <span>Logged in as {{ me.username }}</span>
+ <span class="sep">|</span>
+ <a href="#" @click.prevent="logout">Log out</a>
+ </div>
<div class="api-key">
<template v-if="api.present">
API Token:
@@ -30,6 +32,9 @@
<template v-else>
<code class="token">{{ api.value }}</code>
<span class="sep">|</span>
+ <span v-if="api.copied">copied!</span>
+ <a v-else href="#" @click.prevent="copyApiKey">copy</a>
+ <span class="sep">|</span>
<a href="#" @click.prevent="regenerateApiKey">regenerate</a>
</template>
</template>
@@ -90,7 +95,6 @@
<button :disabled="busy">{{ busy ? 'Working…' : 'Save' }}</button>
<p v-if="error" class="error">{{ error }}</p>
<p v-if="message" class="ok">{{ message }}</p>
- <p class="auth-links"><a href="#" @click.prevent="logout">Logout</a></p>
</form>
</section>
diff --git a/internal/web/styles.css b/internal/web/styles.css
@@ -8,15 +8,14 @@ h1 { margin: 0 0 4px 0; font-size: 24px; }
.container h1 a { color: inherit; text-decoration: none; }
.container h1 a:hover { text-decoration: underline; }
.muted { color: #666; margin: 0 0 8px 0; font-size: 13px; }
-.top-links { align-self: start; font-size: 13px; color: #555; }
-.top-links a { color: inherit; text-decoration: none; }
-.top-links a:hover { text-decoration: underline; }
+.top-links { align-self: start; font-size: 13px; color: #555; display: flex; flex-direction: column; align-items: flex-end; text-align: right; }
+.top-links .user-line { white-space: nowrap; }
+.top-links a { color: inherit; }
.top-links .sep { margin: 0 6px; opacity: 0.6; }
-.top-links .api-key { margin-top: 4px; font-size: 12px; color: #666; }
+.top-links .api-key { margin-top: 10px; font-size: 12px; color: #666; }
.top-links .api-key .token { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; font-size: 12px; }
.small-links { font-size: 12px; margin-left: 8px; color: #666; }
-.small-links a { color: inherit; text-decoration: none; }
-.small-links a:hover { text-decoration: underline; }
+.small-links a { color: inherit; }
.small-links .sep { margin: 0 6px; opacity: 0.6; }
.grid { display: grid; grid-template-columns: 1fr 2fr; gap: 24px; align-items: start; }
@media (max-width: 800px) { .grid { grid-template-columns: 1fr; } }
@@ -41,11 +40,12 @@ button { padding: 8px 12px; font-size: 14px; border-radius: 6px; border: 1px sol
.edit-form .actions { display: flex; gap: 8px; }
.url { color: #666; font-size: 12px; margin: 0 0 6px 0; word-break: break-all; }
.action-links { margin: 6px 0 0 0; font-size: 13px; color: #555; }
-.action-links a { color: inherit; text-decoration: none; }
-.action-links a:hover { text-decoration: underline; }
+.action-links a { color: inherit; }
.action-links .sep { margin: 0 6px; opacity: 0.6; }
.excerpt { margin: 6px 0; white-space: pre-wrap; }
mark { background: #fff3b0; color: inherit; padding: 0 2px; border-radius: 2px; }
.meta { color: #777; font-size: 12px; margin: 8px 0 0 0; }
.desc { margin: 6px 0 0; color: #444; }
.auth-links { margin-top: 8px; font-size: 13px; }
+/* Underline all links globally */
+a { text-decoration: underline; }