pediatric-ai-scribe-v3/public/components/admin.html
Daniel 3d5b77721c Replace all browser dialogs with modern modal, add OIDC admin UI
- Add reusable showConfirm() modal component (supports plain confirm,
  input prompt, danger styling, Enter key)
- Replace ALL 18 confirm() and prompt() calls across 8 JS files with
  showConfirm() modal: admin user actions, session revoke, document
  delete, template delete, milestone management, transcription settings
- Fix broken admin reset-password (btn was undefined in scope)
- Add OIDC/SSO configuration UI to Admin Panel (issuer, client ID/secret,
  button label, disable local auth toggle, callback URL display)
2026-04-09 02:43:23 +02:00

422 lines
30 KiB
HTML

<div class="module-header">
<h2><i class="fas fa-user-shield"></i> Admin Panel</h2>
<p>Manage users, app settings, and view usage statistics</p>
</div>
<!-- Stats -->
<div class="admin-stats" id="admin-stats">
<div class="stat-card"><div class="stat-value" id="stat-users"></div><div class="stat-label">Total Users</div></div>
<div class="stat-card"><div class="stat-value" id="stat-api-total"></div><div class="stat-label">Total API Calls</div></div>
<div class="stat-card"><div class="stat-value" id="stat-api-today"></div><div class="stat-label">API Calls Today</div></div>
</div>
<!-- Registration -->
<div class="card">
<div class="card-header"><h3><i class="fas fa-door-open"></i> Registration</h3></div>
<div style="padding:16px;display:flex;align-items:center;gap:16px;flex-wrap:wrap;">
<span id="reg-status-text" style="font-size:13px;color:var(--g600);">Loading...</span>
<button id="btn-toggle-reg" class="btn-sm btn-primary">Toggle</button>
</div>
</div>
<!-- Users -->
<div class="card">
<div class="card-header">
<h3><i class="fas fa-users"></i> Users</h3>
<button id="btn-refresh-users" class="btn-sm btn-ghost"><i class="fas fa-rotate"></i> Refresh</button>
</div>
<div style="overflow-x:auto;">
<table class="admin-table" id="admin-users-table">
<thead>
<tr>
<th>Name / Email</th>
<th>Role</th>
<th>Status</th>
<th>Joined</th>
<th>Actions</th>
</tr>
</thead>
<tbody id="admin-users-body">
<tr><td colspan="5" style="text-align:center;color:var(--g400);padding:20px;">Loading...</td></tr>
</tbody>
</table>
</div>
</div>
<!-- ── CMS: Announcement Banner ──────────────────────────────── -->
<div class="card">
<div class="card-header"><h3><i class="fas fa-bullhorn"></i> Announcement Banner</h3></div>
<div style="padding:16px;display:flex;flex-direction:column;gap:12px;">
<div style="display:flex;align-items:center;gap:12px;flex-wrap:wrap;">
<label style="font-size:13px;font-weight:600;">Show banner:</label>
<select id="cms-ann-enabled" style="font-size:13px;padding:4px 8px;border:1px solid var(--g300);border-radius:6px;">
<option value="false">Hidden</option>
<option value="true">Visible</option>
</select>
<select id="cms-ann-type" style="font-size:13px;padding:4px 8px;border:1px solid var(--g300);border-radius:6px;">
<option value="info">Info (blue)</option>
<option value="warning">Warning (amber)</option>
<option value="error">Error (red)</option>
<option value="success">Success (green)</option>
</select>
</div>
<textarea id="cms-ann-text" rows="2" style="font-size:13px;padding:8px;border:1px solid var(--g300);border-radius:6px;resize:vertical;" placeholder="Announcement message..."></textarea>
<div>
<button id="btn-save-announcement" class="btn-sm btn-primary">Save &amp; Publish</button>
</div>
</div>
</div>
<!-- ── CMS: Feature Flags ─────────────────────────────────────── -->
<div class="card">
<div class="card-header"><h3><i class="fas fa-toggle-on"></i> Feature Flags</h3></div>
<div style="padding:16px;display:flex;flex-direction:column;gap:10px;" id="cms-feature-flags">
<div style="display:flex;align-items:center;gap:12px;">
<label style="font-size:13px;font-weight:600;min-width:160px;">Read Aloud (TTS):</label>
<select id="cms-flag-read-aloud" style="font-size:13px;padding:4px 8px;border:1px solid var(--g300);border-radius:6px;">
<option value="true">Enabled</option>
<option value="false">Disabled</option>
</select>
</div>
<div style="display:flex;align-items:center;gap:12px;">
<label style="font-size:13px;font-weight:600;min-width:160px;">Nextcloud Integration:</label>
<select id="cms-flag-nextcloud" style="font-size:13px;padding:4px 8px;border:1px solid var(--g300);border-radius:6px;">
<option value="true">Enabled</option>
<option value="false">Disabled</option>
</select>
</div>
<div>
<button id="btn-save-flags" class="btn-sm btn-primary">Save Flags</button>
</div>
</div>
</div>
<!-- ── OIDC / SSO Configuration ──────────────────────────────── -->
<div class="card">
<div class="card-header"><h3><i class="fas fa-shield-halved"></i> Single Sign-On (OIDC)</h3></div>
<div style="padding:16px;display:flex;flex-direction:column;gap:12px;">
<p style="font-size:12px;color:var(--g500);margin:0;">Configure OpenID Connect for SSO with Azure AD, Okta, Keycloak, PocketID, Google, etc.<br>Callback URL: <code style="font-size:11px;background:var(--g100);padding:2px 6px;border-radius:4px;" id="oidc-callback-url"></code></p>
<div style="display:flex;align-items:center;gap:12px;">
<label style="font-size:13px;font-weight:600;min-width:160px;">Enable SSO:</label>
<select id="oidc-enabled" style="font-size:13px;padding:4px 8px;border:1px solid var(--g300);border-radius:6px;">
<option value="false">Disabled</option>
<option value="true">Enabled</option>
</select>
</div>
<div style="display:flex;align-items:center;gap:12px;">
<label style="font-size:13px;font-weight:600;min-width:160px;">Issuer URL:</label>
<input type="url" id="oidc-issuer" placeholder="https://id.example.com" style="flex:1;font-size:13px;padding:5px 8px;border:1px solid var(--g300);border-radius:6px;max-width:400px;">
</div>
<div style="display:flex;align-items:center;gap:12px;">
<label style="font-size:13px;font-weight:600;min-width:160px;">Client ID:</label>
<input type="text" id="oidc-client-id" placeholder="your-client-id" style="flex:1;font-size:13px;padding:5px 8px;border:1px solid var(--g300);border-radius:6px;max-width:400px;">
</div>
<div style="display:flex;align-items:center;gap:12px;">
<label style="font-size:13px;font-weight:600;min-width:160px;">Client Secret:</label>
<input type="password" id="oidc-client-secret" placeholder="Leave blank to keep current" style="flex:1;font-size:13px;padding:5px 8px;border:1px solid var(--g300);border-radius:6px;max-width:400px;">
</div>
<div style="display:flex;align-items:center;gap:12px;">
<label style="font-size:13px;font-weight:600;min-width:160px;">Button Label:</label>
<input type="text" id="oidc-button-label" placeholder="Sign in with SSO" style="flex:1;font-size:13px;padding:5px 8px;border:1px solid var(--g300);border-radius:6px;max-width:400px;">
</div>
<div style="display:flex;align-items:center;gap:12px;">
<label style="font-size:13px;font-weight:600;min-width:160px;">Disable local login:</label>
<select id="oidc-disable-local" style="font-size:13px;padding:4px 8px;border:1px solid var(--g300);border-radius:6px;">
<option value="false">No (both SSO and local login)</option>
<option value="true">Yes (SSO only)</option>
</select>
</div>
<div>
<button id="btn-save-oidc" class="btn-sm btn-primary"><i class="fas fa-floppy-disk"></i> Save OIDC Settings</button>
<span id="oidc-save-status" style="font-size:12px;margin-left:8px;color:var(--g500);"></span>
</div>
</div>
</div>
<!-- ── CMS: Email Templates ───────────────────────────────────── -->
<div class="card">
<div class="card-header"><h3><i class="fas fa-envelope"></i> Email Templates</h3></div>
<div style="padding:16px;display:flex;flex-direction:column;gap:16px;">
<!-- Email template selector -->
<div style="display:flex;align-items:center;gap:12px;flex-wrap:wrap;">
<label style="font-size:13px;font-weight:600;">Template:</label>
<select id="cms-email-template" style="font-size:13px;padding:4px 8px;border:1px solid var(--g300);border-radius:6px;">
<option value="verify">Email Verification</option>
<option value="reset">Password Reset</option>
</select>
</div>
<div>
<label style="font-size:12px;font-weight:600;color:var(--g600);margin-bottom:4px;display:block;">Subject</label>
<input type="text" id="cms-email-subject" style="width:100%;font-size:13px;padding:8px;border:1px solid var(--g300);border-radius:6px;box-sizing:border-box;" placeholder="Email subject...">
</div>
<div>
<label style="font-size:12px;font-weight:600;color:var(--g600);margin-bottom:4px;display:block;">Body (plain text — a button link will be appended automatically)</label>
<textarea id="cms-email-body" rows="4" style="width:100%;font-size:13px;padding:8px;border:1px solid var(--g300);border-radius:6px;resize:vertical;box-sizing:border-box;" placeholder="Email body text..."></textarea>
</div>
<div style="display:flex;gap:8px;flex-wrap:wrap;">
<button id="btn-save-email" class="btn-sm btn-primary">Save Template</button>
<button id="btn-test-email" class="btn-sm btn-ghost"><i class="fas fa-paper-plane"></i> Send Test</button>
</div>
</div>
</div>
<!-- ── CMS: AI Prompts ────────────────────────────────────────── -->
<div class="card">
<div class="card-header">
<h3><i class="fas fa-robot"></i> AI Prompts</h3>
<span style="font-size:12px;color:var(--g500);">Changes take effect immediately, no restart needed</span>
</div>
<div style="padding:16px;display:flex;flex-direction:column;gap:12px;">
<div style="display:flex;align-items:center;gap:12px;flex-wrap:wrap;">
<label style="font-size:13px;font-weight:600;">Prompt:</label>
<select id="cms-prompt-select" style="font-size:13px;padding:4px 8px;border:1px solid var(--g300);border-radius:6px;max-width:320px;"></select>
</div>
<textarea id="cms-prompt-text" rows="10" style="width:100%;font-size:12px;font-family:monospace;padding:8px;border:1px solid var(--g300);border-radius:6px;resize:vertical;box-sizing:border-box;" placeholder="Loading..."></textarea>
<div style="display:flex;gap:8px;flex-wrap:wrap;">
<button id="btn-save-prompt" class="btn-sm btn-primary">Save Prompt</button>
<button id="btn-reset-prompt" class="btn-sm btn-ghost"><i class="fas fa-rotate-left"></i> Reset to Default</button>
</div>
</div>
</div>
<!-- ── CMS: SMTP Email Server ─────────────────────────────────── -->
<div class="card">
<div class="card-header">
<h3><i class="fas fa-server"></i> SMTP Email Server</h3>
<span id="smtp-source-badge" style="font-size:11px;padding:2px 8px;border-radius:10px;background:var(--g100);color:var(--g600);">Loading...</span>
</div>
<div style="padding:16px;display:flex;flex-direction:column;gap:12px;">
<div style="display:grid;grid-template-columns:1fr 1fr;gap:10px;">
<div>
<label style="font-size:12px;font-weight:600;color:var(--g600);display:block;margin-bottom:4px;">SMTP Host</label>
<input type="text" id="cms-smtp-host" style="width:100%;font-size:13px;padding:7px;border:1px solid var(--g300);border-radius:6px;box-sizing:border-box;" placeholder="smtp.gmail.com">
</div>
<div>
<label style="font-size:12px;font-weight:600;color:var(--g600);display:block;margin-bottom:4px;">Port</label>
<input type="number" id="cms-smtp-port" style="width:100%;font-size:13px;padding:7px;border:1px solid var(--g300);border-radius:6px;box-sizing:border-box;" placeholder="587" value="587">
</div>
<div>
<label style="font-size:12px;font-weight:600;color:var(--g600);display:block;margin-bottom:4px;">Username / Email</label>
<input type="text" id="cms-smtp-user" style="width:100%;font-size:13px;padding:7px;border:1px solid var(--g300);border-radius:6px;box-sizing:border-box;" placeholder="user@example.com">
</div>
<div>
<label style="font-size:12px;font-weight:600;color:var(--g600);display:block;margin-bottom:4px;">Password / App Password</label>
<input type="password" id="cms-smtp-pass" style="width:100%;font-size:13px;padding:7px;border:1px solid var(--g300);border-radius:6px;box-sizing:border-box;" placeholder="Leave blank to keep current">
</div>
<div>
<label style="font-size:12px;font-weight:600;color:var(--g600);display:block;margin-bottom:4px;">From Address</label>
<input type="text" id="cms-smtp-from" style="width:100%;font-size:13px;padding:7px;border:1px solid var(--g300);border-radius:6px;box-sizing:border-box;" placeholder="Pediatric Scribe &lt;noreply@example.com&gt;">
</div>
<div style="display:flex;align-items:flex-end;gap:8px;">
<label style="font-size:12px;font-weight:600;color:var(--g600);display:block;">TLS/SSL (port 465):</label>
<select id="cms-smtp-secure" style="font-size:13px;padding:7px;border:1px solid var(--g300);border-radius:6px;">
<option value="false">STARTTLS (587)</option>
<option value="true">SSL/TLS (465)</option>
</select>
</div>
</div>
<div style="display:flex;gap:8px;flex-wrap:wrap;">
<button id="btn-save-smtp" class="btn-sm btn-primary">Save SMTP</button>
<button id="btn-clear-smtp" class="btn-sm btn-ghost"><i class="fas fa-trash"></i> Clear DB (use env)</button>
</div>
<p style="font-size:12px;color:var(--g500);margin:0;"><i class="fas fa-info-circle"></i> Environment variables take precedence over DB settings. Storing password in DB is convenient but consider using env vars for production security.</p>
</div>
</div>
<!-- ── CMS: Saved Encounters (Admin View) ─────────────────────── -->
<div class="card">
<div class="card-header">
<h3><i class="fas fa-database"></i> Saved Encounters (Site-wide)</h3>
<span style="font-size:12px;color:var(--g500);">Auto-deleted after <span id="admin-auto-delete-days">7</span> days</span>
</div>
<div style="padding:16px;display:flex;flex-direction:column;gap:10px;">
<div style="display:flex;align-items:center;gap:12px;flex-wrap:wrap;">
<label style="font-size:13px;font-weight:600;">Auto-delete after:</label>
<select id="cms-auto-delete-days" style="font-size:13px;padding:4px 8px;border:1px solid var(--g300);border-radius:6px;">
<option value="1">1 day</option>
<option value="3">3 days</option>
<option value="7" selected>7 days</option>
<option value="14">14 days</option>
<option value="30">30 days</option>
</select>
<button id="btn-save-auto-delete" class="btn-sm btn-primary">Save</button>
</div>
</div>
</div>
<!-- ── AI Model Management ─────────────────────────────────── -->
<div class="card">
<div class="card-header">
<h3><i class="fas fa-microchip"></i> AI Model Management</h3>
<span id="admin-model-provider-badge" style="font-size:11px;padding:2px 8px;border-radius:10px;background:var(--g100);color:var(--g600);">Loading...</span>
</div>
<div style="padding:16px;display:flex;flex-direction:column;gap:14px;">
<!-- Default Model -->
<div style="display:flex;align-items:center;gap:12px;flex-wrap:wrap;">
<label style="font-size:13px;font-weight:600;min-width:120px;">Default Model:</label>
<select id="admin-default-model" style="font-size:13px;padding:5px 8px;border:1px solid var(--g300);border-radius:6px;flex:1;max-width:400px;"></select>
<button id="btn-save-default-model" class="btn-sm btn-primary">Set Default</button>
</div>
<!-- Built-in Models Toggle -->
<div>
<label style="font-size:12px;font-weight:600;color:var(--g600);display:block;margin-bottom:8px;">Built-in Models (toggle to enable/disable for users)</label>
<div id="admin-builtin-models" style="display:flex;flex-direction:column;gap:4px;max-height:300px;overflow-y:auto;padding-right:4px;">
<p style="color:var(--g400);font-size:13px;">Loading...</p>
</div>
</div>
<!-- Discover Models from API -->
<div style="border-top:1px solid var(--g100);padding-top:14px;">
<label style="font-size:12px;font-weight:600;color:var(--g600);display:block;margin-bottom:8px;">Discover Models from Provider API</label>
<div style="display:flex;gap:8px;flex-wrap:wrap;align-items:center;">
<input type="text" id="admin-model-search" placeholder="Search models (e.g. gemini, vendor-model, gpt)" style="font-size:13px;padding:6px 10px;border:1px solid var(--g300);border-radius:6px;flex:1;min-width:200px;">
<button id="btn-discover-models" class="btn-sm btn-primary"><i class="fas fa-magnifying-glass"></i> Search API</button>
</div>
<div id="admin-discovered-models" style="margin-top:10px;display:flex;flex-direction:column;gap:4px;max-height:400px;overflow-y:auto;">
</div>
<p id="admin-discover-hint" style="font-size:12px;color:var(--g500);margin:8px 0 0;">Click "Search API" to query your configured provider for all available models. Use the search box to filter results.</p>
</div>
<!-- Custom Model (manual) -->
<div style="border-top:1px solid var(--g100);padding-top:14px;">
<label style="font-size:12px;font-weight:600;color:var(--g600);display:block;margin-bottom:8px;">Add Custom Model (manual)</label>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:8px;">
<input type="text" id="admin-custom-model-id" placeholder="Model ID (e.g. openai/gpt-4.1)" style="font-size:13px;padding:6px 10px;border:1px solid var(--g300);border-radius:6px;">
<input type="text" id="admin-custom-model-name" placeholder="Display name" style="font-size:13px;padding:6px 10px;border:1px solid var(--g300);border-radius:6px;">
<input type="text" id="admin-custom-model-cost" placeholder="Cost (e.g. ~$0.01)" style="font-size:13px;padding:6px 10px;border:1px solid var(--g300);border-radius:6px;">
<select id="admin-custom-model-cat" style="font-size:13px;padding:6px 10px;border:1px solid var(--g300);border-radius:6px;">
<option value="fast">Fast & Cheap</option>
<option value="smart" selected>Smart</option>
<option value="premium">Premium</option>
<option value="free">Free</option>
</select>
</div>
<div style="margin-top:8px;">
<button id="btn-add-custom-model" class="btn-sm btn-primary"><i class="fas fa-plus"></i> Add Model</button>
</div>
</div>
<!-- Custom Models List -->
<div id="admin-custom-models-list" style="display:flex;flex-direction:column;gap:4px;">
</div>
</div>
</div>
<!-- ── TTS Model Management ───────────────────────────────────── -->
<div class="card">
<div class="card-header">
<h3><i class="fas fa-volume-up"></i> Text-to-Speech (TTS)</h3>
<span id="admin-tts-provider-badge" style="font-size:11px;padding:2px 8px;border-radius:10px;background:var(--g100);color:var(--g600);">Loading...</span>
</div>
<div style="padding:16px;display:flex;flex-direction:column;gap:14px;">
<div id="admin-tts-info" style="font-size:12px;color:var(--g500);">Loading...</div>
<!-- Search voices from provider -->
<div>
<label style="font-size:12px;font-weight:600;color:var(--g600);display:block;margin-bottom:8px;">Search Voices / Models from Provider</label>
<div style="display:flex;gap:8px;flex-wrap:wrap;align-items:center;">
<input type="text" id="admin-tts-search" placeholder="Filter voices (e.g. Journey, Neural, alloy)" style="font-size:13px;padding:6px 10px;border:1px solid var(--g300);border-radius:6px;flex:1;min-width:180px;">
<button id="btn-discover-tts" class="btn-sm btn-primary"><i class="fas fa-magnifying-glass"></i> Search</button>
</div>
<div id="admin-tts-discovered" style="margin-top:8px;display:flex;flex-direction:column;gap:4px;max-height:300px;overflow-y:auto;"></div>
<p id="admin-tts-discover-hint" style="font-size:12px;color:var(--g500);margin:6px 0 0;">Click Search to query available voices from your configured TTS provider.</p>
</div>
<!-- Test TTS -->
<div style="border-top:1px solid var(--g100);padding-top:12px;">
<label style="font-size:12px;font-weight:600;color:var(--g600);display:block;margin-bottom:8px;">Test Synthesis</label>
<div style="display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:8px;">
<label style="font-size:13px;font-weight:600;min-width:80px;">Voice:</label>
<select id="admin-tts-voice" style="font-size:13px;padding:5px 8px;border:1px solid var(--g300);border-radius:6px;flex:1;max-width:280px;"></select>
</div>
<textarea id="admin-tts-test-text" rows="2" style="width:100%;font-size:13px;padding:8px;border:1px solid var(--g300);border-radius:6px;resize:vertical;box-sizing:border-box;" placeholder="Text to synthesize...">Hello, this is a text to speech test for the Pediatric AI Scribe.</textarea>
<div style="margin-top:8px;display:flex;gap:8px;align-items:center;flex-wrap:wrap;">
<button id="btn-test-tts" class="btn-sm btn-primary"><i class="fas fa-play"></i> Synthesize &amp; Play</button>
<audio id="admin-tts-audio" controls style="display:none;height:32px;flex:1;min-width:180px;"></audio>
</div>
<p id="admin-tts-result" style="font-size:12px;color:var(--g500);margin:6px 0 0;"></p>
</div>
</div>
</div>
<!-- ── STT Model Management ───────────────────────────────────── -->
<div class="card">
<div class="card-header">
<h3><i class="fas fa-microphone"></i> Speech-to-Text (STT)</h3>
<span id="admin-stt-provider-badge" style="font-size:11px;padding:2px 8px;border-radius:10px;background:var(--g100);color:var(--g600);">Loading...</span>
</div>
<div style="padding:16px;display:flex;flex-direction:column;gap:14px;">
<div id="admin-stt-info" style="font-size:12px;color:var(--g500);">Loading...</div>
<!-- Search models from provider -->
<div>
<label style="font-size:12px;font-weight:600;color:var(--g600);display:block;margin-bottom:8px;">Search Models from Provider</label>
<div style="display:flex;gap:8px;flex-wrap:wrap;align-items:center;">
<input type="text" id="admin-stt-search" placeholder="Filter models (e.g. gemini, whisper)" style="font-size:13px;padding:6px 10px;border:1px solid var(--g300);border-radius:6px;flex:1;min-width:180px;">
<button id="btn-discover-stt" class="btn-sm btn-primary"><i class="fas fa-magnifying-glass"></i> Search</button>
</div>
<div id="admin-stt-discovered" style="margin-top:8px;display:flex;flex-direction:column;gap:4px;max-height:300px;overflow-y:auto;"></div>
<p id="admin-stt-discover-hint" style="font-size:12px;color:var(--g500);margin:6px 0 0;">Click Search to query available STT models from your configured provider.</p>
</div>
<!-- Test STT -->
<div style="border-top:1px solid var(--g100);padding-top:12px;">
<label style="font-size:12px;font-weight:600;color:var(--g600);display:block;margin-bottom:8px;">Test STT — Record &amp; Transcribe</label>
<div style="display:flex;gap:8px;align-items:center;flex-wrap:wrap;">
<button id="btn-stt-record" class="btn-sm btn-primary"><i class="fas fa-microphone"></i> Start Recording</button>
<span id="admin-stt-recording-status" style="font-size:12px;color:var(--g500);"></span>
</div>
<div id="admin-stt-result" style="margin-top:10px;padding:10px;background:var(--g50);border-radius:6px;font-size:13px;color:var(--g700);display:none;">
<strong>Transcription:</strong> <span id="admin-stt-text"></span>
<div id="admin-stt-meta" style="font-size:11px;color:var(--g400);margin-top:4px;"></div>
</div>
</div>
</div>
</div>
<!-- ── Embedding Models ───────────────────────────────────────── -->
<div class="card">
<div class="card-header">
<h3><i class="fas fa-network-wired"></i> Embedding Models</h3>
<span id="admin-embed-provider-badge" style="font-size:11px;padding:2px 8px;border-radius:10px;background:var(--g100);color:var(--g600);">Loading...</span>
</div>
<div style="padding:16px;display:flex;flex-direction:column;gap:14px;">
<div id="admin-embed-info" style="font-size:12px;color:var(--g500);">Loading...</div>
<!-- Search embedding models from provider -->
<div>
<label style="font-size:12px;font-weight:600;color:var(--g600);display:block;margin-bottom:8px;">Search Models from Provider</label>
<div style="display:flex;gap:8px;flex-wrap:wrap;align-items:center;">
<input type="text" id="admin-embed-search" placeholder="Filter models (e.g. embedding, vertex)" style="font-size:13px;padding:6px 10px;border:1px solid var(--g300);border-radius:6px;flex:1;min-width:180px;">
<button id="btn-discover-embeddings" class="btn-sm btn-primary"><i class="fas fa-magnifying-glass"></i> Search</button>
</div>
<div id="admin-embed-discovered" style="margin-top:8px;display:flex;flex-direction:column;gap:4px;max-height:300px;overflow-y:auto;"></div>
<p id="admin-embed-discover-hint" style="font-size:12px;color:var(--g500);margin:6px 0 0;">Click Search to query available embedding models from your configured provider.</p>
</div>
<!-- Test Embedding -->
<div style="border-top:1px solid var(--g100);padding-top:12px;">
<label style="font-size:12px;font-weight:600;color:var(--g600);display:block;margin-bottom:8px;">Test Embedding</label>
<div style="display:flex;gap:8px;flex-wrap:wrap;align-items:center;">
<input type="text" id="admin-embed-test-text" value="Pediatric patient with fever and cough" style="font-size:13px;padding:6px 10px;border:1px solid var(--g300);border-radius:6px;flex:1;min-width:200px;" placeholder="Sample text to embed...">
<button id="btn-test-embedding" class="btn-sm btn-primary"><i class="fas fa-code-branch"></i> Generate</button>
</div>
<div id="admin-embed-result" style="margin-top:8px;font-size:12px;color:var(--g500);"></div>
</div>
</div>
</div>
<!-- ── CMS: Reset to Defaults ─────────────────────────────────── -->
<div class="card" style="border:1px solid var(--red-light);">
<div class="card-header"><h3 style="color:var(--red);"><i class="fas fa-triangle-exclamation"></i> Reset Settings</h3></div>
<div style="padding:16px;display:flex;flex-direction:column;gap:10px;">
<p style="font-size:13px;color:var(--g600);margin:0;">Reset all announcement, feature flag, and email settings back to factory defaults. SMTP configuration and custom models are preserved.</p>
<div>
<button id="btn-reset-all-defaults" class="btn-sm" style="background:var(--red);color:white;border:none;border-radius:6px;padding:6px 14px;font-size:13px;cursor:pointer;"><i class="fas fa-rotate-left"></i> Reset All to Defaults</button>
</div>
</div>
</div>