Spaces:
Sleeping
Sleeping
File size: 4,770 Bytes
e5e1997 d978c2b e5e1997 d978c2b e5e1997 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | /* ================================================================
NewsForge Admin β API Client
Handles all communication with the FastAPI backend.
================================================================ */
const API_BASE = window.NF_ADMIN_API_BASE || 'http://localhost:8000';
// ββ Admin Token ββ
const AdminAuth = {
getToken() { return localStorage.getItem('nf_admin_token'); },
setToken(token, admin) {
localStorage.setItem('nf_admin_token', token);
localStorage.setItem('nf_admin_info', JSON.stringify(admin));
},
clearToken() {
localStorage.removeItem('nf_admin_token');
localStorage.removeItem('nf_admin_info');
},
getAdmin() {
try { return JSON.parse(localStorage.getItem('nf_admin_info') || 'null'); }
catch { return null; }
},
};
// ββ Core Fetch ββ
async function adminApiFetch(path, options = {}) {
const headers = { 'Content-Type': 'application/json', ...(options.headers || {}) };
const token = AdminAuth.getToken();
if (token) headers['Authorization'] = `Bearer ${token}`;
const res = await fetch(`${API_BASE}${path}`, { ...options, headers });
if (res.status === 401) {
AdminAuth.clearToken();
document.getElementById('app-layout').classList.remove('active');
document.getElementById('login-page').style.display = 'flex';
showAdminToast('β οΈ', 'Session expired. Please log in again.');
return null;
}
if (!res.ok) {
let errMsg = `API Error ${res.status}`;
try { const body = await res.json(); errMsg = body.detail || errMsg; } catch {}
throw new Error(errMsg);
}
if (res.status === 204) return null;
return res.json();
}
// ββ Admin Auth API ββ
const AdminAuthAPI = {
async login(email, password) {
const res = await fetch(`${API_BASE}/admin/auth/login`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email, password }),
});
if (!res.ok) {
const body = await res.json().catch(() => ({}));
throw new Error(body.detail || 'Invalid email or password');
}
const data = await res.json();
AdminAuth.setToken(data.access_token, { id: data.admin_id, name: data.name, role: data.role });
return data;
},
logout() {
AdminAuth.clearToken();
document.getElementById('app-layout').classList.remove('active');
document.getElementById('login-page').style.display = 'flex';
document.getElementById('admin-email').value = '';
document.getElementById('admin-password').value = '';
},
};
// ββ Analytics API ββ
const AnalyticsAPI = {
async getOverview() { return adminApiFetch('/admin/analytics/overview'); },
async getTemplateStats() { return adminApiFetch('/admin/analytics/templates'); },
async getUserStats() { return adminApiFetch('/admin/analytics/users'); },
async getAIUsage() { return adminApiFetch('/admin/analytics/ai-usage'); },
};
// ββ Templates API (Admin) ββ
const AdminTemplatesAPI = {
async list(params = {}) {
const qs = new URLSearchParams(params).toString();
return adminApiFetch(`/admin/templates?${qs}`);
},
async get(id) {
return adminApiFetch(`/admin/templates/${id}`);
},
async create(data) {
return adminApiFetch('/admin/templates', {
method: 'POST',
body: JSON.stringify(data),
});
},
async update(id, data) {
return adminApiFetch(`/admin/templates/${id}`, {
method: 'PUT',
body: JSON.stringify(data),
});
},
async updateStatus(id, status) {
return adminApiFetch(`/admin/templates/${id}/status`, {
method: 'PATCH',
body: JSON.stringify({ status }),
});
},
async delete(id) {
return adminApiFetch(`/admin/templates/${id}`, { method: 'DELETE' });
},
async uploadAsset(templateId, file, assetType) {
const token = AdminAuth.getToken();
const form = new FormData();
form.append('file', file);
form.append('asset_type', assetType);
const res = await fetch(`${API_BASE}/admin/templates/${templateId}/assets`, {
method: 'POST',
headers: { 'Authorization': `Bearer ${token}` },
body: form,
});
if (!res.ok) {
let errMsg = `Upload failed (${res.status})`;
try { const body = await res.json(); errMsg = body.detail || errMsg; } catch {}
throw new Error(errMsg);
}
return res.json();
},
};
// ββ Users API (Admin) ββ
const AdminUsersAPI = {
async list(search = '', page = 1) {
const qs = new URLSearchParams({ page, ...(search ? { search } : {}) }).toString();
return adminApiFetch(`/admin/users?${qs}`);
},
async update(id, data) {
return adminApiFetch(`/admin/users/${id}`, {
method: 'PATCH',
body: JSON.stringify(data),
});
},
};
|