Initial commit
This commit is contained in:
142
ui/shared/admin-api.js
Normal file
142
ui/shared/admin-api.js
Normal file
@ -0,0 +1,142 @@
|
||||
const ADMIN_TOKEN_KEY = "admin_token";
|
||||
|
||||
function formatMoney(value) {
|
||||
const number = Number(value || 0);
|
||||
if (!Number.isFinite(number)) {
|
||||
return "Rp 0";
|
||||
}
|
||||
return new Intl.NumberFormat("id-ID", {
|
||||
style: "currency",
|
||||
currency: "IDR",
|
||||
maximumFractionDigits: 0
|
||||
}).format(number);
|
||||
}
|
||||
|
||||
function formatDateTime(value) {
|
||||
if (!value) {
|
||||
return "-";
|
||||
}
|
||||
|
||||
const date = new Date(value);
|
||||
if (Number.isNaN(date.getTime())) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return new Intl.DateTimeFormat("en-GB", {
|
||||
dateStyle: "medium",
|
||||
timeStyle: "short"
|
||||
}).format(date);
|
||||
}
|
||||
|
||||
function buildQuery(query) {
|
||||
const search = new URLSearchParams();
|
||||
Object.entries(query || {}).forEach(([key, val]) => {
|
||||
if (val !== undefined && val !== null && val !== "") {
|
||||
search.append(key, String(val));
|
||||
}
|
||||
});
|
||||
return search.toString();
|
||||
}
|
||||
|
||||
async function adminFetch(path, options = {}) {
|
||||
const token = localStorage.getItem(ADMIN_TOKEN_KEY);
|
||||
const {
|
||||
method = "GET",
|
||||
query,
|
||||
body,
|
||||
headers: extraHeaders = {},
|
||||
auth = true
|
||||
} = options;
|
||||
|
||||
const suffix = buildQuery(query || {});
|
||||
const url = suffix ? `${path}?${suffix}` : path;
|
||||
const headers = {
|
||||
...extraHeaders
|
||||
};
|
||||
|
||||
if (auth) {
|
||||
if (!token) {
|
||||
throw new Error("ADMIN_AUTH_MISSING");
|
||||
}
|
||||
headers.Authorization = `Bearer ${token}`;
|
||||
}
|
||||
|
||||
if (method !== "GET" && body !== undefined) {
|
||||
headers["Content-Type"] = "application/json";
|
||||
}
|
||||
|
||||
const response = await fetch(url, {
|
||||
method,
|
||||
headers,
|
||||
body: method === "GET" || body === undefined ? undefined : JSON.stringify(body)
|
||||
});
|
||||
|
||||
const raw = await response.text();
|
||||
let payload;
|
||||
try {
|
||||
payload = raw ? JSON.parse(raw) : {};
|
||||
} catch (error) {
|
||||
payload = {};
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
const message =
|
||||
payload?.message ||
|
||||
payload?.error ||
|
||||
`Request failed with status ${response.status}`;
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
return payload?.data !== undefined ? payload.data : payload;
|
||||
}
|
||||
|
||||
window.AdminUIAPI = {
|
||||
ADMIN_TOKEN_KEY,
|
||||
setToken: (token) => localStorage.setItem(ADMIN_TOKEN_KEY, token),
|
||||
getToken: () => localStorage.getItem(ADMIN_TOKEN_KEY),
|
||||
clearToken: () => localStorage.removeItem(ADMIN_TOKEN_KEY),
|
||||
requireToken: () => {
|
||||
const token = localStorage.getItem(ADMIN_TOKEN_KEY);
|
||||
if (!token) {
|
||||
window.location.href = "/ui/admin-login";
|
||||
throw new Error("ADMIN_AUTH_MISSING");
|
||||
}
|
||||
return token;
|
||||
},
|
||||
login: async ({ username, password }) => {
|
||||
const data = await adminFetch("/admin/login", {
|
||||
method: "POST",
|
||||
auth: false,
|
||||
body: { username, password }
|
||||
});
|
||||
if (data?.token) {
|
||||
window.AdminUIAPI.setToken(data.token);
|
||||
}
|
||||
return data;
|
||||
},
|
||||
listMerchants: () => adminFetch("/admin/merchants"),
|
||||
listOutlets: (query) => adminFetch("/admin/outlets", { query }),
|
||||
getOutlet: (id) => adminFetch(`/admin/outlets/${id}`),
|
||||
getMerchant: (id) => adminFetch(`/admin/merchants/${id}`),
|
||||
patchMerchant: (id, payload) =>
|
||||
adminFetch(`/admin/merchants/${id}`, {
|
||||
method: "PATCH",
|
||||
body: payload
|
||||
}),
|
||||
approveMerchant: (id) => adminFetch(`/admin/merchants/${id}/approve`, { method: "POST" }),
|
||||
rejectMerchant: (id, payload) =>
|
||||
adminFetch(`/admin/merchants/${id}/reject`, {
|
||||
method: "POST",
|
||||
body: payload || {}
|
||||
}),
|
||||
listTerminals: (query) => adminFetch("/admin/terminals", { query }),
|
||||
getTerminal: (id) => adminFetch(`/admin/terminals/${id}`),
|
||||
listDevices: (query) => adminFetch("/admin/devices", { query }),
|
||||
getDevice: (id) => adminFetch(`/admin/devices/${id}`),
|
||||
getDeviceHeartbeats: (id, query) =>
|
||||
adminFetch(`/admin/devices/${id}/heartbeats`, { query }),
|
||||
listTransactions: (query) => adminFetch("/admin/transactions", { query }),
|
||||
getDashboardSummary: () => adminFetch("/admin/dashboard/summary"),
|
||||
formatMoney,
|
||||
formatDateTime
|
||||
};
|
||||
Reference in New Issue
Block a user