143 lines
4.1 KiB
JavaScript
143 lines
4.1 KiB
JavaScript
const MERCHANT_TOKEN_KEY = "merchant_token";
|
|
const MERCHANT_ID_KEY = "merchant_id";
|
|
const MERCHANT_USER_KEY = "merchant_user";
|
|
const MERCHANT_AUTH_MODE_KEY = "merchant_auth_mode";
|
|
|
|
function merchantFormatMoney(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 merchantFormatDateTime(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 merchantBuildQuery(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 merchantFetch(path, options = {}) {
|
|
const token = localStorage.getItem(MERCHANT_TOKEN_KEY);
|
|
const merchantId = localStorage.getItem(MERCHANT_ID_KEY);
|
|
const {
|
|
method = "GET",
|
|
query,
|
|
body,
|
|
headers: extraHeaders = {},
|
|
auth = true
|
|
} = options;
|
|
const suffix = merchantBuildQuery(query || {});
|
|
const headers = { ...extraHeaders };
|
|
|
|
if (auth) {
|
|
if (!token) {
|
|
throw new Error("MERCHANT_AUTH_MISSING");
|
|
}
|
|
headers.Authorization = `Bearer ${token}`;
|
|
if (merchantId) {
|
|
headers["X-Merchant-Id"] = merchantId;
|
|
}
|
|
}
|
|
if (method !== "GET" && body !== undefined) {
|
|
headers["Content-Type"] = "application/json";
|
|
}
|
|
|
|
const response = await fetch(suffix ? `${path}?${suffix}` : path, {
|
|
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) {
|
|
throw new Error(payload?.message || payload?.error || `Request failed with status ${response.status}`);
|
|
}
|
|
return payload?.data !== undefined ? payload.data : payload;
|
|
}
|
|
|
|
window.MerchantUIAPI = {
|
|
MERCHANT_TOKEN_KEY,
|
|
MERCHANT_ID_KEY,
|
|
setSession: ({ token, merchant, user, auth_mode }) => {
|
|
localStorage.setItem(MERCHANT_TOKEN_KEY, token);
|
|
localStorage.setItem(MERCHANT_ID_KEY, merchant.id);
|
|
if (user) {
|
|
localStorage.setItem(MERCHANT_USER_KEY, JSON.stringify(user));
|
|
}
|
|
if (auth_mode) {
|
|
localStorage.setItem(MERCHANT_AUTH_MODE_KEY, auth_mode);
|
|
}
|
|
},
|
|
clearSession: () => {
|
|
localStorage.removeItem(MERCHANT_TOKEN_KEY);
|
|
localStorage.removeItem(MERCHANT_ID_KEY);
|
|
localStorage.removeItem(MERCHANT_USER_KEY);
|
|
localStorage.removeItem(MERCHANT_AUTH_MODE_KEY);
|
|
},
|
|
getSessionUser: () => {
|
|
try {
|
|
return JSON.parse(localStorage.getItem(MERCHANT_USER_KEY) || "null");
|
|
} catch (_error) {
|
|
return null;
|
|
}
|
|
},
|
|
getAuthMode: () => localStorage.getItem(MERCHANT_AUTH_MODE_KEY),
|
|
requireSession: () => {
|
|
const token = localStorage.getItem(MERCHANT_TOKEN_KEY);
|
|
const merchantId = localStorage.getItem(MERCHANT_ID_KEY);
|
|
if (!token || !merchantId) {
|
|
window.location.href = "/ui/merchant-login";
|
|
throw new Error("MERCHANT_AUTH_MISSING");
|
|
}
|
|
return { token, merchantId };
|
|
},
|
|
login: async ({ username, password }) => {
|
|
const data = await merchantFetch("/merchant/login", {
|
|
method: "POST",
|
|
auth: false,
|
|
body: { username, password }
|
|
});
|
|
if (data?.token && data?.merchant) {
|
|
window.MerchantUIAPI.setSession(data);
|
|
}
|
|
return data;
|
|
},
|
|
getProfile: async () => {
|
|
const profile = await merchantFetch("/merchant/profile");
|
|
return profile?.merchant || profile;
|
|
},
|
|
getSettlementSummary: () => merchantFetch("/merchant/settlement-summary"),
|
|
listSettlementBatches: (query) => merchantFetch("/merchant/settlement-batches", { query }),
|
|
getSettlementBatch: (id) => merchantFetch(`/merchant/settlement-batches/${id}`),
|
|
formatMoney: merchantFormatMoney,
|
|
formatDateTime: merchantFormatDateTime
|
|
};
|