import { applyLang, bindHeader, connectToApp, createMask, get, money, navigateTo, post, safeJsonArray, t, toast } from "../bd-static/shared.js?v=20260507-1740";
const query = new URLSearchParams(window.location.search);
const CASH_OUT_MIN_AMOUNT = 50;
const state = {
identity: readIdentity(),
activeAction: query.get("activeAction") || "Exchange",
salaryTab: 0,
balances: { ADMIN_SALARY: {}, BD_SALARY: {}, BD_LEADER_SALARY: {}, TOTAL: {} },
payee: readPayee(),
kyc: null,
bankCard: null,
transferId: null,
exchangeId: null,
cashAmount: null
};
const transfers = [
{ id: 1, amount: 10500, price: 1 },
{ id: 2, amount: 52500, price: 5 },
{ id: 3, amount: 105000, price: 10 },
{ id: 4, amount: 525000, price: 50 },
{ id: 5, amount: 1050000, price: 100 },
{ id: 6, amount: 2100000, price: 200 }
];
const exchanges = transfers.map((item) => ({ id: item.id, coins: item.amount, cash: item.price }));
const actions = [
{ name: "Exchange", lang: "exchange" },
{ name: "Transfer", lang: "transfer" },
{ name: "Cash out", lang: "cash_out" }
];
bindHeader("available_salaries");
applyLang();
document.getElementById("detailsButton").addEventListener("click", () => navigateTo("/income-details"));
async function init() {
try {
await connectToApp();
await Promise.all([loadBalances(), loadKyc(), loadCards()]);
} catch (error) {
toast(error.response?.errorMsg || error.message || t("failed_to_load_balance"));
} finally {
render();
}
}
function readIdentity() {
try {
const data = JSON.parse(localStorage.getItem("identity") || "{}");
return data.identity || data.primaryRole || localStorage.getItem("userIdentity") || "BD";
} catch {
return "BD";
}
}
function readPayee() {
for (const storage of [sessionStorage, localStorage]) {
try {
const value = storage.getItem("transfer.payee") || storage.getItem("payee");
if (value) return JSON.parse(value);
} catch {}
}
return { id: null, account: "", name: "", avatar: "", type: "", isHost: false, isAgency: false, hasSalary: false };
}
async function loadBalances() {
if (state.identity === "ADMIN") {
state.balances.ADMIN_SALARY = await balance("ADMIN_SALARY");
} else if (state.identity === "BD_LEADER") {
const [total, leader, bd] = await Promise.all([get("/wallet/salary-account/balance/total"), balance("BD_LEADER_SALARY"), balance("BD_SALARY")]);
state.balances.TOTAL = total.body || {};
state.balances.BD_LEADER_SALARY = leader;
state.balances.BD_SALARY = bd;
} else {
state.balances.BD_SALARY = await balance("BD_SALARY");
}
}
async function balance(type) {
const response = await get(`/wallet/salary-account/balance?salaryType=${type}`);
return response.status && response.body ? response.body : {};
}
async function loadKyc() {
const response = await get("/wallet/withdraw-info/list");
const body = response.status && Array.isArray(response.body) ? response.body : [];
state.kyc = body.length > 0 ? { ...body[0], previewUrls: safeJsonArray(body[0].passportFrontUrl) } : null;
}
async function loadCards() {
const response = await get("/wallet/bank-card/list");
const body = response.status && Array.isArray(response.body) ? response.body : [];
state.bankCard = body.find((item) => item.use) || null;
}
function salaryType() {
if (state.identity === "ADMIN") return "ADMIN_SALARY";
if (state.identity === "BD_LEADER") return state.salaryTab === 0 ? "BD_SALARY" : "BD_LEADER_SALARY";
return "BD_SALARY";
}
function visibleBalance() {
if (state.identity === "BD_LEADER") return state.balances.TOTAL.availableBalance || 0;
return state.balances[salaryType()]?.availableBalance || 0;
}
function operatingBalance() {
return state.balances[salaryType()]?.availableBalance || 0;
}
function render() {
document.getElementById("totalBalance").textContent = `$${money(visibleBalance())}`;
renderIdentitySwitch();
renderActions();
renderPanel();
}
function renderIdentitySwitch() {
const holder = document.getElementById("identitySwitch");
if (state.identity !== "BD_LEADER") {
holder.hidden = true;
return;
}
holder.hidden = false;
const rows = [
{ label: t("bd"), detail: t("my_bd_salary"), salary: state.balances.BD_SALARY.availableBalance || 0 },
{ label: t("bd_leader"), detail: t("my_bd_leader_salary"), salary: state.balances.BD_LEADER_SALARY.availableBalance || 0 }
];
holder.innerHTML = `
${rows.map((row, index) => ``).join("")}
${rows[state.salaryTab].detail}
$${money(rows[state.salaryTab].salary)}
`;
holder.querySelectorAll("[data-salary]").forEach((button) => {
button.addEventListener("click", () => {
state.salaryTab = Number(button.dataset.salary);
state.transferId = null;
state.exchangeId = null;
render();
});
});
}
function renderActions() {
const nav = document.getElementById("actionTabs");
nav.innerHTML = actions.map((item) => ``).join("");
nav.querySelectorAll("[data-action-name]").forEach((button) => {
button.addEventListener("click", () => {
state.activeAction = button.dataset.actionName;
state.transferId = null;
state.exchangeId = null;
render();
});
});
}
function renderPanel() {
if (state.activeAction === "Transfer") renderTransfer();
else if (state.activeAction === "Cash out") renderCashOut();
else renderExchange();
}
function renderTransfer() {
const panel = document.getElementById("actionPanel");
panel.innerHTML = `
${transfers.map((item) => ``).join("")}
`;
panel.querySelectorAll("[data-transfer]").forEach((button) => button.addEventListener("click", () => {
const id = Number(button.dataset.transfer);
state.transferId = state.transferId === id ? null : id;
renderTransfer();
}));
document.getElementById("payeeButton").addEventListener("click", () => navigateTo("/search-payee?from=/available-income&activeAction=Transfer"));
const transferButton = document.getElementById("transferButton");
transferButton.disabled = !(state.transferId && state.payee?.id);
transferButton.addEventListener("click", submitTransfer);
}
function payeeHtml(payee) {
return `
${payee.name || "-"}
${t("user_id_prefix")}${payee.goodID || payee.account || "-"}
`;
}
function renderExchange() {
const panel = document.getElementById("actionPanel");
panel.innerHTML = `
${exchanges.map((item) => ``).join("")}
`;
panel.querySelectorAll("[data-exchange]").forEach((button) => button.addEventListener("click", () => {
const id = Number(button.dataset.exchange);
state.exchangeId = state.exchangeId === id ? null : id;
renderExchange();
}));
document.getElementById("exchangeButton").addEventListener("click", confirmExchange);
}
function renderCashOut() {
const panel = document.getElementById("actionPanel");
const status = state.kyc?.status;
panel.innerHTML = `
${t("kyc")}${state.kyc ? `: ${statusLabel(status)}` : ""}
${state.kyc ? kycHtml(state.kyc) : ``}
`;
const completeKyc = document.getElementById("completeKyc");
if (completeKyc) completeKyc.addEventListener("click", () => navigateTo("/bank-cards?from=/available-income&activeAction=Cash out"));
const editKyc = document.getElementById("editKyc");
if (editKyc) editKyc.addEventListener("click", () => navigateTo("/bank-cards?from=/available-income&activeAction=Cash out"));
document.getElementById("cashButton").addEventListener("click", () => {
if (state.kyc && state.kyc.status === "PASS") openCashSheet();
else if (!state.kyc) openImproveDialog();
});
}
function statusLabel(status) {
if (status === "PASS") return `${t("review_passed")}`;
if (status === "NOT_PASS") return `${t("review_failed")}`;
if (status === "PENDING") return `${t("awaiting_review")}`;
return "";
}
function kycHtml(item) {
return `
${t("passport_id_card_title")}:
${(item.previewUrls || []).map((src) => `

`).join("")}
${t("contact_number")}:
${item.contactNumber || ""}
${t("other_description")}:
${item.otherDescription || ""}
`;
}
async function submitTransfer() {
const item = transfers.find((entry) => entry.id === state.transferId);
if (!item) return toast(t("please_select_amount"));
if (!state.payee?.id) return toast(t("please_select_payee"));
try {
const response = await post("/wallet/salary-account/transferGold", { amount: item.price, acceptUserId: state.payee.id, salaryType: salaryType() });
if (response.status) {
toast(t("transfer_dollar_success"));
state.transferId = null;
await loadBalances();
render();
}
} catch (error) {
toast(error.response?.errorMsg || t("transfer_error"));
}
}
function confirmExchange() {
if (!state.exchangeId) return toast(t("please_select_coin_amount"));
const panel = document.createElement("section");
panel.className = "card card-pad";
panel.style.cssText = "width:80%;margin:32vh auto 0;text-align:center";
panel.innerHTML = `
${t("tips")}
${t("confirm_exchange")}
`;
const mask = createMask(panel);
panel.querySelector("#cancelExchange").addEventListener("click", () => mask.remove());
panel.querySelector("#confirmExchange").addEventListener("click", () => submitExchange(mask));
}
async function submitExchange(mask) {
const item = exchanges.find((entry) => entry.id === state.exchangeId);
try {
const response = await post("/wallet/salary-account/exchange/gold", { amount: item.cash, salaryType: salaryType() });
if (response.status === true || response.errorCode === 0) {
mask.remove();
toast(t("exchange_success"));
state.exchangeId = null;
await loadBalances();
render();
}
} catch (error) {
mask.remove();
toast(error.response?.errorMsg || t("exchange_error_occurred"));
}
}
function openImproveDialog() {
const panel = document.createElement("section");
panel.className = "card card-pad";
panel.style.cssText = "width:80%;margin:30vh auto 0;text-align:center";
panel.innerHTML = `
${t("prompt")}
${t("fill_info_tips")}
${t("card_issue_tips")}
`;
createMask(panel);
panel.querySelector("#improveButton").addEventListener("click", () => navigateTo("/bank-cards?from=/available-income&activeAction=Cash out"));
}
function openCashSheet() {
const panel = document.createElement("section");
panel.className = "sheet";
panel.innerHTML = `
${t("cash_out")}
${t("withdrawal_method")}: ${state.bankCard?.cardType || ""}
${state.bankCard ? `
${t("card_number")}: ${state.bankCard.cardNo || ""}
` : ""}
${t("cash_out_minimum")}
`;
const mask = createMask(panel);
const input = panel.querySelector("#cashInput");
input.addEventListener("input", () => {
let value = input.value.replace(/[^\d.]/g, "");
const parts = value.split(".");
if (parts.length > 2) value = `${parts[0]}.${parts.slice(1).join("")}`;
if (Number(value) > operatingBalance()) value = String(operatingBalance());
input.value = value;
state.cashAmount = Number(value) || null;
});
panel.querySelector("#changeCard").addEventListener("click", () => navigateTo("/bank-cards?from=/available-income&activeAction=Cash out"));
panel.querySelector("#submitCash").addEventListener("click", () => submitCash(mask));
}
async function submitCash(mask) {
if (!(state.kyc?.status === "PASS" && state.bankCard?.id && state.cashAmount >= CASH_OUT_MIN_AMOUNT)) {
if (!state.bankCard?.id && state.cashAmount >= CASH_OUT_MIN_AMOUNT) {
mask.remove();
openImproveDialog();
}
return;
}
try {
const response = await post("/wallet/bank/withdraw", { amount: state.cashAmount, acceptBankCardId: state.bankCard.id, salaryType: salaryType() });
if (response.status) {
mask.remove();
await loadBalances();
openSuccessDialog();
render();
}
} catch (error) {
mask.remove();
toast(t("something_went_wrong"));
}
}
function openSuccessDialog() {
const panel = document.createElement("section");
panel.className = "card card-pad";
panel.style.cssText = "width:80%;margin:34vh auto 0;text-align:center";
panel.innerHTML = `${t("tips")}
${t("cash_withdrawal_tips")}
`;
createMask(panel);
}
init();