diff --git a/public/components/admin.html b/public/components/admin.html index eb3bb5e..6c6ea30 100644 --- a/public/components/admin.html +++ b/public/components/admin.html @@ -202,63 +202,7 @@ - -
-
-

AI Models

- Loading... -
-
- -
- - - -
- - -
- -
- - - - - - - - - - - - - -
ModelCategoryCostTagEnabled
Loading...
-
-
- - -
- -
-
-
- - -
-
- - -
-
- - -
- -
-
-
-
+
diff --git a/public/js/admin.js b/public/js/admin.js index c882c67..48a80cd 100644 --- a/public/js/admin.js +++ b/public/js/admin.js @@ -279,8 +279,6 @@ if (e.target.closest('#btn-clear-smtp')) clearSmtp(); if (e.target.closest('#btn-save-auto-delete')) saveAutoDelete(); if (e.target.closest('#btn-reset-all-defaults')) resetAllDefaults(); - if (e.target.closest('#btn-add-custom-model')) addCustomModel(); - if (e.target.closest('#btn-save-default-model')) saveDefaultModel(); }); // When email template selector changes, repopulate fields @@ -328,7 +326,6 @@ loadPromptList(); loadSmtp(); - loadModels(); } // ---- ANNOUNCEMENT ---- @@ -560,186 +557,6 @@ .catch(function() { showToast('Request failed', 'error'); }); } - // ---- AI MODEL MANAGEMENT ---- - - var modelsLoaded = false; - - function loadModels() { - if (modelsLoaded) return; - modelsLoaded = true; - - fetch('/api/admin/config/models', { headers: getAuthHeaders() }) - .then(function(r) { return r.json(); }) - .then(function(data) { - if (!data.success) { modelsLoaded = false; return; } - window._adminModelsData = data; - var providerEl = document.getElementById('admin-model-provider'); - if (providerEl) providerEl.textContent = (data.provider || 'openrouter').toUpperCase(); - renderModelTable(data.models || []); - renderCustomModels(data.custom || []); - populateDefaultModelSelect(data.models || [], data.custom || []); - }) - .catch(function(err) { modelsLoaded = false; console.error('[Admin] Models load failed:', err); }); - } - - function renderModelTable(models) { - var tbody = document.getElementById('admin-models-body'); - if (!tbody) return; - if (models.length === 0) { - tbody.innerHTML = 'No models'; - return; - } - - var catColors = { free: 'var(--green)', fast: 'var(--blue)', smart: 'var(--purple)', premium: 'var(--amber)' }; - - tbody.innerHTML = models.map(function(m) { - var catColor = catColors[m.category] || 'var(--g500)'; - var checked = m.enabled ? 'checked' : ''; - return '' + - '
' + esc(m.name) + '
' + esc(m.id) + '
' + - '' + esc(m.category) + '' + - '' + esc(m.cost || '?') + '' + - '' + esc(m.tag || '') + '' + - '' + - ''; - }).join(''); - - // Bind toggle events - tbody.querySelectorAll('.model-toggle').forEach(function(cb) { - cb.addEventListener('change', function() { - var modelId = cb.dataset.modelId; - var enabled = cb.checked; - toggleModel(modelId, enabled); - }); - }); - } - - function toggleModel(modelId, enabled) { - fetch('/api/admin/config/models/toggle', { - method: 'PUT', - headers: getAuthHeaders(), - body: JSON.stringify({ modelId: modelId, enabled: enabled }) - }) - .then(function(r) { return r.json(); }) - .then(function(data) { - if (data.success) { - showToast((enabled ? 'Enabled' : 'Disabled') + ': ' + modelId, 'success'); - } else { - showToast(data.error || 'Toggle failed', 'error'); - } - }) - .catch(function() { showToast('Request failed', 'error'); }); - } - - function renderCustomModels(custom) { - var container = document.getElementById('admin-custom-models-list'); - if (!container) return; - if (custom.length === 0) { - container.innerHTML = '
No custom models added
'; - return; - } - container.innerHTML = custom.map(function(m) { - return '
' + - '' + esc(m.name) + '' + - '' + esc(m.id) + '' + - '' + esc(m.cost || '?') + '' + - '' + - '
'; - }).join(''); - - container.querySelectorAll('[data-delete-model]').forEach(function(btn) { - btn.addEventListener('click', function() { - var id = btn.dataset.deleteModel; - if (!confirm('Remove custom model "' + id + '"?')) return; - deleteCustomModel(id); - }); - }); - } - - function populateDefaultModelSelect(models, custom) { - var sel = document.getElementById('admin-default-model'); - if (!sel) return; - sel.innerHTML = ''; - var all = models.filter(function(m) { return m.enabled; }).concat(custom || []); - all.forEach(function(m) { - var opt = document.createElement('option'); - opt.value = m.id; - opt.textContent = m.name + ' (' + (m.cost || '?') + ')'; - sel.appendChild(opt); - }); - - // Load current default from already-loaded config, or fetch if needed - var cfg = window._adminEmailConfig || {}; - if (cfg['models.default']) { - sel.value = cfg['models.default']; - } else { - // Fetch only the default model setting - fetch('/api/admin/config', { headers: getAuthHeaders() }) - .then(function(r) { return r.json(); }) - .then(function(data) { - if (!data.success) return; - (data.config || []).forEach(function(row) { - if (row.key === 'models.default' && row.value) sel.value = row.value; - }); - }) - .catch(function() {}); - } - } - - function addCustomModel() { - var id = document.getElementById('admin-custom-id').value.trim(); - var name = document.getElementById('admin-custom-name').value.trim(); - var cost = document.getElementById('admin-custom-cost').value.trim(); - if (!id || !name) { showToast('Model ID and name required', 'error'); return; } - - fetch('/api/admin/config/models/custom', { - method: 'POST', - headers: getAuthHeaders(), - body: JSON.stringify({ id: id, name: name, cost: cost || '?', category: 'smart' }) - }) - .then(function(r) { return r.json(); }) - .then(function(data) { - if (data.success) { - showToast('Custom model added: ' + name, 'success'); - document.getElementById('admin-custom-id').value = ''; - document.getElementById('admin-custom-name').value = ''; - document.getElementById('admin-custom-cost').value = ''; - modelsLoaded = false; - loadModels(); - } else { - showToast(data.error || 'Add failed', 'error'); - } - }) - .catch(function() { showToast('Request failed', 'error'); }); - } - - function deleteCustomModel(modelId) { - fetch('/api/admin/config/models/custom/' + encodeURIComponent(modelId), { - method: 'DELETE', - headers: getAuthHeaders() - }) - .then(function(r) { return r.json(); }) - .then(function(data) { - if (data.success) { - showToast('Model removed', 'info'); - modelsLoaded = false; - loadModels(); - } else { - showToast(data.error || 'Delete failed', 'error'); - } - }) - .catch(function() { showToast('Request failed', 'error'); }); - } - - function saveDefaultModel() { - var sel = document.getElementById('admin-default-model'); - if (!sel) return; - var val = sel.value; - putConfig('models.default', val) - .then(function() { showToast('Default model saved' + (val ? ': ' + val : ' (provider default)'), 'success'); }) - .catch(function() { showToast('Save failed', 'error'); }); - } - // ---- HELPERS ---- function putConfig(key, value) {