Files
shopify-ai-backup/chat/public/admin-plan.html
southseact-3d 25d23d8dd1 Add comprehensive feature request admin functionality
- Update data model to include status, adminReply, and updatedAt fields
- Hide user emails from public API responses for privacy
- Add admin-only endpoints: list, reply, update status, delete
- Create admin-feature-requests.html with full management UI
- Add status badges and admin replies to public feature requests page
- Add Feature Requests link to all admin page sidebars

Admin capabilities:
- View all feature requests with author emails (admin only)
- Reply to feature requests with admin responses visible to public
- Update status: pending, planned, in-progress, completed, declined
- Delete feature requests
- Filter and sort by status, votes, date
2026-02-10 13:27:36 +00:00

148 lines
6.3 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Admin Panel Planning</title>
<link rel="stylesheet" href="/styles.css" />
<!-- PostHog Analytics -->
<script src="/posthog.js"></script>
</head>
<body data-page="plan">
<div class="sidebar-overlay"></div>
<div class="app-shell">
<aside class="sidebar">
<div class="brand">
<div class="brand-mark">A</div>
<div>
<div class="brand-title">Admin</div>
<div class="brand-sub">Site management</div>
</div>
<button id="close-sidebar" class="ghost" style="margin-left: auto; display: none;">&times;</button>
</div>
<div class="sidebar-section">
<div class="section-heading">Navigation</div>
<a class="ghost" href="/admin/build">Build models</a>
<a class="ghost" href="/admin/plan">Plan models</a>
<a class="ghost" href="/admin/plans">Plans</a>
<a class="ghost" href="/admin/accounts">Accounts</a>
<a class="ghost" href="/admin/affiliates">Affiliates</a>
<a class="ghost" href="/admin/withdrawals">Withdrawals</a>
<a class="ghost" href="/admin/tracking">Tracking</a>
<a class="ghost" href="/admin/resources">Resources</a>
<a class="ghost" href="/admin/external-testing">External Testing</a>
<a class="ghost" href="/admin/contact-messages">Contact Messages</a>
<a class="ghost" href="/admin/feature-requests">Feature Requests</a>
<a class="ghost" href="/admin/login">Login</a>
</div>
</aside>
<main class="main">
<div class="admin-shell">
<div class="topbar" style="margin-bottom: 12px;">
<button id="menu-toggle">
<span></span><span></span><span></span>
</button>
<div>
<div class="pill">Admin</div>
<div class="title" style="margin-top: 6px;">Planning Control</div>
<div class="crumb">Fallback-ready planning across OpenRouter, Mistral, Google, Groq, and NVIDIA.</div>
</div>
<div class="admin-actions">
<button id="admin-refresh" class="ghost">Refresh</button>
<button id="admin-logout" class="primary">Logout</button>
</div>
</div>
<div class="admin-card">
<header>
<h3>Planning Priority</h3>
<div class="pill">Planning</div>
</header>
<p class="muted" style="margin-top:0;">One row per planning model. Highest priority runs first and automatically falls back on errors or rate limits.</p>
<div id="plan-priority-list" class="admin-list"></div>
<div class="admin-actions" style="margin-top: 12px;">
<button type="button" id="add-plan-row" class="ghost">Add planning model</button>
<div class="status-line" id="plan-chain-status"></div>
</div>
</div>
<div class="admin-card" style="margin-top: 16px;">
<header>
<h3>Rate Limits & Usage</h3>
<div class="pill">Shared</div>
</header>
<p style="margin-top:0; color: var(--muted);">Limits here apply to both planning and build traffic. Set provider/model RPM/TPM caps and monitor live usage.</p>
<form id="provider-limit-form" class="admin-form">
<label>
Provider
<select id="limit-provider">
<option value="openrouter">OpenRouter</option>
<option value="mistral">Mistral</option>
<option value="google">Google</option>
<option value="groq">Groq</option>
<option value="nvidia">NVIDIA</option>
<option value="opencode">OpenCode</option>
</select>
</label>
<label>
Scope
<select id="limit-scope">
<option value="provider">Per Provider</option>
<option value="model">Per Model</option>
</select>
</label>
<label>
Model (for per-model limits)
<select id="limit-model">
<option value="">Any model</option>
</select>
<input id="limit-model-input" type="text" placeholder="Type a model id (e.g. mistral-large-latest)" style="display:none; margin-top:8px;" list="available-model-datalist" />
</label>
<label>
Tokens per minute
<input id="limit-tpm" type="number" min="0" step="1" placeholder="0 = unlimited" />
</label>
<label>
Tokens per day
<input id="limit-tpd" type="number" min="0" step="1" placeholder="0 = unlimited" />
</label>
<label>
Requests per minute
<input id="limit-rpm" type="number" min="0" step="1" placeholder="0 = unlimited" />
</label>
<label>
Requests per day
<input id="limit-rpd" type="number" min="0" step="1" placeholder="0 = unlimited" />
</label>
<label>
Opencode backup model
<input id="limit-backup" type="text" placeholder="Backup model when all providers fail" />
</label>
<div class="admin-actions">
<button type="submit" class="primary">Save limits</button>
</div>
<div class="status-line" id="provider-limit-status"></div>
</form>
<div id="provider-usage" class="admin-list"></div>
</div>
<div class="admin-card" style="margin-top: 16px;">
<header>
<h3>Ollama Test</h3>
<div class="pill">Testing</div>
</header>
<p style="margin-top:0; color: var(--muted);">Test the Ollama provider connection. This makes a test request to verify the configuration and API key are working correctly.</p>
<div class="admin-actions" style="flex-direction: column; align-items: flex-start; gap: 12px;">
<button id="ollama-test-run" class="primary">Run Ollama Test</button>
<div id="ollama-test-status" class="status-line"></div>
<div id="ollama-test-output" style="width: 100%;"></div>
</div>
</div>
</div>
</main>
</div>
<script src="/admin.js"></script>
</body>
</html>