DRY pass #3: one one-time secret reveal (#5373)

AccountView's device-token reveal was OneTimeLink's markup and copy handler
again. OneTimeLink becomes OneTimeSecret (value, note, noun = link | token),
and the account page shows a new token through it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-08 15:13:18 -04:00
co-authored by Claude Opus 5.5
parent a0249564e2
commit 498b23789c
4 changed files with 36 additions and 56 deletions
+8 -39
View File
@@ -8,6 +8,7 @@ import BaseButton from "../components/BaseButton.vue";
import BaseInput from "../components/BaseInput.vue";
import ClientDownloads from "../components/ClientDownloads.vue";
import Icon from "../components/Icon.vue";
import OneTimeSecret from "../components/OneTimeSecret.vue";
import PageHeader from "../components/PageHeader.vue";
import { errorMessage } from "../api/errors";
import { formatDateTime } from "../notes/datetime";
@@ -71,15 +72,6 @@ async function link() {
}
}
async function copyToken() {
try {
await navigator.clipboard.writeText(freshToken.value);
ui.showToast("Token copied to clipboard.");
} catch {
ui.showToast("Couldn't copy — select and copy it manually.");
}
}
async function revoke(id: string, name: string) {
if (!window.confirm(`Revoke "${name}"? That device will need to link again to sync.`)) return;
try {
@@ -147,37 +139,14 @@ onMounted(() => {
Hides itself when the server holds none. -->
<ClientDownloads />
<!-- One-time token reveal -->
<div
<OneTimeSecret
v-if="freshToken"
class="mb-6 rounded-xl border border-brand/40 bg-brand/5 p-4 dark:border-brand/30 dark:bg-brand/10"
>
<p class="text-sm font-medium text-neutral-800 dark:text-neutral-100">
Copy this token now — it won't be shown again.
</p>
<div class="mt-2 flex items-center gap-2">
<code
class="min-w-0 flex-1 overflow-x-auto rounded-lg border border-neutral-300 bg-white px-3 py-2 font-mono text-xs text-neutral-900 dark:border-neutral-700 dark:bg-neutral-900 dark:text-neutral-100"
>{{ freshToken }}</code
>
<button
type="button"
class="icon-btn shrink-0"
title="Copy token"
aria-label="Copy token"
@click="copyToken"
>
<Icon name="copy" />
</button>
</div>
<button
type="button"
class="mt-3 text-xs text-neutral-500 underline hover:text-neutral-700 dark:hover:text-neutral-300"
@click="freshToken = ''"
>
Done
</button>
</div>
class="mb-6"
:value="freshToken"
noun="token"
note="This device's token."
@done="freshToken = ''"
/>
<!-- Create a device token -->
<form class="mb-8 flex items-end gap-3" @submit.prevent="link">