Spaces:
Paused
Paused
icebear0828 Claude Opus 4.6 commited on
Commit ·
90172f5
1
Parent(s): bb065fa
ui: replace icon font + Google Fonts with inline SVGs and system fonts
Browse filesEliminates all Google Fonts CDN dependencies (Material Symbols, Inter,
JetBrains Mono) to remove FOUC entirely. Icons are now inline SVGs that
render instantly; text uses system font stack.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- public/dashboard.html +24 -26
public/dashboard.html
CHANGED
|
@@ -4,8 +4,6 @@
|
|
| 4 |
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
|
| 5 |
<title>Codex Proxy Developer Dashboard</title>
|
| 6 |
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
|
| 7 |
-
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet"/>
|
| 8 |
-
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
| 9 |
<script>
|
| 10 |
tailwind.config = {
|
| 11 |
darkMode: "class",
|
|
@@ -22,8 +20,8 @@
|
|
| 22 |
"text-dim": "#8b949e",
|
| 23 |
},
|
| 24 |
fontFamily: {
|
| 25 |
-
"display": ["
|
| 26 |
-
"mono": ["
|
| 27 |
},
|
| 28 |
borderRadius: {"DEFAULT": "0.25rem", "lg": "0.5rem", "xl": "0.75rem", "full": "9999px"},
|
| 29 |
},
|
|
@@ -34,10 +32,6 @@
|
|
| 34 |
:root { --primary: 16 162 53; --primary-hover: 14 140 46; }
|
| 35 |
.dark { --primary: 16 163 127; --primary-hover: 14 140 108; }
|
| 36 |
|
| 37 |
-
/* Hide icon ligature text until font loads */
|
| 38 |
-
.material-symbols-outlined { opacity: 0; }
|
| 39 |
-
.fonts-ready .material-symbols-outlined { opacity: 1; transition: opacity 0.15s; }
|
| 40 |
-
|
| 41 |
/* Dark scrollbar for code blocks */
|
| 42 |
pre::-webkit-scrollbar { height: 8px; }
|
| 43 |
pre::-webkit-scrollbar-track { background: #0d1117; }
|
|
@@ -51,7 +45,6 @@
|
|
| 51 |
if (t === 'dark' || (!t && window.matchMedia('(prefers-color-scheme: dark)').matches))
|
| 52 |
document.documentElement.classList.add('dark');
|
| 53 |
} catch {}
|
| 54 |
-
document.fonts.ready.then(() => document.documentElement.classList.add('fonts-ready'));
|
| 55 |
</script>
|
| 56 |
</head>
|
| 57 |
<body class="bg-bg-light dark:bg-bg-dark font-display text-slate-900 dark:text-text-main antialiased min-h-screen flex flex-col transition-colors">
|
|
@@ -62,7 +55,7 @@
|
|
| 62 |
<!-- Logo & Title -->
|
| 63 |
<div class="flex items-center gap-3">
|
| 64 |
<div class="flex items-center justify-center size-8 rounded-full bg-primary/10 text-primary border border-primary/20">
|
| 65 |
-
<
|
| 66 |
</div>
|
| 67 |
<h1 class="text-[0.9rem] font-bold tracking-tight">Codex Proxy</h1>
|
| 68 |
</div>
|
|
@@ -77,10 +70,10 @@
|
|
| 77 |
</div>
|
| 78 |
<!-- Theme Toggle -->
|
| 79 |
<button id="themeToggle" onclick="toggleTheme()" class="p-2 rounded-lg text-slate-500 dark:text-text-dim hover:bg-slate-100 dark:hover:bg-border-dark transition-colors" title="Toggle theme">
|
| 80 |
-
<span class="
|
| 81 |
</button>
|
| 82 |
<button id="addAccountBtn" onclick="startAddAccount()" class="flex items-center gap-2 px-4 py-2 bg-primary hover:bg-primary-hover text-white text-xs font-semibold rounded-lg transition-colors shadow-sm active:scale-95">
|
| 83 |
-
<
|
| 84 |
<span>Add Account</span>
|
| 85 |
</button>
|
| 86 |
</div>
|
|
@@ -119,7 +112,7 @@
|
|
| 119 |
<section class="bg-white dark:bg-card-dark border border-gray-200 dark:border-border-dark rounded-xl p-5 shadow-sm transition-colors">
|
| 120 |
<div class="flex items-center justify-between mb-6 border-b border-slate-100 dark:border-border-dark pb-4">
|
| 121 |
<div class="flex items-center gap-2">
|
| 122 |
-
<
|
| 123 |
<h2 class="text-[0.95rem] font-bold">API Configuration</h2>
|
| 124 |
</div>
|
| 125 |
<button onclick="resetConfigDefaults()" class="text-xs text-slate-400 dark:text-text-dim hover:text-slate-600 dark:hover:text-text-main transition-colors">Reset to defaults</button>
|
|
@@ -131,7 +124,7 @@
|
|
| 131 |
<div class="relative flex items-center">
|
| 132 |
<input id="baseUrl" class="w-full pl-3 pr-10 py-2.5 bg-slate-50 dark:bg-bg-dark border border-gray-200 dark:border-border-dark rounded-lg text-[0.78rem] font-mono text-slate-600 dark:text-text-main focus:ring-1 focus:ring-primary focus:border-primary outline-none transition-all" type="text" value="Loading..."/>
|
| 133 |
<button onclick="copyField('baseUrl', this)" class="absolute right-2 p-1.5 text-slate-400 dark:text-text-dim hover:text-primary transition-colors rounded-md hover:bg-slate-100 dark:hover:bg-border-dark" title="Copy URL">
|
| 134 |
-
<
|
| 135 |
</button>
|
| 136 |
</div>
|
| 137 |
</div>
|
|
@@ -143,7 +136,7 @@
|
|
| 143 |
<option value="codex">codex</option>
|
| 144 |
</select>
|
| 145 |
<div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-slate-500 dark:text-text-dim">
|
| 146 |
-
<
|
| 147 |
</div>
|
| 148 |
</div>
|
| 149 |
</div>
|
|
@@ -152,11 +145,11 @@
|
|
| 152 |
<label class="text-xs font-semibold text-slate-700 dark:text-text-main">Your API Key</label>
|
| 153 |
<div class="relative flex items-center">
|
| 154 |
<div class="absolute left-3 text-slate-400 dark:text-text-dim">
|
| 155 |
-
<
|
| 156 |
</div>
|
| 157 |
<input id="apiKey" class="w-full pl-10 pr-10 py-2.5 bg-slate-50 dark:bg-bg-dark border border-gray-200 dark:border-border-dark rounded-lg text-[0.78rem] font-mono text-slate-600 dark:text-text-main focus:ring-1 focus:ring-primary focus:border-primary outline-none transition-all tracking-wider" type="text" value="Loading..."/>
|
| 158 |
<button onclick="copyField('apiKey', this)" class="absolute right-2 p-1.5 text-slate-400 dark:text-text-dim hover:text-primary transition-colors rounded-md hover:bg-slate-100 dark:hover:bg-border-dark" title="Copy API Key">
|
| 159 |
-
<
|
| 160 |
</button>
|
| 161 |
</div>
|
| 162 |
<p class="text-xs text-slate-400 dark:text-text-dim mt-1">Use this key to authenticate requests to the proxy. Do not share it.</p>
|
|
@@ -187,7 +180,7 @@
|
|
| 187 |
<div id="codeContainer" class="relative group rounded-lg overflow-hidden bg-[#0d1117] text-slate-300 font-mono text-xs border border-slate-800 dark:border-border-dark">
|
| 188 |
<div class="absolute right-2 top-2 z-10 opacity-0 group-hover:opacity-100 transition-opacity">
|
| 189 |
<button onclick="copyCurrentCode()" class="flex items-center gap-1.5 px-3 py-1.5 bg-slate-700 hover:bg-slate-600 text-white rounded text-xs font-medium transition-colors">
|
| 190 |
-
<
|
| 191 |
</button>
|
| 192 |
</div>
|
| 193 |
<div class="p-4 overflow-x-auto">
|
|
@@ -231,10 +224,15 @@ function toggleTheme() {
|
|
| 231 |
updateThemeIcon();
|
| 232 |
}
|
| 233 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 234 |
function updateThemeIcon() {
|
| 235 |
-
const
|
| 236 |
-
if (!
|
| 237 |
-
|
| 238 |
}
|
| 239 |
updateThemeIcon();
|
| 240 |
|
|
@@ -342,7 +340,7 @@ function renderAccounts(accounts) {
|
|
| 342 |
return `
|
| 343 |
<div class="group bg-white dark:bg-card-dark border border-gray-200 dark:border-border-dark rounded-xl p-4 shadow-sm hover:shadow-md transition-all hover:border-primary/30 dark:hover:border-primary/50 relative">
|
| 344 |
<button onclick="deleteAccount('${escapeHtml(acct.id)}')" class="absolute top-3 right-3 opacity-0 group-hover:opacity-100 p-1.5 text-slate-300 dark:text-text-dim hover:text-red-500 transition-all rounded-md hover:bg-red-50 dark:hover:bg-red-900/20" title="Delete account">
|
| 345 |
-
<
|
| 346 |
</button>
|
| 347 |
<div class="flex justify-between items-start mb-4">
|
| 348 |
<div class="flex items-center gap-3">
|
|
@@ -673,11 +671,11 @@ function copyField(id, btn) {
|
|
| 673 |
const el = document.getElementById(id);
|
| 674 |
const text = el.value !== undefined ? el.value : el.textContent;
|
| 675 |
navigator.clipboard.writeText(text);
|
| 676 |
-
const
|
| 677 |
-
if (
|
| 678 |
-
|
| 679 |
btn.classList.add('text-primary');
|
| 680 |
-
setTimeout(() => {
|
| 681 |
}
|
| 682 |
}
|
| 683 |
|
|
|
|
| 4 |
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
|
| 5 |
<title>Codex Proxy Developer Dashboard</title>
|
| 6 |
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
|
|
|
|
|
|
|
| 7 |
<script>
|
| 8 |
tailwind.config = {
|
| 9 |
darkMode: "class",
|
|
|
|
| 20 |
"text-dim": "#8b949e",
|
| 21 |
},
|
| 22 |
fontFamily: {
|
| 23 |
+
"display": ["system-ui", "-apple-system", "BlinkMacSystemFont", "Segoe UI", "Roboto", "sans-serif"],
|
| 24 |
+
"mono": ["ui-monospace", "SFMono-Regular", "SF Mono", "Menlo", "Consolas", "Liberation Mono", "monospace"],
|
| 25 |
},
|
| 26 |
borderRadius: {"DEFAULT": "0.25rem", "lg": "0.5rem", "xl": "0.75rem", "full": "9999px"},
|
| 27 |
},
|
|
|
|
| 32 |
:root { --primary: 16 162 53; --primary-hover: 14 140 46; }
|
| 33 |
.dark { --primary: 16 163 127; --primary-hover: 14 140 108; }
|
| 34 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 35 |
/* Dark scrollbar for code blocks */
|
| 36 |
pre::-webkit-scrollbar { height: 8px; }
|
| 37 |
pre::-webkit-scrollbar-track { background: #0d1117; }
|
|
|
|
| 45 |
if (t === 'dark' || (!t && window.matchMedia('(prefers-color-scheme: dark)').matches))
|
| 46 |
document.documentElement.classList.add('dark');
|
| 47 |
} catch {}
|
|
|
|
| 48 |
</script>
|
| 49 |
</head>
|
| 50 |
<body class="bg-bg-light dark:bg-bg-dark font-display text-slate-900 dark:text-text-main antialiased min-h-screen flex flex-col transition-colors">
|
|
|
|
| 55 |
<!-- Logo & Title -->
|
| 56 |
<div class="flex items-center gap-3">
|
| 57 |
<div class="flex items-center justify-center size-8 rounded-full bg-primary/10 text-primary border border-primary/20">
|
| 58 |
+
<svg class="size-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
|
| 59 |
</div>
|
| 60 |
<h1 class="text-[0.9rem] font-bold tracking-tight">Codex Proxy</h1>
|
| 61 |
</div>
|
|
|
|
| 70 |
</div>
|
| 71 |
<!-- Theme Toggle -->
|
| 72 |
<button id="themeToggle" onclick="toggleTheme()" class="p-2 rounded-lg text-slate-500 dark:text-text-dim hover:bg-slate-100 dark:hover:bg-border-dark transition-colors" title="Toggle theme">
|
| 73 |
+
<span id="themeIcon"><svg class="size-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M21.752 15.002A9.72 9.72 0 0118 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 003 11.25C3 16.635 7.365 21 12.75 21a9.753 9.753 0 009.002-5.998z"/></svg></span>
|
| 74 |
</button>
|
| 75 |
<button id="addAccountBtn" onclick="startAddAccount()" class="flex items-center gap-2 px-4 py-2 bg-primary hover:bg-primary-hover text-white text-xs font-semibold rounded-lg transition-colors shadow-sm active:scale-95">
|
| 76 |
+
<svg class="size-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15"/></svg>
|
| 77 |
<span>Add Account</span>
|
| 78 |
</button>
|
| 79 |
</div>
|
|
|
|
| 112 |
<section class="bg-white dark:bg-card-dark border border-gray-200 dark:border-border-dark rounded-xl p-5 shadow-sm transition-colors">
|
| 113 |
<div class="flex items-center justify-between mb-6 border-b border-slate-100 dark:border-border-dark pb-4">
|
| 114 |
<div class="flex items-center gap-2">
|
| 115 |
+
<svg class="size-5 text-primary" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.324.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 011.37.49l1.296 2.247a1.125 1.125 0 01-.26 1.431l-1.003.827c-.293.241-.438.613-.43.992a7.723 7.723 0 010 .255c-.008.378.137.75.43.991l1.004.827c.424.35.534.955.26 1.43l-1.298 2.247a1.125 1.125 0 01-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.47 6.47 0 01-.22.128c-.331.183-.581.495-.644.869l-.213 1.281c-.09.543-.56.94-1.11.94h-2.594c-.55 0-1.019-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 01-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 01-1.369-.49l-1.297-2.247a1.125 1.125 0 01.26-1.431l1.004-.827c.292-.24.437-.613.43-.991a6.932 6.932 0 010-.255c.007-.38-.138-.751-.43-.992l-1.004-.827a1.125 1.125 0 01-.26-1.43l1.297-2.247a1.125 1.125 0 011.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.086.22-.128.332-.183.582-.495.644-.869l.214-1.28z"/><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
|
| 116 |
<h2 class="text-[0.95rem] font-bold">API Configuration</h2>
|
| 117 |
</div>
|
| 118 |
<button onclick="resetConfigDefaults()" class="text-xs text-slate-400 dark:text-text-dim hover:text-slate-600 dark:hover:text-text-main transition-colors">Reset to defaults</button>
|
|
|
|
| 124 |
<div class="relative flex items-center">
|
| 125 |
<input id="baseUrl" class="w-full pl-3 pr-10 py-2.5 bg-slate-50 dark:bg-bg-dark border border-gray-200 dark:border-border-dark rounded-lg text-[0.78rem] font-mono text-slate-600 dark:text-text-main focus:ring-1 focus:ring-primary focus:border-primary outline-none transition-all" type="text" value="Loading..."/>
|
| 126 |
<button onclick="copyField('baseUrl', this)" class="absolute right-2 p-1.5 text-slate-400 dark:text-text-dim hover:text-primary transition-colors rounded-md hover:bg-slate-100 dark:hover:bg-border-dark" title="Copy URL">
|
| 127 |
+
<svg class="size-[18px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1"/></svg>
|
| 128 |
</button>
|
| 129 |
</div>
|
| 130 |
</div>
|
|
|
|
| 136 |
<option value="codex">codex</option>
|
| 137 |
</select>
|
| 138 |
<div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-slate-500 dark:text-text-dim">
|
| 139 |
+
<svg class="size-[18px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M19.5 8.25l-7.5 7.5-7.5-7.5"/></svg>
|
| 140 |
</div>
|
| 141 |
</div>
|
| 142 |
</div>
|
|
|
|
| 145 |
<label class="text-xs font-semibold text-slate-700 dark:text-text-main">Your API Key</label>
|
| 146 |
<div class="relative flex items-center">
|
| 147 |
<div class="absolute left-3 text-slate-400 dark:text-text-dim">
|
| 148 |
+
<svg class="size-[18px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M15.75 5.25a3 3 0 013 3m3 0a6 6 0 01-7.029 5.912c-.563-.097-1.159.026-1.563.43L10.5 17.25H8.25v2.25H6v2.25H2.25v-2.818c0-.597.237-1.17.659-1.591l6.499-6.499c.404-.404.527-1 .43-1.563A6 6 0 1121.75 8.25z"/></svg>
|
| 149 |
</div>
|
| 150 |
<input id="apiKey" class="w-full pl-10 pr-10 py-2.5 bg-slate-50 dark:bg-bg-dark border border-gray-200 dark:border-border-dark rounded-lg text-[0.78rem] font-mono text-slate-600 dark:text-text-main focus:ring-1 focus:ring-primary focus:border-primary outline-none transition-all tracking-wider" type="text" value="Loading..."/>
|
| 151 |
<button onclick="copyField('apiKey', this)" class="absolute right-2 p-1.5 text-slate-400 dark:text-text-dim hover:text-primary transition-colors rounded-md hover:bg-slate-100 dark:hover:bg-border-dark" title="Copy API Key">
|
| 152 |
+
<svg class="size-[18px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1"/></svg>
|
| 153 |
</button>
|
| 154 |
</div>
|
| 155 |
<p class="text-xs text-slate-400 dark:text-text-dim mt-1">Use this key to authenticate requests to the proxy. Do not share it.</p>
|
|
|
|
| 180 |
<div id="codeContainer" class="relative group rounded-lg overflow-hidden bg-[#0d1117] text-slate-300 font-mono text-xs border border-slate-800 dark:border-border-dark">
|
| 181 |
<div class="absolute right-2 top-2 z-10 opacity-0 group-hover:opacity-100 transition-opacity">
|
| 182 |
<button onclick="copyCurrentCode()" class="flex items-center gap-1.5 px-3 py-1.5 bg-slate-700 hover:bg-slate-600 text-white rounded text-xs font-medium transition-colors">
|
| 183 |
+
<svg class="size-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1"/></svg> Copy
|
| 184 |
</button>
|
| 185 |
</div>
|
| 186 |
<div class="p-4 overflow-x-auto">
|
|
|
|
| 224 |
updateThemeIcon();
|
| 225 |
}
|
| 226 |
|
| 227 |
+
const SVG_MOON = '<svg class="size-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M21.752 15.002A9.72 9.72 0 0118 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 003 11.25C3 16.635 7.365 21 12.75 21a9.753 9.753 0 009.002-5.998z"/></svg>';
|
| 228 |
+
const SVG_SUN = '<svg class="size-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M12 3v2.25m6.364.386l-1.591 1.591M21 12h-2.25m-.386 6.364l-1.591-1.591M12 18.75V21m-4.773-4.227l-1.591 1.591M5.25 12H3m4.227-4.773L5.636 5.636M15.75 12a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0z"/></svg>';
|
| 229 |
+
const SVG_COPY = '<svg class="size-[18px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1"/></svg>';
|
| 230 |
+
const SVG_CHECK = '<svg class="size-[18px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"/></svg>';
|
| 231 |
+
|
| 232 |
function updateThemeIcon() {
|
| 233 |
+
const el = document.getElementById('themeIcon');
|
| 234 |
+
if (!el) return;
|
| 235 |
+
el.innerHTML = document.documentElement.classList.contains('dark') ? SVG_SUN : SVG_MOON;
|
| 236 |
}
|
| 237 |
updateThemeIcon();
|
| 238 |
|
|
|
|
| 340 |
return `
|
| 341 |
<div class="group bg-white dark:bg-card-dark border border-gray-200 dark:border-border-dark rounded-xl p-4 shadow-sm hover:shadow-md transition-all hover:border-primary/30 dark:hover:border-primary/50 relative">
|
| 342 |
<button onclick="deleteAccount('${escapeHtml(acct.id)}')" class="absolute top-3 right-3 opacity-0 group-hover:opacity-100 p-1.5 text-slate-300 dark:text-text-dim hover:text-red-500 transition-all rounded-md hover:bg-red-50 dark:hover:bg-red-900/20" title="Delete account">
|
| 343 |
+
<svg class="size-[18px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0"/></svg>
|
| 344 |
</button>
|
| 345 |
<div class="flex justify-between items-start mb-4">
|
| 346 |
<div class="flex items-center gap-3">
|
|
|
|
| 671 |
const el = document.getElementById(id);
|
| 672 |
const text = el.value !== undefined ? el.value : el.textContent;
|
| 673 |
navigator.clipboard.writeText(text);
|
| 674 |
+
const svg = btn.querySelector('svg');
|
| 675 |
+
if (svg) {
|
| 676 |
+
btn.innerHTML = SVG_CHECK;
|
| 677 |
btn.classList.add('text-primary');
|
| 678 |
+
setTimeout(() => { btn.innerHTML = SVG_COPY; btn.classList.remove('text-primary'); }, 2000);
|
| 679 |
}
|
| 680 |
}
|
| 681 |
|