6de2455917
- Added GLOBAL_MARKETS_TITLE to all translation files - Updated footer with 12 markets (4 active + 8 upcoming) - Translated market section to: zh-cn, zh-tw, ja, ko, th, vi, id, ms, hi - Built and deployed to production - CloudFront invalidation: I3RTMXVFDJXWLG3SYX208OP1CC
175 lines
6.2 KiB
JavaScript
175 lines
6.2 KiB
JavaScript
'use strict';
|
|
|
|
class AdminAPI {
|
|
constructor(baseUrl, token) {
|
|
this.baseUrl = baseUrl.replace(/\/$/, '');
|
|
this.token = token || null;
|
|
}
|
|
|
|
// ── Internal ────────────────────────────────────────────────────────────────
|
|
|
|
_headers(extra = {}) {
|
|
const h = { 'Content-Type': 'application/json', ...extra };
|
|
if (this.token) h['Authorization'] = `Bearer ${this.token}`;
|
|
return h;
|
|
}
|
|
|
|
async _fetch(method, path, body) {
|
|
const opts = { method, headers: this._headers() };
|
|
if (body !== undefined) opts.body = JSON.stringify(body);
|
|
|
|
const res = await fetch(`${this.baseUrl}${path}`, opts);
|
|
|
|
if (res.status === 401) {
|
|
this.token = null;
|
|
sessionStorage.removeItem('aamos_token');
|
|
window.location.href = '/login';
|
|
return Promise.reject(new Error('Unauthorized'));
|
|
}
|
|
|
|
let data;
|
|
const ct = res.headers.get('content-type') || '';
|
|
if (ct.includes('application/json')) {
|
|
data = await res.json();
|
|
} else {
|
|
data = await res.text();
|
|
}
|
|
|
|
if (!res.ok) {
|
|
const msg = (data && data.message) || (data && data.error) || `HTTP ${res.status}`;
|
|
const err = new Error(msg);
|
|
err.status = res.status;
|
|
err.data = data;
|
|
return Promise.reject(err);
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
_get(path) { return this._fetch('GET', path); }
|
|
_post(path, body) { return this._fetch('POST', path, body); }
|
|
_put(path, body) { return this._fetch('PUT', path, body); }
|
|
_patch(path, body) { return this._fetch('PATCH', path, body); }
|
|
_delete(path) { return this._fetch('DELETE', path); }
|
|
|
|
// ── Auth ────────────────────────────────────────────────────────────────────
|
|
|
|
async login(email, password) {
|
|
const data = await this._post('/api/v1/auth/login', { email, password });
|
|
if (data && data.token) {
|
|
this.token = data.token;
|
|
sessionStorage.setItem('aamos_token', data.token);
|
|
}
|
|
return data;
|
|
}
|
|
|
|
async logout() {
|
|
try {
|
|
await this._post('/api/v1/auth/logout');
|
|
} finally {
|
|
this.token = null;
|
|
sessionStorage.removeItem('aamos_token');
|
|
}
|
|
}
|
|
|
|
// ── Current user ────────────────────────────────────────────────────────────
|
|
|
|
getMe() {
|
|
return this._get('/api/v1/auth/me');
|
|
}
|
|
|
|
// ── Dashboard ───────────────────────────────────────────────────────────────
|
|
|
|
getDashboard() {
|
|
return this._get('/api/v1/dashboard');
|
|
}
|
|
|
|
getUnifiedDashboard() {
|
|
return this._get('/api/v1/unified-dashboard');
|
|
}
|
|
|
|
getServiceHealth() {
|
|
return this._get('/api/v1/service-health');
|
|
}
|
|
|
|
// ── Users ───────────────────────────────────────────────────────────────────
|
|
|
|
getUsers(page = 1, limit = 25, search = '') {
|
|
const params = new URLSearchParams({ page: String(page), limit: String(limit) });
|
|
if (search) params.set('search', search);
|
|
return this._get(`/api/v1/users?${params}`);
|
|
}
|
|
|
|
createUser(data) {
|
|
return this._post('/api/v1/users', data);
|
|
}
|
|
|
|
updateUser(id, data) {
|
|
return this._put(`/api/v1/users/${encodeURIComponent(id)}`, data);
|
|
}
|
|
|
|
deleteUser(id) {
|
|
return this._delete(`/api/v1/users/${encodeURIComponent(id)}`);
|
|
}
|
|
|
|
// ── Modules ─────────────────────────────────────────────────────────────────
|
|
|
|
getModules() {
|
|
return this._get('/api/v1/modules');
|
|
}
|
|
|
|
toggleModule(id) {
|
|
return this._put(`/api/v1/modules/${encodeURIComponent(id)}/toggle`);
|
|
}
|
|
|
|
// ── Audit log ───────────────────────────────────────────────────────────────
|
|
|
|
getAudit(filters = {}) {
|
|
const params = new URLSearchParams();
|
|
for (const [k, v] of Object.entries(filters)) {
|
|
if (v !== undefined && v !== null && v !== '') params.set(k, String(v));
|
|
}
|
|
const qs = params.toString();
|
|
return this._get(`/api/v1/audit${qs ? `?${qs}` : ''}`);
|
|
}
|
|
|
|
// ── Metrics ─────────────────────────────────────────────────────────────────
|
|
|
|
getMetrics() {
|
|
return this._get('/api/v1/metrics');
|
|
}
|
|
|
|
// ── Settings ────────────────────────────────────────────────────────────────
|
|
|
|
getSettings() {
|
|
return this._get('/api/v1/settings');
|
|
}
|
|
|
|
updateSettings(data) {
|
|
return this._put('/api/v1/settings', data);
|
|
}
|
|
|
|
// ── Onboarding ──────────────────────────────────────────────────────────────
|
|
|
|
startOnboarding(data) {
|
|
return this._post('/api/v1/onboarding/start', data);
|
|
}
|
|
}
|
|
|
|
// ── Factory helper ──────────────────────────────────────────────────────────
|
|
|
|
function createAdminAPI(baseUrl) {
|
|
const token = sessionStorage.getItem('aamos_token') || null;
|
|
return new AdminAPI(baseUrl || window.location.origin, token);
|
|
}
|
|
|
|
// CommonJS / ES-module / browser global
|
|
if (typeof module !== 'undefined' && module.exports) {
|
|
module.exports = { AdminAPI, createAdminAPI };
|
|
} else if (typeof define === 'function' && define.amd) {
|
|
define([], () => ({ AdminAPI, createAdminAPI }));
|
|
} else {
|
|
window.AdminAPI = AdminAPI;
|
|
window.createAdminAPI = createAdminAPI;
|
|
}
|