const API_BASE_URL = "https://jvapi.haiyihy.com"; const icons = { back: "./icons/back.svg", arrow: "./icons/arrow.svg" }; let commonHeaders = { authorization: "Bearer undefined", "req-app-intel": "version=1.0.0;build=1;model=SM-G9550;sysVersion=9;channel=Google", "req-client": "Android", "req-imei": "8fa54d728ab449e04f9292329ed44bda", "req-lang": "id-ID", "req-sys-origin": "origin=ATYOU;originChild=ATYOU", "req-version": "V2", "req-zone": "Asia/Shanghai" }; const i18n = { en: { host_setting: "Host Setting", bank_card: "Bank card", more: "More", add_payment_method: "Add payment method", category: "Category", card_number_label: "Card number", payee: "Payee", kyc: "KYC", review_passed: "Review passed", review_failed: "Review failed", awaiting_review: "Awaiting review", complete_information: "Complete information", passport_id_card_title: "Passport / ID card", contact_number: "Contact number", other_description: "Other description", something_went_wrong: "Something went wrong." }, ar: { host_setting: "إعدادات المضيف", bank_card: "البطاقة البنكية", more: "المزيد", add_payment_method: "إضافة طريقة دفع", category: "الفئة", card_number_label: "رقم البطاقة", payee: "المستفيد", kyc: "KYC", review_passed: "تمت الموافقة", review_failed: "فشل التحقق", awaiting_review: "بانتظار المراجعة", complete_information: "إكمال المعلومات", passport_id_card_title: "جواز السفر / الهوية", contact_number: "رقم التواصل", other_description: "وصف آخر", something_went_wrong: "حدث خطأ ما." }, tr: { host_setting: "Host Ayarı", bank_card: "Banka kartı", more: "Daha fazla", add_payment_method: "Ödeme yöntemi ekle", category: "Kategori", card_number_label: "Kart numarası", payee: "Alacaklı", kyc: "KYC", review_passed: "İnceleme geçti", review_failed: "İnceleme başarısız", awaiting_review: "İnceleme bekliyor", complete_information: "Bilgileri tamamla", passport_id_card_title: "Pasaport / kimlik kartı", contact_number: "İletişim numarası", other_description: "Diğer açıklama", something_went_wrong: "Bir şeyler ters gitti." }, bn: { host_setting: "হোস্ট সেটিং", bank_card: "ব্যাংক কার্ড", more: "আরও", add_payment_method: "পেমেন্ট পদ্ধতি যোগ করুন", category: "ক্যাটাগরি", card_number_label: "কার্ড নম্বর", payee: "প্রাপক", kyc: "KYC", review_passed: "রিভিউ পাস হয়েছে", review_failed: "রিভিউ ব্যর্থ হয়েছে", awaiting_review: "রিভিউ অপেক্ষমাণ", complete_information: "তথ্য সম্পূর্ণ করুন", passport_id_card_title: "পাসপোর্ট / আইডি কার্ড", contact_number: "যোগাযোগ নম্বর", other_description: "অন্যান্য বিবরণ", something_went_wrong: "কিছু ভুল হয়েছে।" } }; const state = { lang: resolveLanguage(), bankCard: null, withdrawInfo: null, profile: {} }; const $ = (selector) => document.querySelector(selector); const $$ = (selector) => Array.from(document.querySelectorAll(selector)); const t = (key) => (i18n[state.lang] && i18n[state.lang][key]) || i18n.en[key] || key; function resolveLanguage() { const params = new URLSearchParams(window.location.search); const hashQuery = window.location.hash.includes("?") ? window.location.hash.split("?")[1] : ""; const hashParams = new URLSearchParams(hashQuery); const lang = params.get("lang") || hashParams.get("lang") || navigator.language || "en"; if (lang.startsWith("ar")) return "ar"; if (lang.startsWith("tr")) return "tr"; if (lang.startsWith("bn")) return "bn"; return "en"; } function splitHeaderPairs(value) { const result = {}; if (!value) return result; value.split(";").forEach((item) => { const index = item.indexOf("="); if (index > -1) result[item.slice(0, index)] = item.slice(index + 1); }); return result; } function parseAccessOrigin(raw) { const data = JSON.parse(raw); const appIntel = splitHeaderPairs(data["Req-App-Intel"]); const sysOrigin = splitHeaderPairs(data["Req-Sys-Origin"]); return { reqLang: data["Req-Lang"], authorization: data.Authorization, buildVersion: appIntel.build, appVersion: appIntel.version, appChannel: appIntel.channel, reqImei: appIntel["Req-Imei"], sysOrigin: sysOrigin.origin, sysOriginChild: sysOrigin.child }; } function setHeadersFromApp(headers) { const next = {}; if (headers.authorization) next.authorization = headers.authorization; if (headers.reqLang) next["req-lang"] = headers.reqLang; if (headers.appVersion || headers.buildVersion || headers.appChannel) { const intel = []; if (headers.appVersion) intel.push(`version=${headers.appVersion}`); if (headers.buildVersion) intel.push(`build=${headers.buildVersion}`); if (headers.appChannel) intel.push(`channel=${headers.appChannel}`); next["req-app-intel"] = intel.join(";"); } if (headers.reqImei) next["req-imei"] = headers.reqImei; if (headers.sysOrigin) { const origin = [`origin=${headers.sysOrigin}`]; if (headers.sysOriginChild) origin.push(`child=${headers.sysOriginChild}`); next["req-sys-origin"] = origin.join(";"); } commonHeaders = { ...commonHeaders, ...next }; } function connectToApp() { return new Promise((resolve) => { window.renderData = resolve; window.getIosAccessOriginParam = resolve; if (!(window.app || window.webkit || window.FlutterPageControl)) { resolve({ success: true, environment: "browser" }); return; } let attempt = 0; const poll = () => { attempt += 1; if (window.app && typeof window.app.getAccessOrigin === "function") { const raw = window.app.getAccessOrigin(); if (raw) setHeadersFromApp(parseAccessOrigin(raw)); resolve({ success: true, environment: "app" }); return; } if (attempt < 50) { window.setTimeout(poll, 100); return; } if (window.FlutterApp && typeof window.FlutterApp.postMessage === "function") { window.FlutterApp.postMessage("requestAccessOrigin"); } resolve({ success: true, environment: "app" }); }; poll(); }).then((result) => { if (typeof result === "string") { setHeadersFromApp(parseAccessOrigin(result)); return { success: true, environment: "app" }; } return result; }); } async function apiGet(path) { const response = await fetch(`${API_BASE_URL}${path}`, { method: "GET", headers: commonHeaders }); const data = await response.json().catch(() => ({})); if (!response.ok || data.status === false) { const error = new Error(data.errorMsg || data.message || `Request failed: ${response.status}`); error.response = data; throw error; } return data; } async function fetchUserProfile() { const cached = localStorage.getItem("userProfile"); if (cached) { try { state.profile = JSON.parse(cached) || {}; } catch (error) { console.error("Failed to parse userProfile:", error); } } try { const result = await apiGet("/team/member/profile"); if (result.status && result.body) { state.profile = result.body; localStorage.setItem("userProfile", JSON.stringify(result.body)); } } catch (error) { console.error("Failed to fetch user profile:", error); } } function getMemberId() { return state.profile.id || state.profile.userId || state.profile.account || null; } function calculateRoles(identity) { if (!identity) return ["guest"]; const roles = []; if (identity.freightAgent) roles.push("freightAgent"); if (identity.agent) roles.push("agent"); if (identity.bdLeader) roles.push("bdLeader"); if (identity.bd) roles.push("bd"); if (identity.anchor) roles.push("anchor"); if (identity.admin) roles.push("admin"); return roles.length ? roles : ["guest"]; } function getPrimaryRole(roles) { const weight = { guest: 0, anchor: 1, agent: 2, bd: 3, bdLeader: 4, freightAgent: 5, admin: 6 }; return roles.reduce((current, role) => (weight[role] > weight[current] ? role : current), "guest"); } function getDefaultPage(role) { return { admin: "/admin-center", freightAgent: "/coin-seller", agent: "/agency-center", bdLeader: "/bd-leader-center", bd: "/bd-center", anchor: "/host-center", guest: "/apply" }[role] || "/apply"; } async function checkIdentityAndRedirect() { const memberId = getMemberId(); if (!memberId) { navigateTo("/apply"); return; } const result = await apiGet("/app/h5/identity"); if (!result.status || !result.body) return; const roles = calculateRoles(result.body); if (!roles.includes("anchor")) { navigateTo(getDefaultPage(getPrimaryRole(roles))); } } async function fetchBankCards() { const result = await apiGet("/wallet/bank-card/list"); if (result.status && result.body) { state.bankCard = result.body.find((item) => item.use) || null; } } async function fetchWithdrawInfo() { const result = await apiGet("/wallet/withdraw-info/list"); if (result.status && result.body && result.body.length > 0) { const first = result.body[0]; let previewUrls = []; try { previewUrls = JSON.parse(first.passportFrontUrl || "[]").map((item) => item); } catch (error) { console.error("Failed to parse passportFrontUrl:", error); } state.withdrawInfo = { previewUrls, ...first }; } } function normalizeRoute(target) { const url = new URL(target, window.location.origin); const currentLang = new URLSearchParams(window.location.search).get("lang"); if (currentLang && !url.searchParams.has("lang")) url.searchParams.set("lang", currentLang); return `${url.pathname}${url.search}${url.hash}`; } function navigateTo(target) { window.location.href = normalizeRoute(target); } function closePage() { if (window.history.length > 1) { window.history.back(); return; } if (window.app && typeof window.app.closePage === "function") { window.app.closePage(); return; } if (window.FlutterPageControl && typeof window.FlutterPageControl.postMessage === "function") { window.FlutterPageControl.postMessage("close_page"); } } function showToast(message) { const toast = $("#toast"); toast.textContent = message; toast.hidden = false; window.clearTimeout(showToast.timer); showToast.timer = window.setTimeout(() => { toast.hidden = true; }, 2500); } function renderI18n() { document.documentElement.lang = state.lang; document.documentElement.dir = state.lang === "ar" ? "rtl" : "ltr"; $("[data-action='language']").textContent = state.lang.toUpperCase(); $$("[data-i18n]").forEach((node) => { node.textContent = t(node.dataset.i18n); }); } function renderIcons() { $("#backIcon").src = icons.back; ["#bankAddArrow", "#kycHeaderArrow", "#kycAddArrow"].forEach((selector) => { $(selector).src = icons.arrow; }); } function renderBankCard() { const hasCard = Boolean(state.bankCard); $("#bankMoreButton").hidden = !hasCard; $("#addBankCardRow").hidden = hasCard; $("#bankDetail").hidden = !hasCard; if (!hasCard) return; $("#cardType").textContent = state.bankCard.cardType || "-"; $("#cardNo").textContent = state.bankCard.cardNo || "-"; $("#payee").textContent = state.bankCard.payee || "-"; } function renderKyc() { const info = state.withdrawInfo; const hasInfo = Boolean(info); $("#kycColon").hidden = !hasInfo; $("#kycStatus").hidden = !hasInfo; $("#kycHeaderButton").hidden = !hasInfo; $("#completeKycRow").hidden = hasInfo; $("#kycDetail").hidden = !hasInfo; if (!hasInfo) return; const status = $("#kycStatus"); status.className = "status-text"; if (info.status === "PASS") { status.textContent = t("review_passed"); status.classList.add("status-pass"); } else if (info.status === "NOT_PASS") { status.textContent = t("review_failed"); status.classList.add("status-failed"); } else if (info.status === "PENDING") { status.textContent = t("awaiting_review"); status.classList.add("status-pending"); } else { status.textContent = info.status || ""; } const previewList = $("#previewList"); previewList.innerHTML = ""; (info.previewUrls || []).forEach((url) => { const image = document.createElement("img"); image.src = url; image.alt = ""; previewList.appendChild(image); }); $("#contactNumber").textContent = info.contactNumber || "-"; $("#otherDescription").textContent = info.otherDescription || "-"; } function render() { renderI18n(); renderIcons(); renderBankCard(); renderKyc(); } function bindEvents() { $("[data-action='back']").addEventListener("click", closePage); $("[data-action='language']").addEventListener("click", () => navigateTo("/language")); $$("[data-route]").forEach((node) => { node.addEventListener("click", () => navigateTo(node.dataset.route)); }); } async function runTask(task, label) { try { await task(); } catch (error) { console.error(`${label} failed:`, error); if (label === "withdraw info") showToast(error.response?.errorMsg || error.message || t("something_went_wrong")); } } async function init() { localStorage.setItem("identity", JSON.stringify({ identity: "HOST" })); bindEvents(); render(); try { await connectToApp(); await fetchUserProfile(); await runTask(checkIdentityAndRedirect, "identity check"); await Promise.all([ runTask(fetchBankCards, "bank cards"), runTask(fetchWithdrawInfo, "withdraw info") ]); } catch (error) { console.error("Host setting initialization failed:", error); showToast(error.response?.errorMsg || error.message || t("something_went_wrong")); } finally { render(); } } init();