1356 lines
47 KiB
JavaScript
1356 lines
47 KiB
JavaScript
(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 fallbackMessages = {
|
||
en: {
|
||
document_title: "Host Center",
|
||
page_label: "Host Center",
|
||
back: "Back",
|
||
title: "Host Center",
|
||
language_button_aria: "Change language",
|
||
uid: "UID: 1234567890",
|
||
agency: "Agency: Bilibili(101013)",
|
||
streaming_duration: "Work Time (min)",
|
||
target: "Target",
|
||
daily_details: "Daily data",
|
||
gift_points: "Gift points",
|
||
online_minutes: "Online minutes",
|
||
no_daily_data: "No daily data",
|
||
close: "Close",
|
||
open_daily_data: "Open daily data",
|
||
my_income: "Salary",
|
||
join_agency_title: "Join Agency",
|
||
join_agency_text: "Search for an agency ID and submit your application.",
|
||
join_agency_action: "Join now",
|
||
agency_id: "Agency ID",
|
||
enter_agent_id: "Enter agency ID",
|
||
search: "Search",
|
||
searching: "Searching...",
|
||
agency_label: "Agency",
|
||
apply: "Apply",
|
||
applying: "Applying...",
|
||
found: "Agency found",
|
||
account_not_found: "Account not found or not an agency",
|
||
application_submitted: "Application submitted",
|
||
application_failed: "Application failed",
|
||
application_records: "Application Records",
|
||
pending: "Pending",
|
||
join_pending_note: "Application is pending. Please wait for agency approval.",
|
||
cancel: "Cancel",
|
||
cancelling: "Cancelling...",
|
||
cancellation_failed: "Cancellation failed",
|
||
application_cancelled: "Application cancelled",
|
||
missing_token: "Missing token",
|
||
network_error: "Network error. Please try again.",
|
||
withdraw_exchange: "Withdraw/Exchange",
|
||
open_withdraw_exchange: "Open withdraw and exchange page",
|
||
open_anchor_policy: "Open host policy",
|
||
anchor_policy: "Host Policy",
|
||
policy_loading: "Loading policy...",
|
||
policy_empty: "No policy data",
|
||
policy_missing_token: "Missing token",
|
||
policy_load_failed: "Failed to load policy",
|
||
policy_level: "Level",
|
||
policy_online: "Online (Hour)",
|
||
policy_effective_day: "Valid days",
|
||
policy_target: "Target",
|
||
policy_host_salary: "Host salary",
|
||
policy_agent_salary: "Agent salary",
|
||
policy_total_salary: "Total salary"
|
||
},
|
||
ar: {
|
||
document_title: "مركز المضيف",
|
||
page_label: "مركز المضيف",
|
||
back: "رجوع",
|
||
title: "مركز المضيف",
|
||
language_button_aria: "تغيير اللغة",
|
||
uid: "معرّف المستخدم: 1234567890",
|
||
agency: "الوكالة: Bilibili(101013)",
|
||
streaming_duration: "وقت العمل (دقيقة)",
|
||
target: "الهدف",
|
||
daily_details: "البيانات اليومية",
|
||
gift_points: "نقاط الهدايا",
|
||
online_minutes: "دقائق الاتصال",
|
||
no_daily_data: "لا توجد بيانات يومية",
|
||
close: "إغلاق",
|
||
open_daily_data: "فتح البيانات اليومية",
|
||
my_income: "الراتب",
|
||
join_agency_title: "الانضمام إلى وكالة",
|
||
join_agency_text: "ابحث عن معرّف وكالة وأرسل طلبك.",
|
||
join_agency_action: "انضم الآن",
|
||
agency_id: "معرّف الوكالة",
|
||
enter_agent_id: "أدخل معرّف الوكالة",
|
||
search: "بحث",
|
||
searching: "جار البحث...",
|
||
agency_label: "الوكالة",
|
||
apply: "تقديم",
|
||
applying: "جار التقديم...",
|
||
found: "تم العثور على الوكالة",
|
||
account_not_found: "لم يتم العثور على الحساب أو ليس وكالة",
|
||
application_submitted: "تم إرسال الطلب",
|
||
application_failed: "فشل إرسال الطلب",
|
||
application_records: "سجلات الطلب",
|
||
pending: "قيد الانتظار",
|
||
join_pending_note: "الطلب قيد الانتظار. يرجى انتظار موافقة الوكالة.",
|
||
cancel: "إلغاء",
|
||
cancelling: "جار الإلغاء...",
|
||
cancellation_failed: "فشل الإلغاء",
|
||
application_cancelled: "تم إلغاء الطلب",
|
||
missing_token: "رمز الدخول مفقود",
|
||
network_error: "خطأ في الشبكة. حاول مرة أخرى.",
|
||
withdraw_exchange: "سحب/استبدال",
|
||
open_withdraw_exchange: "فتح صفحة السحب والاستبدال",
|
||
open_anchor_policy: "فتح سياسة المضيف",
|
||
anchor_policy: "سياسة المضيف",
|
||
policy_loading: "جار تحميل السياسة...",
|
||
policy_empty: "لا توجد بيانات سياسة",
|
||
policy_missing_token: "رمز الدخول مفقود",
|
||
policy_load_failed: "فشل تحميل السياسة",
|
||
policy_level: "المستوى",
|
||
policy_online: "الاتصال (ساعة)",
|
||
policy_effective_day: "الأيام الصالحة",
|
||
policy_target: "الهدف",
|
||
policy_host_salary: "راتب المضيف",
|
||
policy_agent_salary: "راتب الوكيل",
|
||
policy_total_salary: "إجمالي الراتب"
|
||
},
|
||
tr: {
|
||
document_title: "Host Merkezi",
|
||
page_label: "Host Merkezi",
|
||
back: "Geri",
|
||
title: "Host Merkezi",
|
||
language_button_aria: "Dili değiştir",
|
||
uid: "UID: 1234567890",
|
||
agency: "Ajans: Bilibili(101013)",
|
||
streaming_duration: "Çalışma Süresi (dk)",
|
||
target: "Hedef",
|
||
daily_details: "Günlük veri",
|
||
gift_points: "Hediye puanı",
|
||
online_minutes: "Online dakika",
|
||
no_daily_data: "Günlük veri yok",
|
||
close: "Kapat",
|
||
open_daily_data: "Günlük veriyi aç",
|
||
my_income: "Maaş",
|
||
join_agency_title: "Ajansa Katıl",
|
||
join_agency_text: "Ajans ID ile arama yapıp başvurunu gönder.",
|
||
join_agency_action: "Şimdi katıl",
|
||
agency_id: "Ajans ID",
|
||
enter_agent_id: "Ajans ID gir",
|
||
search: "Ara",
|
||
searching: "Aranıyor...",
|
||
agency_label: "Ajans",
|
||
apply: "Başvur",
|
||
applying: "Başvuruluyor...",
|
||
found: "Ajans bulundu",
|
||
account_not_found: "Hesap bulunamadı veya ajans değil",
|
||
application_submitted: "Başvuru gönderildi",
|
||
application_failed: "Başvuru başarısız",
|
||
application_records: "Başvuru Kayıtları",
|
||
pending: "Beklemede",
|
||
join_pending_note: "Başvuru beklemede. Lütfen ajans onayını bekleyin.",
|
||
cancel: "İptal",
|
||
cancelling: "İptal ediliyor...",
|
||
cancellation_failed: "İptal başarısız",
|
||
application_cancelled: "Başvuru iptal edildi",
|
||
missing_token: "Token eksik",
|
||
network_error: "Ağ hatası. Lütfen tekrar deneyin.",
|
||
withdraw_exchange: "Çek/Değiştir",
|
||
open_withdraw_exchange: "Çekme ve değişim sayfasını aç",
|
||
open_anchor_policy: "Host politikasını aç",
|
||
anchor_policy: "Host Politikası",
|
||
policy_loading: "Politika yükleniyor...",
|
||
policy_empty: "Politika verisi yok",
|
||
policy_missing_token: "Token eksik",
|
||
policy_load_failed: "Politika yüklenemedi",
|
||
policy_level: "Seviye",
|
||
policy_online: "Online (Saat)",
|
||
policy_effective_day: "Geçerli gün",
|
||
policy_target: "Hedef",
|
||
policy_host_salary: "Host maaşı",
|
||
policy_agent_salary: "Ajans maaşı",
|
||
policy_total_salary: "Toplam maaş"
|
||
},
|
||
id: {
|
||
document_title: "Pusat Host",
|
||
page_label: "Pusat Host",
|
||
back: "Kembali",
|
||
title: "Pusat Host",
|
||
language_button_aria: "Ubah bahasa",
|
||
uid: "UID: 1234567890",
|
||
agency: "Agensi: Bilibili(101013)",
|
||
streaming_duration: "Waktu Kerja (mnt)",
|
||
target: "Target",
|
||
daily_details: "Data harian",
|
||
gift_points: "Poin hadiah",
|
||
online_minutes: "Menit online",
|
||
no_daily_data: "Tidak ada data harian",
|
||
close: "Tutup",
|
||
open_daily_data: "Buka data harian",
|
||
my_income: "Gaji",
|
||
join_agency_title: "Gabung Agensi",
|
||
join_agency_text: "Cari ID agensi dan kirim pengajuan Anda.",
|
||
join_agency_action: "Gabung sekarang",
|
||
agency_id: "ID Agensi",
|
||
enter_agent_id: "Masukkan ID agensi",
|
||
search: "Cari",
|
||
searching: "Mencari...",
|
||
agency_label: "Agensi",
|
||
apply: "Ajukan",
|
||
applying: "Mengajukan...",
|
||
found: "Agensi ditemukan",
|
||
account_not_found: "Akun tidak ditemukan atau bukan agensi",
|
||
application_submitted: "Pengajuan terkirim",
|
||
application_failed: "Pengajuan gagal",
|
||
application_records: "Catatan Pengajuan",
|
||
pending: "Menunggu",
|
||
join_pending_note: "Pengajuan sedang menunggu. Harap tunggu persetujuan agensi.",
|
||
cancel: "Batal",
|
||
cancelling: "Membatalkan...",
|
||
cancellation_failed: "Gagal membatalkan",
|
||
application_cancelled: "Pengajuan dibatalkan",
|
||
missing_token: "Token tidak ditemukan",
|
||
network_error: "Kesalahan jaringan. Silakan coba lagi.",
|
||
withdraw_exchange: "Tarik/Tukar",
|
||
open_withdraw_exchange: "Buka halaman tarik dan tukar",
|
||
open_anchor_policy: "Buka kebijakan host",
|
||
anchor_policy: "Kebijakan Host",
|
||
policy_loading: "Memuat kebijakan...",
|
||
policy_empty: "Tidak ada data kebijakan",
|
||
policy_missing_token: "Token tidak ditemukan",
|
||
policy_load_failed: "Gagal memuat kebijakan",
|
||
policy_level: "Level",
|
||
policy_online: "Online (Jam)",
|
||
policy_effective_day: "Hari valid",
|
||
policy_target: "Target",
|
||
policy_host_salary: "Gaji host",
|
||
policy_agent_salary: "Gaji agensi",
|
||
policy_total_salary: "Total gaji"
|
||
}
|
||
};
|
||
|
||
const params = readURLParams();
|
||
let currentLang = normalizeLanguage(params.get("lang"));
|
||
let currentMessages = fallbackMessages[currentLang] || fallbackMessages.en;
|
||
let currentProfile = null;
|
||
let currentAgencyProfile = null;
|
||
let currentTeamId = "";
|
||
let currentIdentity = null;
|
||
let currentSalary = "0.00";
|
||
let currentStreamingDuration = "0";
|
||
let currentGiftValue = "0";
|
||
let currentDailyTargets = [];
|
||
let foundJoinAgency = null;
|
||
let pendingJoinRecord = null;
|
||
|
||
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=20260428-2070`, { 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-html]").forEach((node) => {
|
||
const value = localizedValue(messages, node.dataset.i18nHtml);
|
||
if (value) node.innerHTML = 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 apiBaseURL() {
|
||
const override = window.HYAPP_API_BASE_URL || params.get("apiBase");
|
||
if (override) return String(override).replace(/\/+$/, "");
|
||
return API_BASE_URL.replace(/\/+$/, "");
|
||
}
|
||
|
||
function normalizeAuthorization(token) {
|
||
const value = String(token || "").trim();
|
||
if (!value) return "";
|
||
return /^bearer\s+/i.test(value) ? value : `Bearer ${value}`;
|
||
}
|
||
|
||
function authHeadersFromToken(token) {
|
||
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=ATYOU;originChild=ATYOU"
|
||
};
|
||
}
|
||
|
||
async function requestJSON(path, options = {}) {
|
||
const token = readRawParam("token");
|
||
if (!token) throw new Error(message("missing_token", "Missing token"));
|
||
|
||
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(new URL(path, `${apiBaseURL()}/`).toString(), 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.response = data;
|
||
throw error;
|
||
}
|
||
|
||
return data.body ?? data.data ?? null;
|
||
}
|
||
|
||
function profileUidPrefix(messages) {
|
||
const template = messages.uid || fallbackMessages.en.uid;
|
||
const marker = "1234567890";
|
||
return template.includes(marker) ? template.replace(marker, "").trim() : "UID:";
|
||
}
|
||
|
||
function pickProfileName(profile) {
|
||
return profile?.userNickname || profile?.name || "Oscar";
|
||
}
|
||
|
||
function pickProfileAccount(profile) {
|
||
return profile?.ownSpecialId?.account || profile?.account || profile?.id || "1234567890";
|
||
}
|
||
|
||
function agencyPrefix(messages) {
|
||
const template = messages.agency || fallbackMessages.en.agency;
|
||
const marker = "Bilibili(101013)";
|
||
return template.includes(marker) ? template.replace(marker, "").trim() : "Agency:";
|
||
}
|
||
|
||
function pickAgencyName(profile) {
|
||
return profile?.userNickname || profile?.name || profile?.teamName || "-";
|
||
}
|
||
|
||
function pickAgencyAccount(profile) {
|
||
return profile?.ownSpecialId?.account || profile?.account || profile?.id || "";
|
||
}
|
||
|
||
function formatAgencyText(profile, messages = currentMessages) {
|
||
const prefix = agencyPrefix(messages);
|
||
if (!profile) return `${prefix} -`;
|
||
|
||
const name = pickAgencyName(profile);
|
||
const account = pickAgencyAccount(profile);
|
||
return account ? `${prefix} ${name}(${account})` : `${prefix} ${name}`;
|
||
}
|
||
|
||
function renderAgencyProfile(profile, messages = currentMessages) {
|
||
const agencyButton = document.querySelector(".agency");
|
||
const agencyTextNode = document.querySelector(".agency span:first-child");
|
||
if (!agencyButton || !agencyTextNode) return;
|
||
|
||
agencyTextNode.textContent = formatAgencyText(profile, messages);
|
||
agencyButton.dataset.teamId = String(currentTeamId || pickAgencyTeamId(profile) || "");
|
||
agencyButton.dataset.account = String(profile?.account || "");
|
||
agencyButton.dataset.specialAccount = String(profile?.ownSpecialId?.account || "");
|
||
syncPolicyLink();
|
||
}
|
||
|
||
function pickSpecialAccount(profile) {
|
||
return profile?.ownSpecialId?.account ||
|
||
profile?.specialId?.account ||
|
||
profile?.specialAccount ||
|
||
profile?.shortAccount ||
|
||
profile?.shortId ||
|
||
"";
|
||
}
|
||
|
||
function pickJoinAgencyProfile(body) {
|
||
return body?.ownUserProfile || body?.userProfile || body?.teamProfile || body || null;
|
||
}
|
||
|
||
function pickSearchAgency(body) {
|
||
const teamProfile = body?.teamProfile || null;
|
||
const userProfile = body?.ownUserProfile || body?.userProfile || teamProfile?.ownUserProfile || teamProfile?.userProfile || null;
|
||
if (!teamProfile?.id) return null;
|
||
|
||
const specialAccount = pickSpecialAccount(userProfile) || pickSpecialAccount(teamProfile);
|
||
|
||
return {
|
||
...(teamProfile || {}),
|
||
...(userProfile || {}),
|
||
id: teamProfile.id,
|
||
teamId: teamProfile.id,
|
||
teamName: teamProfile.teamName || userProfile?.teamName || "",
|
||
userNickname: userProfile?.userNickname || teamProfile.userNickname || teamProfile.name || teamProfile.teamName || "",
|
||
name: userProfile?.name || teamProfile.name || teamProfile.teamName || "",
|
||
userAvatar: userProfile?.userAvatar || teamProfile.userAvatar || userProfile?.avatar || teamProfile.avatar || "",
|
||
avatar: userProfile?.avatar || teamProfile.avatar || userProfile?.userAvatar || teamProfile.userAvatar || "",
|
||
displayAccount: specialAccount || userProfile?.account || teamProfile.account || "",
|
||
account: userProfile?.account || teamProfile.account || "",
|
||
ownSpecialId: userProfile?.ownSpecialId || teamProfile.ownSpecialId || (specialAccount ? { account: specialAccount } : null),
|
||
specialId: userProfile?.specialId || teamProfile.specialId || null,
|
||
specialAccount,
|
||
shortAccount: userProfile?.shortAccount || teamProfile.shortAccount || "",
|
||
shortId: userProfile?.shortId || teamProfile.shortId || ""
|
||
};
|
||
}
|
||
|
||
function pickJoinAgencyName(profile) {
|
||
return profile?.userNickname || profile?.name || profile?.teamName || "-";
|
||
}
|
||
|
||
function pickJoinAgencyAccount(profile) {
|
||
return pickSpecialAccount(profile) || profile?.displayAccount || profile?.account || profile?.id || "-";
|
||
}
|
||
|
||
function pickAgencyTeamId(profile) {
|
||
return profile?.teamId || profile?.teamProfile?.id || profile?.id || "";
|
||
}
|
||
|
||
function pickTeamEntryId(entry) {
|
||
return entry?.teamProfile?.id || entry?.teamId || entry?.id || "";
|
||
}
|
||
|
||
function removeAvatarFallback() {
|
||
document.querySelector("#profileAvatarFallback")?.remove();
|
||
}
|
||
|
||
function ensureAvatarFallback(displayName) {
|
||
const avatarShell = document.querySelector(".avatar-shell");
|
||
if (!avatarShell) return null;
|
||
|
||
let avatarFallback = document.querySelector("#profileAvatarFallback");
|
||
if (avatarFallback) {
|
||
avatarFallback.hidden = false;
|
||
avatarFallback.setAttribute("aria-label", `${displayName} avatar`);
|
||
return avatarFallback;
|
||
}
|
||
|
||
const template = document.createElement("template");
|
||
template.innerHTML = `
|
||
<svg class="avatar-fallback" id="profileAvatarFallback" viewBox="0 0 72 72" role="img">
|
||
<defs>
|
||
<linearGradient id="avatarBg" x1="12" y1="8" x2="60" y2="64">
|
||
<stop stop-color="#5AF6E4"></stop>
|
||
<stop offset="1" stop-color="#D9FFF5"></stop>
|
||
</linearGradient>
|
||
</defs>
|
||
<circle cx="36" cy="36" r="35" fill="url(#avatarBg)"></circle>
|
||
<path d="M22 30 20 18l10 7M50 30l2-12-10 7" fill="#101820"></path>
|
||
<path d="M20 31c3-9 28-9 32 0 4 10-3 21-16 21S16 41 20 31Z" fill="#F7FBF7"></path>
|
||
<circle cx="29" cy="36" r="4" fill="#101820"></circle>
|
||
<circle cx="46" cy="36" r="4" fill="#101820"></circle>
|
||
<circle cx="25" cy="41" r="5" fill="#F0B64A" opacity=".9"></circle>
|
||
<path d="M35 42h3l-1.5 2Z" fill="#101820"></path>
|
||
<path d="M36 45c-2 2-5 3-8 2M38 45c2 2 5 3 8 2" fill="none" stroke="#101820" stroke-width="2" stroke-linecap="round"></path>
|
||
</svg>
|
||
`;
|
||
avatarFallback = template.content.firstElementChild;
|
||
avatarFallback.setAttribute("aria-label", `${displayName} avatar`);
|
||
avatarShell.appendChild(avatarFallback);
|
||
return avatarFallback;
|
||
}
|
||
|
||
function renderProfile(profile, messages = currentMessages) {
|
||
if (!profile) return;
|
||
|
||
const profileCard = document.querySelector(".profile-card");
|
||
const nameNode = document.querySelector("#profileName");
|
||
const uidNode = document.querySelector("#profileUid");
|
||
const avatarImage = document.querySelector("#profileAvatar");
|
||
const displayName = pickProfileName(profile);
|
||
const displayAccount = pickProfileAccount(profile);
|
||
|
||
if (profileCard) {
|
||
profileCard.dataset.userId = String(profile.id || "");
|
||
profileCard.dataset.account = String(profile.account || "");
|
||
profileCard.dataset.specialAccount = String(profile?.ownSpecialId?.account || "");
|
||
}
|
||
|
||
if (nameNode) nameNode.textContent = displayName;
|
||
if (uidNode) uidNode.textContent = `${profileUidPrefix(messages)} ${displayAccount}`.trim();
|
||
|
||
if (!avatarImage) return;
|
||
|
||
const avatar = profile.userAvatar ? String(profile.userAvatar) : "";
|
||
avatarImage.alt = displayName;
|
||
|
||
if (!avatar) {
|
||
avatarImage.hidden = true;
|
||
avatarImage.onerror = null;
|
||
avatarImage.removeAttribute("src");
|
||
ensureAvatarFallback(displayName);
|
||
return;
|
||
}
|
||
|
||
avatarImage.hidden = false;
|
||
removeAvatarFallback();
|
||
avatarImage.onerror = () => {
|
||
avatarImage.hidden = true;
|
||
avatarImage.removeAttribute("src");
|
||
ensureAvatarFallback(displayName);
|
||
};
|
||
avatarImage.src = avatar;
|
||
}
|
||
|
||
function hasOwn(object, key) {
|
||
return Boolean(object && Object.prototype.hasOwnProperty.call(object, key));
|
||
}
|
||
|
||
function isTruthyIdentityValue(value) {
|
||
if (typeof value === "boolean") return value;
|
||
if (typeof value === "number") return value === 1;
|
||
if (typeof value === "string") return ["true", "1", "yes"].includes(value.toLowerCase());
|
||
return false;
|
||
}
|
||
|
||
function shouldOpenJoinAgency(identity) {
|
||
if (!hasOwn(identity, "anchor")) return false;
|
||
return !isTruthyIdentityValue(identity.anchor);
|
||
}
|
||
|
||
function setLoading(isLoading) {
|
||
const root = document.querySelector(".host-center");
|
||
const loadingMask = document.querySelector("#loadingMask");
|
||
if (root) root.dataset.loading = isLoading ? "true" : "false";
|
||
if (loadingMask) {
|
||
loadingMask.hidden = !isLoading;
|
||
loadingMask.setAttribute("aria-busy", String(isLoading));
|
||
}
|
||
}
|
||
|
||
function setIdentityView(identity) {
|
||
const root = document.querySelector(".host-center");
|
||
const showJoinAgency = shouldOpenJoinAgency(identity);
|
||
if (root) root.dataset.view = showJoinAgency ? "join-agency" : "host";
|
||
|
||
document.querySelectorAll(".host-only").forEach((node) => {
|
||
node.hidden = showJoinAgency;
|
||
});
|
||
|
||
const joinAgencyCard = document.querySelector("#joinAgencyCard");
|
||
if (joinAgencyCard) joinAgencyCard.hidden = !showJoinAgency;
|
||
|
||
const agencyButton = document.querySelector(".agency");
|
||
if (agencyButton) agencyButton.hidden = showJoinAgency;
|
||
}
|
||
|
||
function closeHostCenterPage() {
|
||
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 host center page failed:", error);
|
||
if (window.history.length > 1) window.history.back();
|
||
}
|
||
}
|
||
|
||
function formatCurrentSalary(value) {
|
||
const numericValue = Number(value);
|
||
if (Number.isFinite(numericValue)) return numericValue.toFixed(2);
|
||
return "0.00";
|
||
}
|
||
|
||
function pickCurrentSalary(body) {
|
||
if (typeof body === "number") return body;
|
||
if (body && typeof body === "object") {
|
||
return body.currentSalary ?? body.availableBalance ?? body.balance ?? 0;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
function renderCurrentSalary(value) {
|
||
currentSalary = formatCurrentSalary(value);
|
||
const salaryNode = document.querySelector("#currentSalary");
|
||
if (salaryNode) salaryNode.textContent = currentSalary;
|
||
}
|
||
|
||
function formatStreamingDuration(value) {
|
||
const numericValue = Number(value);
|
||
if (!Number.isFinite(numericValue)) return "0";
|
||
const safeValue = Math.max(0, numericValue);
|
||
return Number.isInteger(safeValue) ? String(safeValue) : String(Number(safeValue.toFixed(2)));
|
||
}
|
||
|
||
function pickStreamingDuration(body) {
|
||
const workTarget = pickFirstMemberWorkTarget(body);
|
||
return body?.onlineTime ?? body?.target?.onlineTime ?? workTarget?.target?.onlineTime ?? workTarget?.onlineTime ?? 0;
|
||
}
|
||
|
||
function renderStreamingDuration(value) {
|
||
currentStreamingDuration = formatStreamingDuration(value);
|
||
const durationNode = document.querySelector("#streamingDuration");
|
||
if (durationNode) durationNode.textContent = currentStreamingDuration;
|
||
}
|
||
|
||
function formatCountValue(value) {
|
||
if (value === null || value === undefined || value === "") return "-";
|
||
const number = Number(value);
|
||
if (Number.isFinite(number) && Number.isInteger(number)) return String(number);
|
||
if (Number.isFinite(number)) return String(Number(number.toFixed(2)));
|
||
return String(value);
|
||
}
|
||
|
||
function renderCurrentGiftValue(value) {
|
||
currentGiftValue = formatCountValue(value === null || value === undefined || value === "" ? 0 : value);
|
||
const giftNode = document.querySelector("#currentGiftValue");
|
||
const dailyGiftNode = document.querySelector("#dailyCurrentGift");
|
||
if (giftNode) giftNode.textContent = currentGiftValue;
|
||
if (dailyGiftNode) dailyGiftNode.textContent = currentGiftValue;
|
||
}
|
||
|
||
function pickFirstMemberWorkTarget(body) {
|
||
const targets = Array.isArray(body?.targets) ? body.targets : [];
|
||
return targets[0] || body?.target || null;
|
||
}
|
||
|
||
function pickGiftValue(workTarget) {
|
||
const target = workTarget?.target || workTarget || {};
|
||
return target.acceptGiftValue ?? target.giftValue ?? target.giftScore ?? target.currentGiftValue ?? null;
|
||
}
|
||
|
||
function pickDailyTargets(workTarget) {
|
||
const target = workTarget?.target || workTarget || {};
|
||
return Array.isArray(target.dailyTargets) ? target.dailyTargets : [];
|
||
}
|
||
|
||
function formatDateNumber(value) {
|
||
const text = String(value || "");
|
||
if (/^\d{8}$/.test(text)) {
|
||
return `${text.slice(0, 4)}.${text.slice(4, 6)}.${text.slice(6, 8)}`;
|
||
}
|
||
return text || "-";
|
||
}
|
||
|
||
function createDailyRow(item) {
|
||
const row = document.createElement("div");
|
||
row.className = "daily-row";
|
||
|
||
const date = document.createElement("div");
|
||
date.className = "daily-date";
|
||
date.textContent = formatDateNumber(item?.dateNumber);
|
||
|
||
const values = document.createElement("div");
|
||
values.className = "daily-values";
|
||
|
||
const gift = document.createElement("div");
|
||
gift.className = "daily-cell";
|
||
gift.innerHTML = `<span>${currentMessages.gift_points || fallbackMessages.en.gift_points}</span><strong>${formatCountValue(item?.acceptGiftValue ?? 0)}</strong>`;
|
||
|
||
const online = document.createElement("div");
|
||
online.className = "daily-cell";
|
||
online.innerHTML = `<span>${currentMessages.online_minutes || fallbackMessages.en.online_minutes}</span><strong>${formatCountValue(item?.onlineTime ?? 0)}</strong>`;
|
||
|
||
values.appendChild(gift);
|
||
values.appendChild(online);
|
||
row.appendChild(date);
|
||
row.appendChild(values);
|
||
return row;
|
||
}
|
||
|
||
function replaceNodeChildren(node, children) {
|
||
while (node.firstChild) node.removeChild(node.firstChild);
|
||
children.forEach((child) => node.appendChild(child));
|
||
}
|
||
|
||
function renderDailyTargets(targets = currentDailyTargets) {
|
||
currentDailyTargets = Array.isArray(targets) ? targets : [];
|
||
const list = document.querySelector("#dailyList");
|
||
if (!list) return;
|
||
|
||
if (!currentDailyTargets.length) {
|
||
const empty = document.createElement("div");
|
||
empty.className = "daily-empty";
|
||
empty.textContent = currentMessages.no_daily_data || fallbackMessages.en.no_daily_data;
|
||
replaceNodeChildren(list, [empty]);
|
||
return;
|
||
}
|
||
|
||
replaceNodeChildren(list, currentDailyTargets.map(createDailyRow));
|
||
}
|
||
|
||
function updateModalBodyLock() {
|
||
const hasOpenModal = Array.from(document.querySelectorAll(".daily-modal, .join-agency-modal")).some((modal) => !modal.hidden);
|
||
document.body.classList.toggle("daily-modal-open", hasOpenModal);
|
||
}
|
||
|
||
function renderMemberWorkSummary(memberWork) {
|
||
const workTarget = pickFirstMemberWorkTarget(memberWork);
|
||
renderStreamingDuration(pickStreamingDuration(memberWork));
|
||
renderCurrentGiftValue(pickGiftValue(workTarget) ?? 0);
|
||
renderDailyTargets(pickDailyTargets(workTarget));
|
||
}
|
||
|
||
function setDailyModalOpen(open) {
|
||
const modal = document.querySelector("#dailyModal");
|
||
if (!modal) return;
|
||
modal.hidden = !open;
|
||
updateModalBodyLock();
|
||
if (open) renderDailyTargets();
|
||
}
|
||
|
||
function showJoinAgencyStatus(text, type = "") {
|
||
const node = document.querySelector("#joinAgencyStatus");
|
||
if (!node) return;
|
||
|
||
node.textContent = text || "";
|
||
node.hidden = !text;
|
||
node.classList.toggle("is-error", type === "error");
|
||
node.classList.toggle("is-success", type === "success");
|
||
}
|
||
|
||
function renderJoinAgencyAvatar(profile, imageSelector, fallbackSelector) {
|
||
const image = document.querySelector(imageSelector);
|
||
const fallback = document.querySelector(fallbackSelector);
|
||
if (!image || !fallback) return;
|
||
|
||
const name = pickJoinAgencyName(profile);
|
||
const avatar = profile?.userAvatar || profile?.avatar || "";
|
||
fallback.textContent = String(name || "A").slice(0, 1).toUpperCase() || "A";
|
||
image.alt = name;
|
||
|
||
if (!avatar) {
|
||
image.hidden = true;
|
||
image.removeAttribute("src");
|
||
fallback.hidden = false;
|
||
return;
|
||
}
|
||
|
||
fallback.hidden = true;
|
||
image.hidden = false;
|
||
image.onerror = () => {
|
||
image.hidden = true;
|
||
image.removeAttribute("src");
|
||
fallback.hidden = false;
|
||
};
|
||
image.src = avatar;
|
||
}
|
||
|
||
function syncJoinAgencyApplyAvailability() {
|
||
const button = document.querySelector("#joinAgencyApplyButton");
|
||
if (button) button.hidden = Boolean(pendingJoinRecord) || !foundJoinAgency?.id;
|
||
|
||
const cancelButton = document.querySelector("#joinAgencyCancelButton");
|
||
if (cancelButton) cancelButton.hidden = !pendingJoinRecord || !pickPendingJoinRecordId(pendingJoinRecord);
|
||
}
|
||
|
||
function pickPendingJoinRecordId(record) {
|
||
return record?.messageId || record?.id || "";
|
||
}
|
||
|
||
function renderFoundJoinAgency(profile = foundJoinAgency) {
|
||
const card = document.querySelector("#joinAgencyResult");
|
||
if (!card) return;
|
||
|
||
if (!profile) {
|
||
card.hidden = true;
|
||
syncJoinAgencyApplyAvailability();
|
||
return;
|
||
}
|
||
|
||
card.hidden = false;
|
||
const nameNode = document.querySelector("#joinAgencyName");
|
||
const accountNode = document.querySelector("#joinAgencyAccountText");
|
||
if (nameNode) nameNode.textContent = pickJoinAgencyName(profile);
|
||
if (accountNode) accountNode.textContent = `${profileUidPrefix(currentMessages)} ${pickJoinAgencyAccount(profile)}`.trim();
|
||
renderJoinAgencyAvatar(profile, "#joinAgencyAvatar", "#joinAgencyAvatarFallback");
|
||
syncJoinAgencyApplyAvailability();
|
||
}
|
||
|
||
function renderPendingJoinRecord(record = pendingJoinRecord) {
|
||
const card = document.querySelector("#joinAgencyPending");
|
||
if (!card) return;
|
||
|
||
if (!record) {
|
||
card.hidden = true;
|
||
syncJoinAgencyApplyAvailability();
|
||
return;
|
||
}
|
||
|
||
const profile = pickJoinAgencyProfile(record);
|
||
card.hidden = false;
|
||
const nameNode = document.querySelector("#joinAgencyPendingName");
|
||
const accountNode = document.querySelector("#joinAgencyPendingAccount");
|
||
if (nameNode) nameNode.textContent = pickJoinAgencyName(profile);
|
||
if (accountNode) accountNode.textContent = `${profileUidPrefix(currentMessages)} ${pickJoinAgencyAccount(profile)}`.trim();
|
||
renderJoinAgencyAvatar(profile, "#joinAgencyPendingAvatar", "#joinAgencyPendingAvatarFallback");
|
||
syncJoinAgencyApplyAvailability();
|
||
}
|
||
|
||
function joinAgencyErrorMessage(error, fallbackKey) {
|
||
return error?.response?.errorMsg || error?.response?.message || error?.message || message(fallbackKey);
|
||
}
|
||
|
||
async function fetchPendingJoinRecord() {
|
||
try {
|
||
pendingJoinRecord = await requestJSON("/team/wait-apply/profile");
|
||
renderPendingJoinRecord(pendingJoinRecord);
|
||
return pendingJoinRecord;
|
||
} catch (error) {
|
||
pendingJoinRecord = null;
|
||
renderPendingJoinRecord(null);
|
||
if (error.message === message("missing_token")) showJoinAgencyStatus(error.message, "error");
|
||
return null;
|
||
}
|
||
}
|
||
|
||
async function searchJoinAgency(event) {
|
||
event?.preventDefault();
|
||
const input = document.querySelector("#joinAgencyAccount");
|
||
const button = document.querySelector("#joinAgencySearchButton");
|
||
const account = String(input?.value || "").trim();
|
||
|
||
if (!account) {
|
||
showJoinAgencyStatus(message("enter_agent_id"), "error");
|
||
return;
|
||
}
|
||
|
||
foundJoinAgency = null;
|
||
renderFoundJoinAgency(null);
|
||
if (button) {
|
||
button.disabled = true;
|
||
button.textContent = message("searching");
|
||
}
|
||
showJoinAgencyStatus("");
|
||
|
||
try {
|
||
const body = await requestJSON(`/team/search-account?account=${encodeURIComponent(account)}`);
|
||
const profile = pickSearchAgency(body);
|
||
if (!profile?.id) {
|
||
showJoinAgencyStatus(message("account_not_found"), "error");
|
||
return;
|
||
}
|
||
|
||
foundJoinAgency = profile;
|
||
renderFoundJoinAgency(foundJoinAgency);
|
||
showJoinAgencyStatus(message("found"), "success");
|
||
} catch (error) {
|
||
foundJoinAgency = null;
|
||
renderFoundJoinAgency(null);
|
||
showJoinAgencyStatus(joinAgencyErrorMessage(error, "network_error"), "error");
|
||
} finally {
|
||
if (button) {
|
||
button.disabled = false;
|
||
button.textContent = message("search");
|
||
}
|
||
}
|
||
}
|
||
|
||
async function applyToJoinAgency() {
|
||
if (pendingJoinRecord || !foundJoinAgency?.id) return;
|
||
|
||
const button = document.querySelector("#joinAgencyApplyButton");
|
||
if (button) {
|
||
button.disabled = true;
|
||
button.textContent = message("applying");
|
||
}
|
||
showJoinAgencyStatus("");
|
||
|
||
try {
|
||
const appliedAgency = foundJoinAgency;
|
||
await requestJSON("/team/user/apply", {
|
||
method: "POST",
|
||
body: {
|
||
teamId: appliedAgency.id,
|
||
reason: "JOIN"
|
||
}
|
||
});
|
||
|
||
foundJoinAgency = null;
|
||
renderFoundJoinAgency(null);
|
||
showJoinAgencyStatus(message("application_submitted"), "success");
|
||
const pending = await fetchPendingJoinRecord();
|
||
if (!pending) {
|
||
pendingJoinRecord = { ownUserProfile: appliedAgency };
|
||
renderPendingJoinRecord(pendingJoinRecord);
|
||
}
|
||
} catch (error) {
|
||
showJoinAgencyStatus(joinAgencyErrorMessage(error, "application_failed"), "error");
|
||
} finally {
|
||
if (button) {
|
||
button.disabled = false;
|
||
button.textContent = message("apply");
|
||
}
|
||
syncJoinAgencyApplyAvailability();
|
||
}
|
||
}
|
||
|
||
async function cancelJoinApplication() {
|
||
const id = pickPendingJoinRecordId(pendingJoinRecord);
|
||
if (!id) return;
|
||
|
||
const button = document.querySelector("#joinAgencyCancelButton");
|
||
if (button) {
|
||
button.disabled = true;
|
||
button.textContent = message("cancelling");
|
||
}
|
||
showJoinAgencyStatus("");
|
||
|
||
try {
|
||
await requestJSON("/team/user/join-apply-cancel", {
|
||
method: "POST",
|
||
body: { id }
|
||
});
|
||
|
||
pendingJoinRecord = null;
|
||
renderPendingJoinRecord(null);
|
||
showJoinAgencyStatus(message("application_cancelled"), "success");
|
||
} catch (error) {
|
||
showJoinAgencyStatus(joinAgencyErrorMessage(error, "cancellation_failed"), "error");
|
||
} finally {
|
||
if (button) {
|
||
button.disabled = false;
|
||
button.textContent = message("cancel");
|
||
}
|
||
syncJoinAgencyApplyAvailability();
|
||
}
|
||
}
|
||
|
||
function setJoinAgencyModalOpen(open) {
|
||
const modal = document.querySelector("#joinAgencyModal");
|
||
if (!modal) return;
|
||
|
||
modal.hidden = !open;
|
||
updateModalBodyLock();
|
||
if (!open) return;
|
||
|
||
showJoinAgencyStatus("");
|
||
fetchPendingJoinRecord();
|
||
window.setTimeout(() => {
|
||
document.querySelector("#joinAgencyAccount")?.focus();
|
||
}, 0);
|
||
}
|
||
|
||
async function fetchUserProfile() {
|
||
const token = readRawParam("token");
|
||
if (!token) {
|
||
console.warn("Missing token for /team/member/profile");
|
||
return null;
|
||
}
|
||
|
||
try {
|
||
const url = new URL("/team/member/profile", `${apiBaseURL()}/`);
|
||
|
||
const response = await fetch(url.toString(), {
|
||
cache: "no-store",
|
||
headers: authHeadersFromToken(token)
|
||
});
|
||
const data = await response.json().catch(() => ({}));
|
||
if (!response.ok || data.status === false) {
|
||
throw new Error(data.errorMsg || data.message || `Request failed: ${response.status}`);
|
||
}
|
||
|
||
currentProfile = data.body || data.data || {};
|
||
renderProfile(currentProfile);
|
||
return currentProfile;
|
||
} catch (error) {
|
||
console.error("Failed to load user profile:", error);
|
||
return null;
|
||
}
|
||
}
|
||
|
||
async function fetchIdentity() {
|
||
const token = readRawParam("token");
|
||
if (!token) {
|
||
console.warn("Missing token for /app/h5/identity");
|
||
return null;
|
||
}
|
||
|
||
try {
|
||
const url = new URL("/app/h5/identity", `${apiBaseURL()}/`);
|
||
|
||
const response = await fetch(url.toString(), {
|
||
cache: "no-store",
|
||
headers: authHeadersFromToken(token)
|
||
});
|
||
const data = await response.json().catch(() => ({}));
|
||
if (!response.ok || data.status === false) {
|
||
throw new Error(data.errorMsg || data.message || `Request failed: ${response.status}`);
|
||
}
|
||
|
||
currentIdentity = data.body || data.data || {};
|
||
return currentIdentity;
|
||
} catch (error) {
|
||
console.error("Failed to load H5 identity:", error);
|
||
return null;
|
||
}
|
||
}
|
||
|
||
async function fetchAgencyProfile() {
|
||
const token = readRawParam("token");
|
||
if (!token) {
|
||
console.warn("Missing token for /team/team-own/profile");
|
||
renderAgencyProfile(null);
|
||
return null;
|
||
}
|
||
|
||
try {
|
||
const url = new URL("/team/team-own/profile", `${apiBaseURL()}/`);
|
||
|
||
const response = await fetch(url.toString(), {
|
||
cache: "no-store",
|
||
headers: authHeadersFromToken(token)
|
||
});
|
||
const data = await response.json().catch(() => ({}));
|
||
if (!response.ok || data.status === false) {
|
||
throw new Error(data.errorMsg || data.message || `Request failed: ${response.status}`);
|
||
}
|
||
|
||
currentAgencyProfile = data.body || data.data || null;
|
||
renderAgencyProfile(currentAgencyProfile);
|
||
return currentAgencyProfile;
|
||
} catch (error) {
|
||
console.error("Failed to load agency profile:", error);
|
||
renderAgencyProfile(null);
|
||
return null;
|
||
}
|
||
}
|
||
|
||
async function fetchTeamEntry() {
|
||
const token = readRawParam("token");
|
||
if (!token) {
|
||
console.warn("Missing token for /team/entry");
|
||
return "";
|
||
}
|
||
|
||
try {
|
||
const url = new URL("/team/entry", `${apiBaseURL()}/`);
|
||
|
||
const response = await fetch(url.toString(), {
|
||
cache: "no-store",
|
||
headers: authHeadersFromToken(token)
|
||
});
|
||
const data = await response.json().catch(() => ({}));
|
||
if (!response.ok || data.status === false) {
|
||
throw new Error(data.errorMsg || data.message || `Request failed: ${response.status}`);
|
||
}
|
||
|
||
currentTeamId = pickTeamEntryId(data.body || data.data || {});
|
||
renderAgencyProfile(currentAgencyProfile);
|
||
syncPolicyLink();
|
||
return currentTeamId;
|
||
} catch (error) {
|
||
console.error("Failed to load team entry:", error);
|
||
return "";
|
||
}
|
||
}
|
||
|
||
async function fetchBankBalance() {
|
||
const token = readRawParam("token");
|
||
if (!token) {
|
||
console.warn("Missing token for /wallet/bank/balance");
|
||
return;
|
||
}
|
||
|
||
try {
|
||
const url = new URL("/wallet/bank/balance", `${apiBaseURL()}/`);
|
||
|
||
const response = await fetch(url.toString(), {
|
||
cache: "no-store",
|
||
headers: authHeadersFromToken(token)
|
||
});
|
||
const data = await response.json().catch(() => ({}));
|
||
if (!response.ok || data.status === false) {
|
||
throw new Error(data.errorMsg || data.message || `Request failed: ${response.status}`);
|
||
}
|
||
|
||
renderCurrentSalary(pickCurrentSalary(data.body ?? data.data));
|
||
} catch (error) {
|
||
console.error("Failed to load bank balance:", error);
|
||
renderCurrentSalary(0);
|
||
}
|
||
}
|
||
|
||
async function fetchStreamingDuration(memberId) {
|
||
const memberWork = await fetchMemberWork(memberId);
|
||
renderMemberWorkSummary(memberWork);
|
||
return memberWork;
|
||
}
|
||
|
||
async function fetchMemberWork(memberId) {
|
||
if (!memberId) {
|
||
console.warn("Missing memberId for /team/member-work");
|
||
return null;
|
||
}
|
||
|
||
try {
|
||
const url = new URL("/team/member-work", `${apiBaseURL()}/`);
|
||
url.searchParams.set("userId", String(memberId));
|
||
const token = readRawParam("token");
|
||
if (!token) {
|
||
console.warn("Missing token for /team/member-work");
|
||
return null;
|
||
}
|
||
|
||
const response = await fetch(url.toString(), {
|
||
cache: "no-store",
|
||
headers: authHeadersFromToken(token)
|
||
});
|
||
const data = await response.json().catch(() => ({}));
|
||
if (!response.ok || data.status === false) {
|
||
throw new Error(data.errorMsg || data.message || `Request failed: ${response.status}`);
|
||
}
|
||
|
||
return data.body || data.data || null;
|
||
} catch (error) {
|
||
console.error("Failed to load member work:", error);
|
||
return null;
|
||
}
|
||
}
|
||
|
||
function syncLocalizedLinks() {
|
||
const nextParams = new URLSearchParams(params);
|
||
const token = readRawParam("token");
|
||
if (token) nextParams.set("token", token);
|
||
if (currentLang) nextParams.set("lang", currentLang);
|
||
const query = nextParams.toString();
|
||
|
||
document.querySelectorAll('a[href^="../withdraw-exchange/index.html"]').forEach((link) => {
|
||
link.setAttribute("href", `../withdraw-exchange/index.html${query ? `?${query}` : ""}`);
|
||
});
|
||
}
|
||
|
||
function syncPolicyLink() {
|
||
const link = document.querySelector("#anchorPolicyLink");
|
||
if (!link) return;
|
||
|
||
const nextParams = new URLSearchParams(params);
|
||
const token = readRawParam("token");
|
||
const teamId = currentTeamId;
|
||
if (token) nextParams.set("token", token);
|
||
if (currentLang) nextParams.set("lang", currentLang);
|
||
if (teamId) nextParams.set("teamId", teamId);
|
||
|
||
const query = nextParams.toString();
|
||
link.setAttribute("href", `./policy.html${query ? `?${query}` : ""}`);
|
||
}
|
||
|
||
function setLanguageMenuOpen(open) {
|
||
const languageButton = document.querySelector(".language-button");
|
||
const languageMenu = document.querySelector(".language-menu");
|
||
if (!languageButton || !languageMenu) return;
|
||
|
||
languageMenu.hidden = !open;
|
||
languageButton.setAttribute("aria-expanded", String(open));
|
||
}
|
||
|
||
function renderLanguageControls(messages) {
|
||
const languageButton = document.querySelector(".language-button");
|
||
if (languageButton) {
|
||
languageButton.textContent = languageLabels[currentLang];
|
||
languageButton.setAttribute("aria-label", 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));
|
||
});
|
||
}
|
||
|
||
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 = messages.document_title || messages.title || "Host Center";
|
||
renderMessages(messages);
|
||
renderLanguageControls(messages);
|
||
syncLocalizedLinks();
|
||
syncPolicyLink();
|
||
renderProfile(currentProfile, messages);
|
||
renderAgencyProfile(currentAgencyProfile, messages);
|
||
renderDailyTargets();
|
||
renderFoundJoinAgency(foundJoinAgency);
|
||
renderPendingJoinRecord(pendingJoinRecord);
|
||
}
|
||
|
||
document.querySelector(".language-button")?.addEventListener("click", (event) => {
|
||
event.stopPropagation();
|
||
const languageMenu = document.querySelector(".language-menu");
|
||
setLanguageMenuOpen(Boolean(languageMenu?.hidden));
|
||
});
|
||
|
||
document.querySelectorAll(".language-menu [data-lang]").forEach((button) => {
|
||
button.addEventListener("click", (event) => {
|
||
event.stopPropagation();
|
||
setLanguageMenuOpen(false);
|
||
applyLanguage(button.dataset.lang);
|
||
});
|
||
});
|
||
|
||
document.addEventListener("click", () => {
|
||
setLanguageMenuOpen(false);
|
||
});
|
||
|
||
document.querySelector(".back-button")?.addEventListener("click", () => {
|
||
closeHostCenterPage();
|
||
});
|
||
|
||
document.querySelector(".agency")?.addEventListener("click", () => {
|
||
if (currentIdentity && shouldOpenJoinAgency(currentIdentity)) setJoinAgencyModalOpen(true);
|
||
});
|
||
|
||
document.querySelector("#joinAgencyButton")?.addEventListener("click", () => {
|
||
setJoinAgencyModalOpen(true);
|
||
});
|
||
|
||
document.querySelector("#joinAgencySearchForm")?.addEventListener("submit", searchJoinAgency);
|
||
|
||
document.querySelector("#joinAgencyApplyButton")?.addEventListener("click", () => {
|
||
applyToJoinAgency();
|
||
});
|
||
|
||
document.querySelector("#joinAgencyCancelButton")?.addEventListener("click", () => {
|
||
cancelJoinApplication();
|
||
});
|
||
|
||
document.querySelectorAll("[data-close-join-agency]").forEach((node) => {
|
||
node.addEventListener("click", () => {
|
||
setJoinAgencyModalOpen(false);
|
||
});
|
||
});
|
||
|
||
document.querySelector(".gift-value")?.addEventListener("click", () => {
|
||
setDailyModalOpen(true);
|
||
});
|
||
|
||
document.querySelectorAll("[data-close-daily]").forEach((node) => {
|
||
node.addEventListener("click", () => {
|
||
setDailyModalOpen(false);
|
||
});
|
||
});
|
||
|
||
document.addEventListener("keydown", (event) => {
|
||
if (event.key === "Escape") {
|
||
setDailyModalOpen(false);
|
||
setJoinAgencyModalOpen(false);
|
||
}
|
||
});
|
||
|
||
ensureAvatarFallback("Oscar");
|
||
|
||
async function initializePage() {
|
||
setLoading(true);
|
||
|
||
try {
|
||
await applyLanguage(currentLang);
|
||
|
||
const identity = await fetchIdentity();
|
||
setIdentityView(identity);
|
||
|
||
const profile = await fetchUserProfile();
|
||
const pendingRequests = [];
|
||
|
||
if (!shouldOpenJoinAgency(identity)) {
|
||
pendingRequests.push(fetchAgencyProfile());
|
||
pendingRequests.push(fetchTeamEntry());
|
||
pendingRequests.push(fetchBankBalance());
|
||
|
||
const memberId = profile?.id || profile?.account;
|
||
if (memberId) pendingRequests.push(fetchStreamingDuration(memberId));
|
||
}
|
||
|
||
await Promise.allSettled(pendingRequests);
|
||
} catch (error) {
|
||
console.error("Failed to initialize host center:", error);
|
||
setIdentityView(currentIdentity);
|
||
} finally {
|
||
setLoading(false);
|
||
}
|
||
}
|
||
|
||
initializePage();
|
||
})();
|