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:
Jino Jose committed 2026-07-09 11:11:38 +05:30
1 parent 7540da04a8
commit b3eec34158
57 files changed
+2832 -1354

No files matched your search

+44 -41
View File
@@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Prompt Library — Nexus One AI Portal</title>
<link rel="stylesheet" href="style.css?v=4">
<link rel="stylesheet" href="style.css?v=12">
<style>
/* ── Admin bar ── */
.pl-admin-bar { display:none; align-items:center; gap:10px; margin-bottom:18px; }
@@ -82,6 +82,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 &amp; Ratings</a>
<span class="nav-drop-cat">MANAGE /</span>
<a href="users.html">Users</a>
@@ -121,7 +122,9 @@
</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-md" aria-hidden="true"><svg viewBox="0 0 24 24"><path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.73 21a2 2 0 0 1-3.46 0"/></svg></span>
</a>
<span class="badge" data-brand="tier">Basic Tier</span>
<div id="nav-org-logo" class="nav-org-logo"></div>
</header>
@@ -136,8 +139,8 @@
<!-- Admin bar — visible only to admins -->
<div class="pl-admin-bar" id="pl-admin-bar">
<button class="pl-admin-btn primary" onclick="openModal()">+ Add Prompt</button>
<span id="pl-admin-mode-toggle" style="font-size:13px;color:var(--lt);cursor:pointer;" onclick="toggleAdminMode()">⚙ Edit mode: <strong id="admin-mode-label">Off</strong></span>
<button class="pl-admin-btn primary" onclick="openModal()"><span class="icon-label"><span class="icon-svg icon-sm" aria-hidden="true"><svg viewBox="0 0 24 24"><path d="M12 5v14M5 12h14"/></svg></span><span>Add Prompt</span></span></button>
<span id="pl-admin-mode-toggle" style="font-size:13px;color:var(--lt);cursor:pointer;" onclick="toggleAdminMode()"><span class="icon-label"><span class="icon-svg icon-sm" aria-hidden="true"><svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 1 1-4 0v-.09a1.65 1.65 0 0 0-1-1.51 1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 1 1 0-4h.09a1.65 1.65 0 0 0 1.51-1 1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33h.01A1.65 1.65 0 0 0 10.5 3.1V3a2 2 0 1 1 4 0v.09a1.65 1.65 0 0 0 1 1.51h.01a1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82v.01a1.65 1.65 0 0 0 1.51 1H21a2 2 0 1 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg></span><span>Edit mode: <strong id="admin-mode-label">Off</strong></span></span></span>
</div>
<!-- SEARCH + FILTERS -->
@@ -145,33 +148,33 @@
<input type="text" class="ts-search" id="pl-search" placeholder="Search prompts — e.g. 'tender', 'summary', 'complaint'…" oninput="filterCards()">
<div class="pl-filters" id="pl-filters">
<button class="pl-filter active" data-cat="all" onclick="setFilter('all',this)">All <span class="pl-count" id="count-all"></span></button>
<button class="pl-filter" data-cat="procurement" onclick="setFilter('procurement',this)">📋 Procurement</button>
<button class="pl-filter" data-cat="hr" onclick="setFilter('hr',this)">👥 HR &amp; Admin</button>
<button class="pl-filter" data-cat="legal" onclick="setFilter('legal',this)">⚖️ Legal &amp; Compliance</button>
<button class="pl-filter" data-cat="operations" onclick="setFilter('operations',this)">⚙️ Operations</button>
<button class="pl-filter" data-cat="citizen" onclick="setFilter('citizen',this)">🏛️ Citizen Services</button>
<button class="pl-filter" data-cat="finance" onclick="setFilter('finance',this)">💰 Finance</button>
<button class="pl-filter" data-cat="comms" onclick="setFilter('comms',this)">✉️ Communications</button>
<button class="pl-filter" data-cat="management" onclick="setFilter('management',this)">📊 Management</button>
<button class="pl-filter" data-cat="general" onclick="setFilter('general',this)">🔧 General</button>
<button class="pl-filter" data-cat="procurement" onclick="setFilter('procurement',this)">Procurement</button>
<button class="pl-filter" data-cat="hr" onclick="setFilter('hr',this)">HR &amp; Admin</button>
<button class="pl-filter" data-cat="legal" onclick="setFilter('legal',this)">Legal &amp; Compliance</button>
<button class="pl-filter" data-cat="operations" onclick="setFilter('operations',this)">Operations</button>
<button class="pl-filter" data-cat="citizen" onclick="setFilter('citizen',this)">Citizen Services</button>
<button class="pl-filter" data-cat="finance" onclick="setFilter('finance',this)">Finance</button>
<button class="pl-filter" data-cat="comms" onclick="setFilter('comms',this)">Communications</button>
<button class="pl-filter" data-cat="management" onclick="setFilter('management',this)">Management</button>
<button class="pl-filter" data-cat="general" onclick="setFilter('general',this)">General</button>
</div>
</div>
<div class="pl-tip">
<span>💡</span>
<span>Prompts with <span class="upload-badge-inline">📎 Upload doc</span> work best when you first upload the relevant file using the <strong>+</strong> button in Open WebUI. Replace text in <span class="placeholder-eg">[brackets]</span> with your own details.</span>
<span class="icon-svg icon-sm" aria-hidden="true"><svg viewBox="0 0 24 24"><path d="M9.09 9a3 3 0 1 1 5.82 1c0 2-3 3-3 3"/><path d="M12 17h.01"/><circle cx="12" cy="12" r="9"/></svg></span>
<span>Prompts with <span class="upload-badge-inline">Upload doc</span> work best when you first upload the relevant file using the <strong>+</strong> button in Open WebUI. Replace text in <span class="placeholder-eg">[brackets]</span> with your own details.</span>
</div>
<!-- PROMPT CARDS -->
<div class="pl-grid" id="pl-grid">
<div class="pl-empty" id="pl-loading" style="padding:48px 0">
<div style="font-size:32px;margin-bottom:10px">⏳</div>
<div class="icon-svg icon-2xl" style="margin-bottom:10px" aria-hidden="true"><svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg></div>
<div>Loading prompts…</div>
</div>
</div>
<div id="pl-empty" class="pl-empty" style="display:none">
<div style="font-size:40px;margin-bottom:12px">🔍</div>
<div class="icon-svg icon-3xl" style="margin-bottom:12px" aria-hidden="true"><svg viewBox="0 0 24 24"><circle cx="11" cy="11" r="6"/><path d="m20 20-4.35-4.35"/></svg></div>
<div>No prompts match your search. Try different keywords.</div>
</div>
@@ -188,7 +191,7 @@
</div>
<div class="info-card">
<h4>Upload the document first</h4>
<p>For any prompt marked <span class="upload-badge-inline">📎 Upload doc</span>, click the + button in Open WebUI and upload your file before sending the prompt. The AI will read the actual document rather than guessing from general knowledge.</p>
<p>For any prompt marked <span class="upload-badge-inline">Upload doc</span>, click the + button in Open WebUI and upload your file before sending the prompt. The AI will read the actual document rather than guessing from general knowledge.</p>
</div>
<div class="info-card">
<h4>Iterate — ask follow-ups</h4>
@@ -210,15 +213,15 @@
<div>
<label>Category</label>
<select id="m-cat">
<option value="procurement">📋 Procurement</option>
<option value="hr">👥 HR &amp; Admin</option>
<option value="legal">⚖️ Legal &amp; Compliance</option>
<option value="operations">⚙️ Operations</option>
<option value="citizen">🏛️ Citizen Services</option>
<option value="finance">💰 Finance</option>
<option value="comms">✉️ Communications</option>
<option value="management">📊 Management</option>
<option value="general">🔧 General</option>
<option value="procurement">Procurement</option>
<option value="hr">HR &amp; Admin</option>
<option value="legal">Legal &amp; Compliance</option>
<option value="operations">Operations</option>
<option value="citizen">Citizen Services</option>
<option value="finance">Finance</option>
<option value="comms">Communications</option>
<option value="management">Management</option>
<option value="general">General</option>
</select>
</div>
<div>
@@ -248,15 +251,15 @@
<script>
const _API = '/api';
const CAT_META = {
procurement: { label:'📋 Procurement', cls:'procurement' },
hr: { label:'👥 HR & Admin', cls:'hr' },
legal: { label:'⚖️ Legal & Compliance', cls:'legal' },
operations: { label:'⚙️ Operations', cls:'operations' },
citizen: { label:'🏛️ Citizen Services', cls:'citizen' },
finance: { label:'💰 Finance', cls:'finance' },
comms: { label:'✉️ Communications', cls:'comms' },
management: { label:'📊 Management', cls:'management' },
general: { label:'🔧 General', cls:'general' },
procurement: { label:'Procurement', cls:'procurement' },
hr: { label:'HR & Admin', cls:'hr' },
legal: { label:'Legal & Compliance', cls:'legal' },
operations: { label:'Operations', cls:'operations' },
citizen: { label:'Citizen Services', cls:'citizen' },
finance: { label:'Finance', cls:'finance' },
comms: { label:'Communications', cls:'comms' },
management: { label:'Management', cls:'management' },
general: { label:'General', cls:'general' },
};
let allPrompts = [];
@@ -303,14 +306,14 @@ function renderCards() {
card.innerHTML = `
<div class="pl-card-header">
<span class="pl-cat-tag ${meta.cls}">${meta.label}</span>
${p.needs_upload ? '<span class="upload-badge">📎 Upload doc</span>' : ''}
${p.needs_upload ? '<span class="upload-badge">Upload doc</span>' : ''}
</div>
<div class="pl-title">${escHtml(p.title)}</div>
<div class="pl-prompt" id="pt-${p.id}">${escHtml(p.prompt_text)}</div>
<button class="pl-copy-btn" onclick="copyPrompt('pt-${p.id}', this)">Copy Prompt</button>
<div class="pl-card-actions">
<button class="pl-edit-btn" onclick="openModal(${p.id})">✏ Edit</button>
<button class="pl-del-btn" onclick="deletePrompt(${p.id}, '${escHtml(p.title).replace(/'/g,"\\'")}')">🗑 Delete</button>
<button class="pl-edit-btn" onclick="openModal(${p.id})">Edit</button>
<button class="pl-del-btn" onclick="deletePrompt(${p.id}, '${escHtml(p.title).replace(/'/g,"\\'")}')">Delete</button>
</div>
`;
grid.appendChild(card);
@@ -345,7 +348,7 @@ function copyPrompt(id, btn) {
const text = document.getElementById(id).textContent.trim();
navigator.clipboard.writeText(text).then(() => {
const orig = btn.textContent;
btn.textContent = '✓ Copied!';
btn.textContent = 'Copied!';
btn.classList.add('copied');
setTimeout(() => { btn.textContent = orig; btn.classList.remove('copied'); }, 2000);
});
@@ -449,6 +452,6 @@ document.addEventListener('cezenAuthReady', function() {
}
});
</script>
<script src="branding.js"></script>
<script src="branding.js?v=3"></script>
</body>
</html>