fc3g(ext): options page — FC URL + API key form with test-connection button
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,41 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<title>FabledCurator — Settings</title>
|
||||||
|
<style>
|
||||||
|
body { font: 14px/1.4 system-ui, sans-serif; max-width: 520px; margin: 32px auto; padding: 0 16px; }
|
||||||
|
h1 { font-family: Georgia, serif; font-size: 20px; }
|
||||||
|
label { display: block; font-weight: 500; margin: 16px 0 6px; }
|
||||||
|
input { width: 100%; padding: 8px; box-sizing: border-box; font: inherit; }
|
||||||
|
.hint { color: #666; font-size: 12px; margin-top: 4px; }
|
||||||
|
.row { display: flex; gap: 8px; margin-top: 16px; }
|
||||||
|
button { padding: 8px 16px; cursor: pointer; font: inherit; }
|
||||||
|
button.primary { background: #F4BA7A; color: #14171A; border: none; border-radius: 4px; }
|
||||||
|
button.test { background: none; border: 1px solid #ccc; border-radius: 4px; }
|
||||||
|
.status { margin-top: 16px; padding: 8px 12px; border-radius: 4px; }
|
||||||
|
.status.ok { background: #DFF5DF; color: #2B6A2B; }
|
||||||
|
.status.err { background: #FBE1E1; color: #862525; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>FabledCurator extension</h1>
|
||||||
|
|
||||||
|
<label for="api-url">FC base URL</label>
|
||||||
|
<input id="api-url" type="url" placeholder="http://curator.example.com/api" />
|
||||||
|
<div class="hint">Find this on FC → Settings → Maintenance → Browser extension.</div>
|
||||||
|
|
||||||
|
<label for="api-key">Extension API key</label>
|
||||||
|
<input id="api-key" type="password" placeholder="paste from FC Settings card" />
|
||||||
|
<div class="hint">Generate or rotate on FC → Settings → Maintenance → Browser extension.</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<button class="primary" id="save-btn">Save</button>
|
||||||
|
<button class="test" id="test-btn">Test connection</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="status" class="status" style="display:none;"></div>
|
||||||
|
|
||||||
|
<script src="options.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
document.addEventListener('DOMContentLoaded', async () => {
|
||||||
|
const stored = await browser.storage.local.get(['apiUrl', 'apiKey']);
|
||||||
|
document.getElementById('api-url').value = stored.apiUrl || '';
|
||||||
|
document.getElementById('api-key').value = stored.apiKey || '';
|
||||||
|
|
||||||
|
document.getElementById('save-btn').addEventListener('click', save);
|
||||||
|
document.getElementById('test-btn').addEventListener('click', test);
|
||||||
|
});
|
||||||
|
|
||||||
|
async function save() {
|
||||||
|
const apiUrl = document.getElementById('api-url').value.trim().replace(/\/+$/, '');
|
||||||
|
const apiKey = document.getElementById('api-key').value.trim();
|
||||||
|
if (!apiUrl || !apiKey) {
|
||||||
|
showStatus('Both fields are required.', 'err');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await browser.storage.local.set({ apiUrl, apiKey });
|
||||||
|
await browser.storage.local.remove(['lastConnectionTest', 'lastConnectionStatus']);
|
||||||
|
showStatus('Saved.', 'ok');
|
||||||
|
}
|
||||||
|
|
||||||
|
async function test() {
|
||||||
|
const apiUrl = document.getElementById('api-url').value.trim().replace(/\/+$/, '');
|
||||||
|
const apiKey = document.getElementById('api-key').value.trim();
|
||||||
|
if (!apiUrl || !apiKey) {
|
||||||
|
showStatus('Fill both fields first.', 'err');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const r = await fetch(`${apiUrl}/credentials`, {
|
||||||
|
method: 'GET',
|
||||||
|
headers: { 'X-Extension-Key': apiKey },
|
||||||
|
});
|
||||||
|
if (r.ok) showStatus(`Connected — HTTP ${r.status}.`, 'ok');
|
||||||
|
else showStatus(`HTTP ${r.status}: ${r.statusText}`, 'err');
|
||||||
|
} catch (e) {
|
||||||
|
showStatus(`Cannot reach ${apiUrl}: ${e.message}`, 'err');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function showStatus(text, kind) {
|
||||||
|
const el = document.getElementById('status');
|
||||||
|
el.textContent = text;
|
||||||
|
el.className = `status ${kind}`;
|
||||||
|
el.style.display = 'block';
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user