Sync cezen-portal/ from live working copy (V1.0 GA polish + search-icon ordering fix)
Brings the ISO-packaged portal copy current with the live cezen-portal/ working directory, which had drifted across the entire V1.0 GA polish initiative (Phases 1-10) plus this session's topnav icon-order bugfix. - 52 existing files updated, 2 new pages added (about.html, health.html) - cgit/cezen-portal/ is now byte-identical to cezen-portal/ - Backend files (rag_ingest.py, cezen_license.py) already in sync; main.py intentionally left as-is (cgit is ahead there with workstation-category commercial-fit logic not yet backported to the live working copy) Next: rebuild the ISO (bash autoinstall/build-iso.sh) to bake this in.
This commit is contained in:
1 parent
7540da04a8
commit
b3eec34158
57 files changed
+2832
-1354
No files matched your search
+18
-11
@@ -4,7 +4,7 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>API Keys — Nexus One AI</title>
|
||||
<link rel="stylesheet" href="style.css?v=4">
|
||||
<link rel="stylesheet" href="style.css?v=12">
|
||||
<style>
|
||||
.ak-card { background:var(--navy2); border:1px solid var(--bdr); border-radius:14px; padding:28px; margin-bottom:28px; }
|
||||
.ak-card-title { font-size:16px; font-weight:700; color:var(--ink); margin-bottom:4px; }
|
||||
@@ -96,6 +96,7 @@
|
||||
<a href="dashboard.html">Dashboard</a>
|
||||
<a href="analytics.html">Usage Analytics</a>
|
||||
<a href="audit.html">Governance & Audit</a>
|
||||
<a href="health.html">Health Center</a>
|
||||
<a href="feedback.html">Feedback & Ratings</a>
|
||||
<span class="nav-drop-cat">MANAGE /</span>
|
||||
<a href="users.html">Users</a>
|
||||
@@ -135,7 +136,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<a href="notifications.html" style="position:relative">🔔</a>
|
||||
<a href="notifications.html" class="nav-icon-btn" style="position:relative" aria-label="Notifications"><span class="icon-svg icon-sm" aria-hidden="true"><svg viewBox="0 0 24 24"><path d="M15 17h5l-1.4-1.4A2 2 0 0 1 18 14.2V11a6 6 0 1 0-12 0v3.2a2 2 0 0 1-.6 1.4L4 17h5"/><path d="M10 17a2 2 0 0 0 4 0"/></svg></span></a>
|
||||
<span class="badge" data-brand="tier">Basic Tier</span>
|
||||
<div id="nav-org-logo" class="nav-org-logo"></div>
|
||||
</header>
|
||||
@@ -150,7 +151,7 @@
|
||||
|
||||
<!-- Tier gate — shown only on Entry tier -->
|
||||
<div class="tier-gate" id="tier-gate" style="display:none">
|
||||
<h3>🔒 Pro Tier & Above</h3>
|
||||
<h3>Pro Tier & Above</h3>
|
||||
<p>API Key management is available on Mid and Advanced tiers. Upgrade to enable programmatic access for pipelines and integrations.</p>
|
||||
</div>
|
||||
|
||||
@@ -159,7 +160,7 @@
|
||||
|
||||
<!-- Create card -->
|
||||
<div class="ak-card">
|
||||
<div class="ak-card-title">🔑 Your API Keys</div>
|
||||
<div class="ak-card-title">Your API Keys</div>
|
||||
<div class="ak-card-sub">Keys authenticate requests to <code>/api/*</code> via <code>Authorization: Bearer <key></code>. Each key is shown only once on creation.</div>
|
||||
<button class="ak-btn primary" onclick="openModal()">+ Generate New Key</button>
|
||||
</div>
|
||||
@@ -167,12 +168,13 @@
|
||||
<!-- Keys table -->
|
||||
<div class="ak-card">
|
||||
<div class="ak-card-title" id="keys-title">API Keys</div>
|
||||
<input type="text" id="key-filter" placeholder="Filter by key name or owner…" oninput="renderKeys()" style="width:100%;box-sizing:border-box;margin:0 0 12px;padding:8px 10px;border:1px solid var(--bdr);border-radius:7px;font-size:12.5px;font-family:inherit">
|
||||
<div id="keys-list"><div class="ak-empty">Loading…</div></div>
|
||||
</div>
|
||||
|
||||
<!-- Usage example -->
|
||||
<div class="ak-card">
|
||||
<div class="ak-card-title">📖 How to Use</div>
|
||||
<div class="ak-card-title">How to Use</div>
|
||||
<div class="ak-card-sub">Pass your API key in the <code>Authorization</code> header on every request.</div>
|
||||
<div class="ak-reveal">
|
||||
<div class="ak-reveal-label" style="color:#A3E635">cURL example</div>
|
||||
@@ -211,13 +213,13 @@ curl -H "Authorization: Bearer czk_your_key_here" \
|
||||
<!-- Key reveal modal -->
|
||||
<div class="ak-modal-bg" id="ak-reveal-bg">
|
||||
<div class="ak-modal">
|
||||
<h3>🔑 Your New API Key</h3>
|
||||
<h3>Your New API Key</h3>
|
||||
<div style="font-size:13px;color:var(--lt);margin-bottom:12px">This key will not be shown again. Copy it now and store it securely.</div>
|
||||
<div class="ak-reveal">
|
||||
<div class="ak-reveal-label">SECRET KEY — COPY NOW</div>
|
||||
<span id="reveal-key"></span>
|
||||
</div>
|
||||
<button class="ak-btn primary" onclick="copyKey()" style="width:100%;margin-bottom:10px" id="copy-key-btn">📋 Copy Key</button>
|
||||
<button class="ak-btn primary" onclick="copyKey()" style="width:100%;margin-bottom:10px" id="copy-key-btn">Copy Key</button>
|
||||
<div class="ak-modal-footer">
|
||||
<button class="save" onclick="closeReveal()">Done</button>
|
||||
</div>
|
||||
@@ -264,6 +266,11 @@ function renderKeys() {
|
||||
if (!allKeys.length) {
|
||||
el.innerHTML = '<div class="ak-empty">No API keys yet. Generate one above.</div>'; return;
|
||||
}
|
||||
const q = (document.getElementById('key-filter')?.value || '').trim().toLowerCase();
|
||||
const keysToRender = q ? allKeys.filter(k => (k.name || '').toLowerCase().includes(q) || (k.username || '').toLowerCase().includes(q)) : allKeys;
|
||||
if (!keysToRender.length) {
|
||||
el.innerHTML = '<div class="ak-empty">No API keys match your filter.</div>'; return;
|
||||
}
|
||||
const now = new Date().toISOString();
|
||||
let html = `<div class="ak-table-wrap"><table class="ak-table">
|
||||
<tr>
|
||||
@@ -276,7 +283,7 @@ function renderKeys() {
|
||||
<th>Expires</th>
|
||||
<th></th>
|
||||
</tr>`;
|
||||
allKeys.forEach(k => {
|
||||
keysToRender.forEach(k => {
|
||||
const expired = k.expires_at && now > k.expires_at;
|
||||
const statusBadge = !k.is_active ? '<span class="badge-revoked">Revoked</span>'
|
||||
: expired ? '<span class="badge-expired">Expired</span>'
|
||||
@@ -338,8 +345,8 @@ async function generateKey() {
|
||||
function copyKey() {
|
||||
navigator.clipboard.writeText(newKeyValue).then(() => {
|
||||
const btn = document.getElementById('copy-key-btn');
|
||||
btn.textContent = '✓ Copied!';
|
||||
setTimeout(() => btn.textContent = '📋 Copy Key', 2000);
|
||||
btn.textContent = 'Copied!';
|
||||
setTimeout(() => btn.textContent = 'Copy Key', 2000);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -381,6 +388,6 @@ document.addEventListener('cezenAuthReady', function() {
|
||||
setTimeout(checkTier, 200);
|
||||
});
|
||||
</script>
|
||||
<script src="branding.js"></script>
|
||||
<script src="branding.js?v=3"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in new issue
Block a user