1674 lines
59 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

(function () {
const supportedLanguages = ["en", "ar", "tr", "id"];
const languageLabels = {
en: "EN",
ar: "AR",
tr: "TR",
id: "ID"
};
const API_BASE_URL = "https://jvapi.haiyihy.com";
const GO_API_PATH_PREFIX = "/go";
const LOCAL_GO_API_BASE_URL = "http://127.0.0.1:1100";
const defaultPropsType = "RIDE";
// 后端经理中心 VIP 赠送默认 30 天;接口缺 days 时前端兜底展示同一口径。
const defaultNobleVIPGiftDays = 30;
const fallbackMessages = {
en: {
document_title: "Manager Center",
page_label: "Manager Center",
back: "Back",
title: "Manager Center",
language_button_aria: "Change language",
close: "Close",
current_manager: "Current Manager",
user: "User",
user_search_placeholder: "Enter user ID or account",
search: "Search",
searching: "Searching...",
target_user: "Target User",
current_country: "Current country",
change_country: "Change Country",
change_country_disabled: "Change Country disabled",
select_country: "Select country",
changing_country: "Changing...",
country_changed: "Country changed",
no_countries: "No countries available",
bd_leaders: "BD Leaders",
bd_leader_count: "{count} BD Leaders",
refresh: "Refresh",
refreshing: "Refreshing...",
no_bd_leaders: "No BD Leaders yet",
add_bd_leader: "Add BD Leader",
add_bd_leader_disabled: "Add BD Leader disabled",
adding_bd_leader: "Adding...",
add_bd_leader_success: "BD Leader added",
gift_props: "Gift Props",
gift_props_disabled: "Gift Props disabled",
gift_type: "Gift Type",
prop_type_ride: "Ride",
prop_type_noble_vip: "Noble VIP",
prop_type_avatar_frame: "Avatar Frame",
prop_type_badge: "Badge",
prop_type_chat_bubble: "Chat Bubble",
prop_type_data_card: "Profile Card",
no_giftable_props: "No giftable props",
send: "Send",
sending: "Sending...",
send_success: "Sent successfully",
ban_user: "Ban User",
ban_user_disabled: "Ban User disabled",
ban_reason: "Ban reason",
ban: "Ban",
submitting: "Submitting...",
ban_success: "User banned",
unban_user: "Unban User",
unban_user_disabled: "Unban User disabled",
unban_reason: "Unban reason",
unban: "Unban",
unban_success: "User unbanned",
can_unban: "Can unban",
cannot_unban: "Cannot unban",
loading: "Loading...",
uid_label: "UID",
days: "{count} days",
recharged: "Recharged",
not_recharged: "Not recharged",
recharge_unknown: "Recharge unknown",
can_ban: "Can ban",
cannot_ban: "Cannot ban",
missing_token: "Missing token",
not_manager: "Current account is not a manager",
user_not_found: "User not found",
user_recharged: "This user has recharge records and cannot be banned",
user_already_banned: "This user is already banned",
user_not_banned: "This user is not banned",
manager_region_required: "Manager region is required",
bd_leader_origin_mismatch: "The user is not in this manager's origin",
user_is_admin: "Admin users cannot be added as BD Leaders",
user_already_bd_leader: "This user is already a BD Leader",
user_already_bound_bd_leader: "This user is already bound to a BD Leader",
user_identity_locked: "This user has Host, Agency, BD, BD Leader, or Coin Seller identity and cannot be moved",
country_not_found: "Country not found",
country_required: "Select country",
prop_not_giftable: "This prop is not available for manager gifting",
vip_not_giftable: "This noble prop cannot be gifted",
manager_feature_disabled: "This feature is disabled by admin",
request_failed: "Request failed",
enter_user: "Enter user ID or account"
},
ar: {
document_title: "مركز المدير",
page_label: "مركز المدير",
back: "رجوع",
title: "مركز المدير",
language_button_aria: "تغيير اللغة",
close: "إغلاق",
current_manager: "المدير الحالي",
user: "المستخدم",
user_search_placeholder: "أدخل معرّف المستخدم أو الحساب",
search: "بحث",
searching: "جار البحث...",
target_user: "المستخدم المستهدف",
current_country: "Current country",
change_country: "Change Country",
change_country_disabled: "Change Country disabled",
select_country: "Select country",
changing_country: "Changing...",
country_changed: "Country changed",
no_countries: "No countries available",
bd_leaders: "قادة BD",
bd_leader_count: "{count} قادة BD",
refresh: "تحديث",
refreshing: "جار التحديث...",
no_bd_leaders: "لا يوجد قادة BD بعد",
add_bd_leader: "إضافة قائد BD",
add_bd_leader_disabled: "إضافة قائد BD معطلة",
adding_bd_leader: "جار الإضافة...",
add_bd_leader_success: "تمت إضافة قائد BD",
gift_props: "إرسال العناصر",
gift_props_disabled: "إرسال العناصر معطل",
gift_type: "نوع الهدية",
prop_type_ride: "مركبة",
prop_type_noble_vip: "VIP نبيل",
prop_type_avatar_frame: "إطار الصورة",
prop_type_badge: "شارة",
prop_type_chat_bubble: "فقاعة الدردشة",
prop_type_data_card: "بطاقة الملف",
no_giftable_props: "لا توجد عناصر قابلة للإهداء",
send: "إرسال",
sending: "جار الإرسال...",
send_success: "تم الإرسال بنجاح",
ban_user: "حظر المستخدم",
ban_user_disabled: "حظر المستخدم معطل",
ban_reason: "سبب الحظر",
ban: "حظر",
submitting: "جار الإرسال...",
ban_success: "تم حظر المستخدم",
unban_user: "إلغاء حظر المستخدم",
unban_user_disabled: "إلغاء حظر المستخدم معطل",
unban_reason: "سبب إلغاء الحظر",
unban: "إلغاء الحظر",
unban_success: "تم إلغاء حظر المستخدم",
can_unban: "يمكن إلغاء الحظر",
cannot_unban: "لا يمكن إلغاء الحظر",
loading: "جار التحميل...",
uid_label: "UID",
days: "{count} يوم",
recharged: "تم الشحن",
not_recharged: "لم يتم الشحن",
recharge_unknown: "حالة الشحن غير معروفة",
can_ban: "يمكن الحظر",
cannot_ban: "لا يمكن الحظر",
missing_token: "رمز الدخول مفقود",
not_manager: "الحساب الحالي ليس مديرًا",
user_not_found: "المستخدم غير موجود",
user_recharged: "لدى هذا المستخدم سجلات شحن ولا يمكن حظره",
user_already_banned: "هذا المستخدم محظور بالفعل",
user_not_banned: "هذا المستخدم غير محظور",
manager_region_required: "منطقة المدير مطلوبة",
bd_leader_origin_mismatch: "المستخدم ليس ضمن نظام هذا المدير",
user_is_admin: "لا يمكن إضافة مستخدم إداري كقائد BD",
user_already_bd_leader: "هذا المستخدم قائد BD بالفعل",
user_already_bound_bd_leader: "هذا المستخدم مرتبط بالفعل بقائد BD",
user_identity_locked: "This user has Host, Agency, BD, BD Leader, or Coin Seller identity and cannot be moved",
country_not_found: "Country not found",
country_required: "Select country",
prop_not_giftable: "هذا العنصر غير متاح كهديّة من المدير",
vip_not_giftable: "لا يمكن إهداء عنصر VIP هذا",
manager_feature_disabled: "تم تعطيل هذه الميزة من الإدارة",
request_failed: "فشل الطلب",
enter_user: "أدخل معرّف المستخدم أو الحساب"
},
tr: {
document_title: "Yönetici Merkezi",
page_label: "Yönetici Merkezi",
back: "Geri",
title: "Yönetici Merkezi",
language_button_aria: "Dili değiştir",
close: "Kapat",
current_manager: "Mevcut Yönetici",
user: "Kullanıcı",
user_search_placeholder: "Kullanıcı ID veya hesap gir",
search: "Ara",
searching: "Aranıyor...",
target_user: "Hedef Kullanıcı",
current_country: "Current country",
change_country: "Change Country",
change_country_disabled: "Change Country disabled",
select_country: "Select country",
changing_country: "Changing...",
country_changed: "Country changed",
no_countries: "No countries available",
bd_leaders: "BD Liderleri",
bd_leader_count: "{count} BD Lideri",
refresh: "Yenile",
refreshing: "Yenileniyor...",
no_bd_leaders: "Henüz BD lideri yok",
add_bd_leader: "BD Lideri Ekle",
add_bd_leader_disabled: "BD lideri ekleme kapalı",
adding_bd_leader: "Ekleniyor...",
add_bd_leader_success: "BD lideri eklendi",
gift_props: "Eşya Gönder",
gift_props_disabled: "Eşya gönderme kapalı",
gift_type: "Hediye Türü",
prop_type_ride: "Araç",
prop_type_noble_vip: "Noble VIP",
prop_type_avatar_frame: "Avatar Çerçevesi",
prop_type_badge: "Rozet",
prop_type_chat_bubble: "Sohbet Balonu",
prop_type_data_card: "Profil Kartı",
no_giftable_props: "Gönderilebilir eşya yok",
send: "Gönder",
sending: "Gönderiliyor...",
send_success: "Başarıyla gönderildi",
ban_user: "Kullanıcıyı Yasakla",
ban_user_disabled: "Kullanıcı yasaklama kapalı",
ban_reason: "Yasaklama nedeni",
ban: "Yasakla",
submitting: "Gönderiliyor...",
ban_success: "Kullanıcı yasaklandı",
unban_user: "Yasağı Kaldır",
unban_user_disabled: "Yasak kaldırma kapalı",
unban_reason: "Yasağı kaldırma nedeni",
unban: "Yasağı kaldır",
unban_success: "Kullanıcının yasağı kaldırıldı",
can_unban: "Yasak kaldırılabilir",
cannot_unban: "Yasak kaldırılamaz",
loading: "Yükleniyor...",
uid_label: "UID",
days: "{count} gün",
recharged: "Yükleme yaptı",
not_recharged: "Yükleme yapmadı",
recharge_unknown: "Yükleme durumu bilinmiyor",
can_ban: "Yasaklanabilir",
cannot_ban: "Yasaklanamaz",
missing_token: "Token eksik",
not_manager: "Mevcut hesap yönetici değil",
user_not_found: "Kullanıcı bulunamadı",
user_recharged: "Bu kullanıcının yükleme kaydı var, yasaklanamaz",
user_already_banned: "Bu kullanıcı zaten yasaklı",
user_not_banned: "Bu kullanıcı yasaklı değil",
manager_region_required: "Yönetici bölgesi gerekli",
bd_leader_origin_mismatch: "Kullanıcı bu yöneticinin origin değerinde değil",
user_is_admin: "Admin kullanıcılar BD lideri eklenemez",
user_already_bd_leader: "Bu kullanıcı zaten BD lideri",
user_already_bound_bd_leader: "Bu kullanıcı zaten bir BD liderine bağlı",
user_identity_locked: "This user has Host, Agency, BD, BD Leader, or Coin Seller identity and cannot be moved",
country_not_found: "Country not found",
country_required: "Select country",
prop_not_giftable: "Bu eşya yönetici hediyesi için açık değil",
vip_not_giftable: "Bu noble eşyası gönderilemez",
manager_feature_disabled: "Bu özellik admin tarafından kapatıldı",
request_failed: "İstek başarısız",
enter_user: "Kullanıcı ID veya hesap gir"
},
id: {
document_title: "Pusat Manajer",
page_label: "Pusat Manajer",
back: "Kembali",
title: "Pusat Manajer",
language_button_aria: "Ubah bahasa",
close: "Tutup",
current_manager: "Manajer Saat Ini",
user: "Pengguna",
user_search_placeholder: "Masukkan ID pengguna atau akun",
search: "Cari",
searching: "Mencari...",
target_user: "Pengguna Target",
current_country: "Current country",
change_country: "Change Country",
change_country_disabled: "Change Country disabled",
select_country: "Select country",
changing_country: "Changing...",
country_changed: "Country changed",
no_countries: "No countries available",
bd_leaders: "BD Leader",
bd_leader_count: "{count} BD Leader",
refresh: "Segarkan",
refreshing: "Menyegarkan...",
no_bd_leaders: "Belum ada BD Leader",
add_bd_leader: "Tambah BD Leader",
add_bd_leader_disabled: "Tambah BD Leader dinonaktifkan",
adding_bd_leader: "Menambahkan...",
add_bd_leader_success: "BD Leader ditambahkan",
gift_props: "Kirim Properti",
gift_props_disabled: "Kirim properti dinonaktifkan",
gift_type: "Jenis Hadiah",
prop_type_ride: "Kendaraan",
prop_type_noble_vip: "Noble VIP",
prop_type_avatar_frame: "Bingkai Avatar",
prop_type_badge: "Lencana",
prop_type_chat_bubble: "Gelembung Chat",
prop_type_data_card: "Kartu Profil",
no_giftable_props: "Tidak ada properti yang dapat dikirim",
send: "Kirim",
sending: "Mengirim...",
send_success: "Berhasil dikirim",
ban_user: "Blokir Pengguna",
ban_user_disabled: "Blokir pengguna dinonaktifkan",
ban_reason: "Alasan blokir",
ban: "Blokir",
submitting: "Mengirim...",
ban_success: "Pengguna diblokir",
unban_user: "Buka Blokir Pengguna",
unban_user_disabled: "Buka blokir pengguna dinonaktifkan",
unban_reason: "Alasan buka blokir",
unban: "Buka blokir",
unban_success: "Blokir pengguna dibuka",
can_unban: "Dapat dibuka",
cannot_unban: "Tidak dapat dibuka",
loading: "Memuat...",
uid_label: "UID",
days: "{count} hari",
recharged: "Sudah isi ulang",
not_recharged: "Belum isi ulang",
recharge_unknown: "Status isi ulang tidak diketahui",
can_ban: "Dapat diblokir",
cannot_ban: "Tidak dapat diblokir",
missing_token: "Token tidak ditemukan",
not_manager: "Akun saat ini bukan manajer",
user_not_found: "Pengguna tidak ditemukan",
user_recharged: "Pengguna ini memiliki riwayat isi ulang dan tidak dapat diblokir",
user_already_banned: "Pengguna ini sudah diblokir",
user_not_banned: "Pengguna ini tidak diblokir",
manager_region_required: "Region manajer diperlukan",
bd_leader_origin_mismatch: "Pengguna tidak berada di origin manajer ini",
user_is_admin: "Pengguna admin tidak dapat ditambahkan sebagai BD Leader",
user_already_bd_leader: "Pengguna ini sudah menjadi BD Leader",
user_already_bound_bd_leader: "Pengguna ini sudah terhubung ke BD Leader",
user_identity_locked: "This user has Host, Agency, BD, BD Leader, or Coin Seller identity and cannot be moved",
country_not_found: "Country not found",
country_required: "Select country",
prop_not_giftable: "Properti ini tidak tersedia untuk hadiah manajer",
vip_not_giftable: "Properti noble ini tidak dapat dikirim",
manager_feature_disabled: "Fitur ini dinonaktifkan oleh admin",
request_failed: "Permintaan gagal",
enter_user: "Masukkan ID pengguna atau akun"
}
};
const state = {
manager: null,
target: null,
activeAction: "",
features: defaultFeatures(),
propsType: defaultPropsType,
props: [],
selectedPropsId: "",
countries: [],
selectedCountryId: "",
countriesLoading: false,
changingCountry: false,
bdLeaders: [],
bdLeadersLoading: false,
bdLeadersError: "",
addingBDLeader: false
};
const actionConfigs = {
addBDLeader: {
titleKey: "add_bd_leader",
disabledKey: "add_bd_leader_disabled",
feature: "addBdLeader",
panel: "#addBDLeaderPanel",
status: "#addBDLeaderStatus",
needsUser: true
},
changeCountry: {
titleKey: "change_country",
disabledKey: "change_country_disabled",
feature: "changeCountry",
panel: "#countryPanel",
status: "#countryStatus",
needsUser: true
},
giftProps: {
titleKey: "gift_props",
disabledKey: "gift_props_disabled",
feature: "giftProps",
panel: "#giftPanel",
status: "#propsStatus",
needsUser: true
},
banUser: {
titleKey: "ban_user",
disabledKey: "ban_user_disabled",
feature: "banUser",
panel: "#banPanel",
status: "#banStatus",
needsUser: true
},
unbanUser: {
titleKey: "unban_user",
disabledKey: "unban_user_disabled",
feature: "unbanUser",
panel: "#unbanPanel",
status: "#unbanStatus",
needsUser: true
},
bdLeaders: {
titleKey: "bd_leaders",
panel: "#bdLeaderPanel",
needsUser: false
}
};
const params = readURLParams();
let currentLang = normalizeLanguage(params.get("lang"));
let currentMessages = fallbackMessages[currentLang] || fallbackMessages.en;
function readURLParams() {
const result = new URLSearchParams(window.location.search);
const hashQuery = window.location.hash.includes("?") ? window.location.hash.split("?")[1] : "";
const hashParams = new URLSearchParams(hashQuery);
hashParams.forEach((value, key) => {
if (!result.has(key)) result.set(key, value);
});
return result;
}
function readRawParam(name) {
const queries = [window.location.search.replace(/^\?/, "")];
if (window.location.hash.includes("?")) queries.push(window.location.hash.split("?")[1]);
for (const query of queries) {
for (const part of query.split("&")) {
if (!part) continue;
const equalIndex = part.indexOf("=");
const rawKey = equalIndex >= 0 ? part.slice(0, equalIndex) : part;
const rawValue = equalIndex >= 0 ? part.slice(equalIndex + 1) : "";
let decodedKey = "";
try {
decodedKey = decodeURIComponent(rawKey);
} catch (error) {
continue;
}
if (decodedKey !== name) continue;
try {
return decodeURIComponent(rawValue.replace(/\+/g, "%2B"));
} catch (error) {
return rawValue;
}
}
}
return "";
}
function normalizeLanguage(lang) {
const value = String(lang || "en").toLowerCase();
return supportedLanguages.includes(value) ? value : "en";
}
async function loadMessages(lang) {
const normalizedLang = normalizeLanguage(lang);
if (window.location.protocol === "file:") return fallbackMessages[normalizedLang];
try {
const response = await fetch(`./locales/${normalizedLang}.json?v=20260626-0100`, { cache: "no-store" });
if (response.ok) return await response.json();
} catch (error) {
return fallbackMessages[normalizedLang];
}
return fallbackMessages[normalizedLang];
}
function localizedValue(messages, key) {
return messages?.[key] || fallbackMessages[currentLang]?.[key] || fallbackMessages.en[key] || "";
}
function message(key, fallback = "") {
return localizedValue(currentMessages, key) || fallback || key;
}
function renderMessages(messages) {
document.querySelectorAll("[data-i18n]").forEach((node) => {
const value = localizedValue(messages, node.dataset.i18n);
if (value) node.textContent = value;
});
document.querySelectorAll("[data-i18n-aria]").forEach((node) => {
const value = localizedValue(messages, node.dataset.i18nAria);
if (value) node.setAttribute("aria-label", value);
});
document.querySelectorAll("[data-i18n-placeholder]").forEach((node) => {
const value = localizedValue(messages, node.dataset.i18nPlaceholder);
if (value) node.setAttribute("placeholder", value);
});
}
function setLanguageMenuOpen(open) {
const languageButton = $(".language-button");
const languageMenu = $(".language-menu");
if (!languageButton || !languageMenu) return;
languageMenu.hidden = !open;
languageButton.setAttribute("aria-expanded", String(open));
}
function renderLanguageControls(messages) {
const languageButton = $(".language-button");
if (languageButton) {
languageButton.textContent = languageLabels[currentLang];
languageButton.setAttribute("aria-label", localizedValue(messages, "language_button_aria") || "Change language");
}
document.querySelectorAll(".language-menu [data-lang]").forEach((button) => {
const isActive = button.dataset.lang === currentLang;
button.classList.toggle("is-active", isActive);
button.setAttribute("aria-pressed", String(isActive));
});
}
function setPropsTypeMenuOpen(open) {
const root = $("#propsTypeSelect");
const button = $("#propsTypeButton");
const menu = $("#propsTypeMenu");
if (!root || !button || !menu) return;
root.classList.toggle("is-open", open);
menu.hidden = !open;
button.setAttribute("aria-expanded", String(open));
}
function setCountryMenuOpen(open) {
const root = $("#countrySelect");
const button = $("#countryButton");
const menu = $("#countryMenu");
if (!root || !button || !menu) return;
root.classList.toggle("is-open", open);
menu.hidden = !open;
button.setAttribute("aria-expanded", String(open));
}
function renderPropsTypeSelect() {
const root = $("#propsTypeSelect");
const label = $("#propsTypeSelectedLabel");
if (root) root.dataset.value = state.propsType;
if (label) label.textContent = propTypeLabel(state.propsType);
document.querySelectorAll("#propsTypeMenu [data-value]").forEach((button) => {
const isSelected = button.dataset.value === state.propsType;
button.classList.toggle("is-selected", isSelected);
button.setAttribute("aria-selected", String(isSelected));
});
}
function renderCountrySelect() {
const root = $("#countrySelect");
const label = $("#countrySelectedLabel");
const menu = $("#countryMenu");
if (root) root.dataset.value = state.selectedCountryId || "";
if (label) label.textContent = countryLabel(selectedCountry()) || message("select_country");
if (!menu) return;
menu.replaceChildren();
state.countries.forEach((country) => {
const button = document.createElement("button");
button.type = "button";
button.setAttribute("role", "option");
button.dataset.value = String(country.id);
button.textContent = countryLabel(country);
const isSelected = String(country.id) === String(state.selectedCountryId);
button.classList.toggle("is-selected", isSelected);
button.setAttribute("aria-selected", String(isSelected));
button.addEventListener("click", (event) => {
event.stopPropagation();
chooseCountry(country.id);
});
menu.appendChild(button);
});
}
function chooseCountry(countryId) {
state.selectedCountryId = String(countryId || "");
setCountryMenuOpen(false);
renderCountrySelect();
updateActionState();
}
async function choosePropsType(value) {
const nextValue = String(value || defaultPropsType);
setPropsTypeMenuOpen(false);
setCountryMenuOpen(false);
if (nextValue === state.propsType) {
renderPropsTypeSelect();
return;
}
state.propsType = nextValue;
renderPropsTypeSelect();
try {
await loadProps();
} catch (error) {
setStatus($("#propsStatus"), friendlyError(error), "error");
}
}
async function applyLanguage(lang) {
currentLang = normalizeLanguage(lang);
const messages = await loadMessages(currentLang);
currentMessages = messages;
document.documentElement.lang = currentLang;
document.documentElement.dir = currentLang === "ar" ? "rtl" : "ltr";
document.title = message("document_title", "Manager Center");
renderMessages(messages);
renderLanguageControls(messages);
renderPropsTypeSelect();
renderCountrySelect();
renderManager(state.manager);
renderTarget();
renderActionModal();
renderProps();
renderBDLeaders();
updateActionState();
}
function $(selector) {
return document.querySelector(selector);
}
function apiBaseURL() {
const override = window.HYAPP_API_BASE_URL || params.get("apiBase");
if (override) return String(override).replace(/\/+$/, "");
return API_BASE_URL.replace(/\/+$/, "");
}
function isLocalDocumentsFile() {
if (window.location.protocol !== "file:") return false;
let pathname = window.location.pathname || "";
try {
pathname = decodeURIComponent(pathname);
} catch (error) {
return false;
}
return pathname.startsWith("/Users/hy/Documents/");
}
function goApiBaseURL() {
const override = window.HYAPP_GO_API_BASE_URL || params.get("goApiBase") || params.get("goBase");
if (override) return String(override).replace(/\/+$/, "");
if (isLocalDocumentsFile()) return `${LOCAL_GO_API_BASE_URL}${GO_API_PATH_PREFIX}`;
return `${apiBaseURL()}${GO_API_PATH_PREFIX}`;
}
function buildRequestURL(baseURL, path) {
const base = `${String(baseURL || API_BASE_URL).replace(/\/+$/, "")}/`;
const target = String(path || "").replace(/^\/+/, "");
return new URL(target, base).toString();
}
function normalizeAuthorization(token) {
const value = String(token || "").trim();
if (!value) return "";
return /^bearer\s+/i.test(value) ? value : `Bearer ${value}`;
}
function authHeadersFromToken(token) {
const sysOrigin = params.get("sysOrigin") || params.get("origin") || "ATYOU";
return {
Authorization: normalizeAuthorization(token),
"req-lang": currentLang,
"req-client": "H5",
"req-version": "V2",
"req-zone": Intl.DateTimeFormat().resolvedOptions().timeZone || "Asia/Shanghai",
"req-app-intel": "version=1.0.0;build=1;model=H5;sysVersion=Web;channel=Web",
"req-sys-origin": `origin=${sysOrigin};originChild=${sysOrigin}`
};
}
async function requestGoJSON(path, options = {}) {
const token = readRawParam("token");
if (!token) {
const error = new Error(message("missing_token"));
error.code = "missing_token";
throw error;
}
const headers = authHeadersFromToken(token);
const request = {
method: options.method || "GET",
cache: "no-store",
headers
};
if (options.body !== undefined) {
headers["Content-Type"] = "application/json";
request.body = JSON.stringify(options.body);
}
const response = await fetch(buildRequestURL(goApiBaseURL(), path), request);
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.code = data.code || data.errorCodeName || "";
error.response = data;
throw error;
}
return data.body ?? data.data ?? null;
}
function endpointProfile() {
return "/app/h5/manager-center/profile";
}
function endpointSearchUser(account) {
return `/app/h5/manager-center/users/search?account=${encodeURIComponent(account)}`;
}
function endpointCountries() {
return "/app/h5/manager-center/countries";
}
function endpointChangeUserCountry() {
return "/app/h5/manager-center/users/country";
}
function endpointProps(type) {
return `/app/h5/manager-center/props?type=${encodeURIComponent(type || "")}`;
}
function endpointSendProps() {
return "/app/h5/manager-center/props/send";
}
function endpointBDLeaders() {
return "/app/h5/manager-center/bd-leaders";
}
function endpointBanUser() {
return "/app/h5/manager-center/users/ban";
}
function endpointUnbanUser() {
return "/app/h5/manager-center/users/unban";
}
function setLoading(isLoading) {
const root = $(".manager-center");
const mask = $("#loadingMask");
if (root) root.dataset.loading = isLoading ? "true" : "false";
if (mask) mask.hidden = !isLoading;
}
function setStatus(node, text, type = "") {
if (!node) return;
node.textContent = text || "";
node.hidden = !text;
node.classList.toggle("is-error", type === "error");
}
function showToast(text) {
const toast = $("#toast");
if (!toast) return;
toast.textContent = text || "";
toast.hidden = !text;
window.clearTimeout(showToast.timer);
showToast.timer = window.setTimeout(() => {
toast.hidden = true;
}, 2300);
}
function syncModalState() {
document.body.classList.toggle("is-modal-open", Boolean(document.querySelector(".modal-mask:not([hidden])")));
}
function activeConfig() {
return actionConfigs[state.activeAction] || null;
}
function clearActionStatuses() {
setStatus($("#modalSearchStatus"), "");
Object.values(actionConfigs).forEach((config) => {
if (config.status) setStatus($(config.status), "");
});
}
function clearActionModalForm() {
const input = $("#modalAccountInput");
if (input) input.value = "";
const banReason = $("#banReason");
const unbanReason = $("#unbanReason");
if (banReason) banReason.value = "";
if (unbanReason) unbanReason.value = "";
state.target = null;
state.selectedCountryId = "";
renderTarget();
clearActionStatuses();
}
function renderActionModal() {
const config = activeConfig();
const title = $("#actionModalTitle");
if (title) title.textContent = config ? message(config.titleKey) : "-";
const needsUser = config?.needsUser !== false;
const searchForm = $("#modalSearchForm");
const modalTarget = $("#targetCard");
if (searchForm) searchForm.hidden = !needsUser;
if (modalTarget && !needsUser) modalTarget.hidden = true;
Object.values(actionConfigs).forEach((item) => {
const panel = $(item.panel);
if (panel) panel.hidden = item !== config || (item.needsUser !== false && !state.target);
});
}
function setModalOpen(selector, open) {
const modal = $(selector);
if (!modal) return;
modal.hidden = !open;
if (open) {
setLanguageMenuOpen(false);
setPropsTypeMenuOpen(false);
setCountryMenuOpen(false);
}
syncModalState();
}
function closeModals() {
document.querySelectorAll(".modal-mask").forEach((modal) => {
modal.hidden = true;
});
state.activeAction = "";
state.target = null;
setPropsTypeMenuOpen(false);
setCountryMenuOpen(false);
renderTarget();
syncModalState();
}
function openActionModal(action) {
const config = actionConfigs[action];
if (!config) return;
if (config.feature && !featureEnabled(config.feature)) {
showToast(message(config.disabledKey));
return;
}
state.activeAction = action;
clearActionModalForm();
renderActionModal();
setModalOpen("#actionModal", true);
updateActionState();
if (action === "giftProps" && !state.props.length) {
loadProps().catch((error) => {
setStatus($("#propsStatus"), friendlyError(error), "error");
});
}
if (action === "bdLeaders") {
renderBDLeaders();
}
window.setTimeout(() => {
if (config.needsUser !== false) $("#modalAccountInput")?.focus();
}, 0);
}
function openGiftModal() {
openActionModal("giftProps");
}
function openCountryModal() {
openActionModal("changeCountry");
}
function openBanModal() {
openActionModal("banUser");
}
function openUnbanModal() {
openActionModal("unbanUser");
}
function closePage() {
try {
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");
return;
}
if (window.history.length > 1) window.history.back();
} catch (error) {
console.error("close manager center failed:", error);
if (window.history.length > 1) window.history.back();
}
}
function firstLetter(name, fallback) {
const value = String(name || fallback || "U").trim();
return value ? value.slice(0, 1).toUpperCase() : "U";
}
function renderAvatar(imgSelector, fallbackSelector, url, name, fallback) {
const img = $(imgSelector);
const fallbackNode = $(fallbackSelector);
if (!img || !fallbackNode) return;
const src = String(url || "").trim();
fallbackNode.textContent = firstLetter(name, fallback);
if (src) {
img.src = src;
img.hidden = false;
fallbackNode.hidden = true;
} else {
img.removeAttribute("src");
img.hidden = true;
fallbackNode.hidden = false;
}
}
function displayName(user) {
return user?.userNickname || user?.nickname || user?.name || "-";
}
function displayUserID(user) {
return String(user?.userId || user?.id || "-");
}
function sameUserID(left, right) {
return displayUserID(left) === displayUserID(right);
}
function displayShortID(user) {
return String(user?.actualAccount || user?.account || user?.shortId || user?.userId || user?.id || "-");
}
function canBanTarget(target) {
return Boolean(target) && target.canBan !== false && !target.hasRecharge && !canUnbanTarget(target);
}
function defaultFeatures() {
return {
addBdLeader: true,
giftProps: true,
banUser: true,
unbanUser: true,
changeCountry: true
};
}
function normalizeFeatures(features) {
return {
addBdLeader: features?.addBdLeader !== false,
giftProps: features?.giftProps !== false,
banUser: features?.banUser !== false,
unbanUser: features?.unbanUser !== false,
changeCountry: features?.changeCountry !== false
};
}
function featureEnabled(key) {
return state.features?.[key] !== false;
}
function canUnbanTarget(target) {
const status = String(target?.accountStatus || "").trim().toUpperCase();
return Boolean(target) && (status === "FREEZE" || status === "ARCHIVE" || status === "ARCHIVE_DEVICE");
}
function userIDText(user) {
return `${message("uid_label", "UID")}: ${displayShortID(user)}`;
}
function displayCountryText(user) {
const name = String(user?.countryName || "").trim();
const code = String(user?.countryCode || "").trim();
if (name && code) return `${name} (${code})`;
return name || code || "-";
}
function countryLabel(country) {
if (!country) return "";
const name = String(country.countryName || "").trim();
const code = String(country.countryCode || "").trim();
if (name && code) return `${name} (${code})`;
return name || code || "";
}
function selectedCountry() {
return state.countries.find((country) => String(country.id) === String(state.selectedCountryId)) || null;
}
function matchingCountryId(user) {
const code = String(user?.countryCode || "").trim().toUpperCase();
if (!code) return "";
const country = state.countries.find((item) => String(item.countryCode || "").trim().toUpperCase() === code);
return country?.id || "";
}
function propTypeLabel(type) {
const key = `prop_type_${String(type || "").toLowerCase()}`;
return message(key, type || "-");
}
function formatDays(days) {
return message("days", "{count} days").replace("{count}", new Intl.NumberFormat("en-US").format(Number(days) || 0));
}
function formatBDLeaderCount(count) {
return message("bd_leader_count", "{count} BD Leaders").replace("{count}", new Intl.NumberFormat("en-US").format(Number(count) || 0));
}
function formatBDLeaderSummary() {
const countText = formatBDLeaderCount(state.bdLeaders.length);
const firstLeader = state.bdLeaders[0];
if (!firstLeader) return countText;
return `${countText} - ${userIDText(firstLeader)}`;
}
function formatDateTime(value) {
if (!value) return "";
const date = new Date(value);
if (Number.isNaN(date.getTime())) return "";
try {
return new Intl.DateTimeFormat(currentLang, {
month: "short",
day: "2-digit",
hour: "2-digit",
minute: "2-digit"
}).format(date);
} catch (error) {
return date.toLocaleString();
}
}
function giftDays(item) {
const days = Number(item?.days);
if (Number.isFinite(days) && days > 0) return days;
return String(item?.type || state.propsType).toUpperCase() === "NOBLE_VIP" ? defaultNobleVIPGiftDays : 7;
}
function renderManager(manager) {
$("#managerName").textContent = displayName(manager);
$("#managerUid").textContent = userIDText(manager);
renderAvatar("#managerAvatar", "#managerAvatarFallback", manager?.userAvatar, displayName(manager), "M");
}
function renderTarget() {
const card = $("#targetCard");
if (!state.target) {
if (card) card.hidden = true;
renderActionModal();
updateActionState();
return;
}
const target = state.target;
if (card) card.hidden = false;
$("#targetName").textContent = displayName(target);
$("#targetUid").textContent = userIDText(target);
$("#targetAccountStatus").textContent = target.accountStatus || "-";
$("#targetCountryStatus").textContent = displayCountryText(target);
const canBan = canBanTarget(target);
const banEligibility = $("#banEligibility");
if (banEligibility) {
banEligibility.textContent = canBan ? message("can_ban") : message("cannot_ban");
banEligibility.classList.toggle("is-danger", !canBan);
}
const canUnban = canUnbanTarget(target);
const unbanEligibility = $("#unbanEligibility");
if (unbanEligibility) {
unbanEligibility.textContent = canUnban ? message("can_unban") : message("cannot_unban");
unbanEligibility.classList.toggle("is-danger", !canUnban);
}
renderAvatar("#targetAvatar", "#targetAvatarFallback", target.userAvatar, displayName(target), "U");
renderActionModal();
updateActionState();
}
async function prepareActiveActionAfterTarget() {
if (!state.target) return;
if (state.activeAction === "changeCountry") {
const currentCountryText = $("#currentCountryText");
if (currentCountryText) currentCountryText.textContent = `${message("current_country")}: ${displayCountryText(state.target)}`;
state.selectedCountryId = String(state.target.countryId || matchingCountryId(state.target) || "");
renderCountrySelect();
if (!state.countries.length) {
await loadCountries();
}
return;
}
if (state.activeAction === "giftProps") {
renderProps();
}
updateActionState();
}
function renderProps() {
const list = $("#propsList");
if (!list) return;
list.replaceChildren();
if (!state.props.length) {
setStatus($("#propsStatus"), message("no_giftable_props"));
updateActionState();
return;
}
setStatus($("#propsStatus"), "");
state.props.forEach((item) => {
const button = document.createElement("button");
button.type = "button";
button.className = "prop-option";
button.dataset.propsId = String(item.id);
if (String(item.id) === String(state.selectedPropsId)) {
button.classList.add("is-selected");
}
const cover = document.createElement("span");
cover.className = "prop-cover";
if (item.cover || item.sourceUrl) {
const img = document.createElement("img");
img.alt = "";
img.src = item.cover || item.sourceUrl;
cover.appendChild(img);
} else {
const fallback = document.createElement("span");
fallback.textContent = firstLetter(item.name, "G");
cover.appendChild(fallback);
}
const copy = document.createElement("span");
copy.className = "prop-copy";
const name = document.createElement("span");
name.className = "prop-name";
name.textContent = item.name || `ID ${item.id}`;
const meta = document.createElement("span");
meta.className = "prop-meta";
meta.textContent = item.vipLevel ? `${propTypeLabel(item.type)} · VIP ${item.vipLevel}` : propTypeLabel(item.type);
copy.append(name, meta);
const days = document.createElement("span");
days.className = "prop-days";
days.textContent = formatDays(giftDays(item));
button.append(cover, copy, days);
button.addEventListener("click", () => {
state.selectedPropsId = String(item.id);
renderProps();
updateActionState();
});
list.appendChild(button);
});
updateActionState();
}
function isTargetBDLeader() {
if (!state.target) return false;
return state.bdLeaders.some((leader) => sameUserID(leader, state.target));
}
function renderBDLeaders() {
const list = $("#bdLeaderList");
const count = $("#bdLeaderCount");
const summary = $("#bdLeaderSummary");
const leaderCountText = formatBDLeaderCount(state.bdLeaders.length);
if (count) count.textContent = leaderCountText;
if (summary) summary.textContent = formatBDLeaderSummary();
if (!list) return;
list.replaceChildren();
if (state.bdLeadersLoading) {
setStatus($("#bdLeaderStatus"), message("refreshing"));
updateActionState();
return;
}
if (state.bdLeadersError) {
setStatus($("#bdLeaderStatus"), state.bdLeadersError, "error");
updateActionState();
return;
}
if (!state.bdLeaders.length) {
setStatus($("#bdLeaderStatus"), message("no_bd_leaders"));
updateActionState();
return;
}
setStatus($("#bdLeaderStatus"), "");
state.bdLeaders.forEach((leader) => {
const row = document.createElement("div");
row.className = "bd-leader-row";
const avatar = document.createElement("span");
avatar.className = "bd-leader-avatar";
if (leader.userAvatar) {
const img = document.createElement("img");
img.alt = "";
img.src = leader.userAvatar;
avatar.appendChild(img);
} else {
const fallback = document.createElement("span");
fallback.textContent = firstLetter(displayName(leader), "B");
avatar.appendChild(fallback);
}
const copy = document.createElement("span");
copy.className = "bd-leader-copy";
const name = document.createElement("span");
name.className = "bd-leader-name";
name.textContent = displayName(leader);
const meta = document.createElement("span");
meta.className = "bd-leader-meta";
meta.textContent = userIDText(leader);
copy.append(name, meta);
const time = document.createElement("span");
time.className = "bd-leader-time";
time.textContent = formatDateTime(leader.createTime);
row.append(avatar, copy, time);
list.appendChild(row);
});
updateActionState();
}
function updateActionState() {
const addBDLeaderButton = $("#addBDLeaderButton");
const countryEntryButton = $("#countryEntryButton");
const giftEntryButton = $("#giftEntryButton");
const banEntryButton = $("#banEntryButton");
const unbanEntryButton = $("#unbanEntryButton");
const bdLeaderListButton = $("#bdLeaderListButton");
const refreshBDLeaderButton = $("#refreshBDLeaderButton");
const addBDLeaderConfirmButton = $("#addBDLeaderConfirmButton");
const sendButton = $("#sendPropsButton");
const changeCountryButton = $("#changeCountryButton");
const banButton = $("#banButton");
const unbanButton = $("#unbanButton");
if (addBDLeaderButton) {
const disabledByFeature = !featureEnabled("addBdLeader");
addBDLeaderButton.disabled = disabledByFeature || state.addingBDLeader;
addBDLeaderButton.classList.toggle("is-feature-disabled", disabledByFeature);
const title = addBDLeaderButton.querySelector(".action-item-title");
if (title) {
title.textContent = disabledByFeature
? message("add_bd_leader_disabled")
: state.addingBDLeader ? message("adding_bd_leader") : message("add_bd_leader");
}
}
if (giftEntryButton) {
const disabledByFeature = !featureEnabled("giftProps");
giftEntryButton.disabled = disabledByFeature;
giftEntryButton.classList.toggle("is-feature-disabled", disabledByFeature);
const title = giftEntryButton.querySelector(".action-item-title");
if (title) title.textContent = disabledByFeature ? message("gift_props_disabled") : message("gift_props");
}
if (countryEntryButton) {
const disabledByFeature = !featureEnabled("changeCountry");
countryEntryButton.disabled = disabledByFeature || state.changingCountry;
countryEntryButton.classList.toggle("is-feature-disabled", disabledByFeature);
const title = countryEntryButton.querySelector(".action-item-title");
if (title) title.textContent = disabledByFeature ? message("change_country_disabled") : message("change_country");
}
if (banEntryButton) {
const disabledByFeature = !featureEnabled("banUser");
banEntryButton.disabled = disabledByFeature;
banEntryButton.classList.toggle("is-feature-disabled", disabledByFeature);
const title = banEntryButton.querySelector(".action-item-title");
if (title) title.textContent = disabledByFeature ? message("ban_user_disabled") : message("ban_user");
}
if (unbanEntryButton) {
const disabledByFeature = !featureEnabled("unbanUser");
unbanEntryButton.disabled = disabledByFeature;
unbanEntryButton.classList.toggle("is-feature-disabled", disabledByFeature);
const title = unbanEntryButton.querySelector(".action-item-title");
if (title) title.textContent = disabledByFeature ? message("unban_user_disabled") : message("unban_user");
}
if (bdLeaderListButton) bdLeaderListButton.disabled = state.bdLeadersLoading;
if (refreshBDLeaderButton) refreshBDLeaderButton.disabled = state.bdLeadersLoading;
if (addBDLeaderConfirmButton) {
addBDLeaderConfirmButton.disabled = !featureEnabled("addBdLeader") || !state.target || state.addingBDLeader || isTargetBDLeader();
addBDLeaderConfirmButton.textContent = state.addingBDLeader ? message("adding_bd_leader") : message("add_bd_leader");
}
if (sendButton) sendButton.disabled = !featureEnabled("giftProps") || !state.target || !state.selectedPropsId;
if (changeCountryButton) {
const currentID = String(state.target?.countryId || matchingCountryId(state.target) || "");
changeCountryButton.disabled = !featureEnabled("changeCountry") || !state.target || state.countriesLoading || state.changingCountry || !state.selectedCountryId || state.selectedCountryId === currentID;
changeCountryButton.textContent = state.changingCountry ? message("changing_country") : message("change_country");
}
if (banButton) banButton.disabled = !featureEnabled("banUser") || !canBanTarget(state.target);
if (unbanButton) unbanButton.disabled = !featureEnabled("unbanUser") || !canUnbanTarget(state.target);
}
async function loadProfile() {
const body = await requestGoJSON(endpointProfile());
state.manager = body?.manager || body || {};
state.features = normalizeFeatures(body?.features);
renderManager(state.manager);
updateActionState();
}
async function loadProps() {
state.props = [];
state.selectedPropsId = "";
renderProps();
if (!featureEnabled("giftProps")) {
setStatus($("#propsStatus"), message("gift_props_disabled"));
return;
}
setStatus($("#propsStatus"), message("loading"));
const body = await requestGoJSON(endpointProps(state.propsType));
state.props = Array.isArray(body?.records) ? body.records : [];
state.selectedPropsId = state.props.length ? String(state.props[0].id) : "";
renderProps();
}
async function loadCountries() {
state.countriesLoading = true;
setStatus($("#countryStatus"), message("loading"));
updateActionState();
try {
const body = await requestGoJSON(endpointCountries());
state.countries = Array.isArray(body?.records) ? body.records : [];
if (!state.selectedCountryId) state.selectedCountryId = String(state.target?.countryId || matchingCountryId(state.target) || "");
setStatus($("#countryStatus"), state.countries.length ? "" : message("no_countries"));
renderCountrySelect();
} finally {
state.countriesLoading = false;
updateActionState();
}
}
async function loadBDLeaders() {
state.bdLeadersLoading = true;
state.bdLeadersError = "";
renderBDLeaders();
try {
const body = await requestGoJSON(endpointBDLeaders());
state.bdLeaders = Array.isArray(body?.records) ? body.records : [];
setStatus($("#bdLeaderStatus"), "");
} catch (error) {
state.bdLeadersError = friendlyError(error);
throw error;
} finally {
state.bdLeadersLoading = false;
renderBDLeaders();
}
}
async function searchUser(event) {
event.preventDefault();
const input = $("#modalAccountInput");
const status = $("#modalSearchStatus");
const button = $("#modalSearchButton");
const account = String(input?.value || "").trim();
if (!account) {
setStatus(status, message("enter_user"), "error");
return;
}
button.disabled = true;
setStatus(status, message("searching"));
try {
const body = await requestGoJSON(endpointSearchUser(account));
state.target = body?.user || body || null;
renderTarget();
await prepareActiveActionAfterTarget();
setStatus(status, "");
} catch (error) {
state.target = null;
renderTarget();
setStatus(status, friendlyError(error), "error");
} finally {
button.disabled = false;
}
}
async function addBDLeader() {
if (!featureEnabled("addBdLeader")) {
showToast(message("add_bd_leader_disabled"));
return;
}
if (!state.target) {
setStatus($("#addBDLeaderStatus"), message("enter_user"), "error");
return;
}
if (state.addingBDLeader) return;
if (isTargetBDLeader()) {
setStatus($("#addBDLeaderStatus"), message("user_already_bd_leader"), "error");
return;
}
state.addingBDLeader = true;
setStatus($("#addBDLeaderStatus"), message("adding_bd_leader"));
updateActionState();
try {
await requestGoJSON(endpointBDLeaders(), {
method: "POST",
body: {
userId: displayUserID(state.target)
}
});
setStatus($("#addBDLeaderStatus"), "");
closeModals();
showToast(message("add_bd_leader_success"));
await loadBDLeaders();
} catch (error) {
setStatus($("#addBDLeaderStatus"), friendlyError(error), "error");
} finally {
state.addingBDLeader = false;
updateActionState();
}
}
async function sendProps() {
if (!featureEnabled("giftProps")) {
showToast(message("gift_props_disabled"));
return;
}
if (!state.target) {
setStatus($("#propsStatus"), message("enter_user"), "error");
return;
}
if (!state.selectedPropsId) return;
const button = $("#sendPropsButton");
button.disabled = true;
try {
await requestGoJSON(endpointSendProps(), {
method: "POST",
body: {
acceptUserId: displayUserID(state.target),
propsId: state.selectedPropsId
}
});
closeModals();
showToast(message("send_success"));
} catch (error) {
showToast(friendlyError(error));
} finally {
updateActionState();
}
}
async function banUser() {
if (!featureEnabled("banUser")) {
setStatus($("#banStatus"), message("ban_user_disabled"), "error");
return;
}
if (!state.target) {
setStatus($("#banStatus"), message("enter_user"), "error");
return;
}
if (!canBanTarget(state.target)) return;
const button = $("#banButton");
button.disabled = true;
setStatus($("#banStatus"), message("submitting"));
try {
await requestGoJSON(endpointBanUser(), {
method: "POST",
body: {
userId: displayUserID(state.target),
reason: $("#banReason").value || ""
}
});
state.target.accountStatus = "ARCHIVE";
renderTarget();
setStatus($("#banStatus"), "");
closeModals();
showToast(message("ban_success"));
} catch (error) {
setStatus($("#banStatus"), friendlyError(error), "error");
} finally {
updateActionState();
}
}
async function unbanUser() {
if (!featureEnabled("unbanUser")) {
setStatus($("#unbanStatus"), message("unban_user_disabled"), "error");
return;
}
if (!state.target) {
setStatus($("#unbanStatus"), message("enter_user"), "error");
return;
}
if (!canUnbanTarget(state.target)) return;
const button = $("#unbanButton");
button.disabled = true;
setStatus($("#unbanStatus"), message("submitting"));
try {
await requestGoJSON(endpointUnbanUser(), {
method: "POST",
body: {
userId: displayUserID(state.target),
reason: $("#unbanReason").value || ""
}
});
state.target.accountStatus = "NORMAL";
renderTarget();
setStatus($("#unbanStatus"), "");
closeModals();
showToast(message("unban_success"));
} catch (error) {
setStatus($("#unbanStatus"), friendlyError(error), "error");
} finally {
updateActionState();
}
}
async function changeUserCountry() {
if (!state.target) {
setStatus($("#countryStatus"), message("enter_user"), "error");
return;
}
if (!featureEnabled("changeCountry")) {
setStatus($("#countryStatus"), message("change_country_disabled"), "error");
return;
}
if (!state.selectedCountryId) {
setStatus($("#countryStatus"), message("country_required"), "error");
return;
}
state.changingCountry = true;
setStatus($("#countryStatus"), message("changing_country"));
updateActionState();
try {
const body = await requestGoJSON(endpointChangeUserCountry(), {
method: "POST",
body: {
userId: displayUserID(state.target),
countryId: state.selectedCountryId
}
});
state.target = body?.user || state.target;
renderTarget();
setStatus($("#countryStatus"), "");
closeModals();
showToast(message("country_changed"));
} catch (error) {
setStatus($("#countryStatus"), friendlyError(error), "error");
} finally {
state.changingCountry = false;
updateActionState();
}
}
function friendlyError(error) {
const code = error?.code || error?.response?.code || error?.response?.errorCodeName || "";
if (code === "missing_token") return message("missing_token");
if (code === "not_manager") return message("not_manager");
if (code === "user_not_found") return message("user_not_found");
if (code === "user_recharged") return message("user_recharged");
if (code === "user_already_banned") return message("user_already_banned");
if (code === "user_not_banned") return message("user_not_banned");
if (code === "manager_region_required") return message("manager_region_required");
if (code === "bd_leader_origin_mismatch") return message("bd_leader_origin_mismatch");
if (code === "user_is_admin") return message("user_is_admin");
if (code === "user_already_bd_leader") return message("user_already_bd_leader");
if (code === "user_already_bound_bd_leader") return message("user_already_bound_bd_leader");
if (code === "user_identity_locked") return message("user_identity_locked");
if (code === "country_not_found") return message("country_not_found");
if (code === "country_required") return message("country_required");
if (code === "prop_not_giftable") return message("prop_not_giftable");
if (code === "vip_not_giftable") return message("vip_not_giftable");
if (code === "manager_feature_disabled") return message("manager_feature_disabled");
return error?.message || message("request_failed");
}
function bindEvents() {
$(".back-button")?.addEventListener("click", closePage);
$(".language-button")?.addEventListener("click", (event) => {
event.stopPropagation();
setCountryMenuOpen(false);
setLanguageMenuOpen(Boolean($(".language-menu")?.hidden));
});
document.querySelectorAll(".language-menu [data-lang]").forEach((button) => {
button.addEventListener("click", async (event) => {
event.stopPropagation();
setLanguageMenuOpen(false);
await applyLanguage(button.dataset.lang);
});
});
document.addEventListener("click", () => {
setLanguageMenuOpen(false);
setPropsTypeMenuOpen(false);
setCountryMenuOpen(false);
});
$("#addBDLeaderButton")?.addEventListener("click", () => openActionModal("addBDLeader"));
$("#bdLeaderListButton")?.addEventListener("click", () => openActionModal("bdLeaders"));
$("#refreshBDLeaderButton")?.addEventListener("click", () => {
loadBDLeaders().catch((error) => {
showToast(friendlyError(error));
});
});
$("#giftEntryButton")?.addEventListener("click", openGiftModal);
$("#countryEntryButton")?.addEventListener("click", openCountryModal);
$("#banEntryButton")?.addEventListener("click", openBanModal);
$("#unbanEntryButton")?.addEventListener("click", openUnbanModal);
document.querySelectorAll("[data-modal-close]").forEach((button) => {
button.addEventListener("click", closeModals);
});
document.querySelectorAll(".modal-mask").forEach((modal) => {
modal.addEventListener("click", (event) => {
if (event.target === modal) closeModals();
});
});
$("#propsTypeButton")?.addEventListener("click", (event) => {
event.stopPropagation();
setLanguageMenuOpen(false);
setCountryMenuOpen(false);
setPropsTypeMenuOpen(Boolean($("#propsTypeMenu")?.hidden));
});
document.querySelectorAll("#propsTypeMenu [data-value]").forEach((button) => {
button.addEventListener("click", async (event) => {
event.stopPropagation();
await choosePropsType(button.dataset.value);
});
});
$("#countryButton")?.addEventListener("click", (event) => {
event.stopPropagation();
setLanguageMenuOpen(false);
setPropsTypeMenuOpen(false);
setCountryMenuOpen(Boolean($("#countryMenu")?.hidden));
});
document.addEventListener("keydown", (event) => {
if (event.key !== "Escape") return;
setLanguageMenuOpen(false);
setPropsTypeMenuOpen(false);
setCountryMenuOpen(false);
closeModals();
});
$("#modalSearchForm")?.addEventListener("submit", searchUser);
$("#addBDLeaderConfirmButton")?.addEventListener("click", addBDLeader);
$("#sendPropsButton")?.addEventListener("click", sendProps);
$("#banButton")?.addEventListener("click", banUser);
$("#unbanButton")?.addEventListener("click", unbanUser);
$("#changeCountryButton")?.addEventListener("click", changeUserCountry);
}
async function init() {
bindEvents();
renderPropsTypeSelect();
await applyLanguage(currentLang);
if (!readRawParam("token")) {
setLoading(false);
setStatus($("#pageStatus"), message("missing_token"), "error");
return;
}
try {
await loadProfile();
await Promise.all([loadProps(), loadBDLeaders()]);
} catch (error) {
showToast(friendlyError(error));
} finally {
setLoading(false);
}
}
init();
})();