工资相关
This commit is contained in:
parent
496c74a291
commit
ae4d97ed66
@ -99,7 +99,7 @@
|
||||
"invite.claimed": "تم الاستلام",
|
||||
"invite.claimSuccess": "تم الاستلام",
|
||||
"invite.claimFailed": "فشل الاستلام",
|
||||
"invite.notAvailable": "غير متاح بعد",
|
||||
"invite.notAvailable": "غير متاح الآن",
|
||||
"invite.noRewardTasks": "لا توجد مهام مكافآت",
|
||||
"invite.rechargeMilestone": "مرحلة الشحن {index}",
|
||||
"invite.validInviteMilestone": "مرحلة الدعوة {index}",
|
||||
@ -111,8 +111,6 @@
|
||||
"invite.noRankData": "لا توجد بيانات ترتيب",
|
||||
"invite.copied": "تم النسخ",
|
||||
"invite.copyFailed": "فشل النسخ",
|
||||
"invite.notAvailable": "غير متاح الآن",
|
||||
"invite.claimed": "تم الاستلام",
|
||||
"host_center.title": "مركز المضيف",
|
||||
"host_center.back": "رجوع",
|
||||
"host_center.change_language": "تغيير اللغة",
|
||||
@ -339,31 +337,6 @@
|
||||
"bd_center.invitation_rejected": "تم رفض الدعوة.",
|
||||
"bd_center.load_messages_failed": "فشل تحميل الرسائل.",
|
||||
"bd_center.process_invitation_failed": "فشلت المعالجة. حاول مرة أخرى لاحقًا.",
|
||||
"bd_leader_center.back": "رجوع",
|
||||
"bd_leader_center.title": "مركز BD Leader",
|
||||
"bd_leader_center.change_language": "تغيير اللغة",
|
||||
"bd_leader_center.role": "BD Leader",
|
||||
"bd_leader_center.salary": "الراتب",
|
||||
"bd_leader_center.withdraw_exchange": "سحب/تبديل",
|
||||
"bd_leader_center.salary_history": "سجل الراتب",
|
||||
"bd_leader_center.invite_bd": "دعوة BD",
|
||||
"bd_leader_center.bd_list": "قائمة BD",
|
||||
"bd_leader_center.close": "إغلاق",
|
||||
"bd_leader_center.enter_user_id": "أدخل معرف المستخدم",
|
||||
"bd_leader_center.search": "بحث",
|
||||
"bd_leader_center.no_users_found": "لم يتم العثور على مستخدمين",
|
||||
"bd_leader_center.uid_prefix": "UID: {uid}",
|
||||
"bd_leader_center.bd_number": "عدد BD",
|
||||
"bd_leader_center.agencies": "الوكالات",
|
||||
"bd_leader_center.agency_number": "عدد الوكالات",
|
||||
"bd_leader_center.team_salary": "راتب الفريق",
|
||||
"bd_leader_center.team_recharge": "شحن الفريق",
|
||||
"bd_leader_center.total_income": "إجمالي الدخل",
|
||||
"bd_leader_center.previous_income": "دخل الفترة السابقة",
|
||||
"bd_leader_center.in_progress": "قيد التنفيذ",
|
||||
"bd_leader_center.invite": "دعوة",
|
||||
"bd_leader_center.invite_success": "تم إرسال الدعوة.",
|
||||
"bd_leader_center.tools": "أدوات BD Leader",
|
||||
"agency_center.title": "مركز الوكالة",
|
||||
"agency_center.back": "رجوع",
|
||||
"agency_center.change_language": "تغيير اللغة",
|
||||
|
||||
@ -111,8 +111,6 @@
|
||||
"invite.noRankData": "No rank data",
|
||||
"invite.copied": "Copied",
|
||||
"invite.copyFailed": "Copy failed",
|
||||
"invite.notAvailable": "Not available yet",
|
||||
"invite.claimed": "Claimed",
|
||||
"host_center.title": "Host Center",
|
||||
"host_center.back": "Back",
|
||||
"host_center.change_language": "Change language",
|
||||
@ -345,31 +343,6 @@
|
||||
"bd_center.invitation_rejected": "Invitation rejected.",
|
||||
"bd_center.load_messages_failed": "Load messages failed.",
|
||||
"bd_center.process_invitation_failed": "Process failed. Try again later.",
|
||||
"bd_leader_center.back": "Back",
|
||||
"bd_leader_center.title": "BD Leader Center",
|
||||
"bd_leader_center.change_language": "Change language",
|
||||
"bd_leader_center.role": "BD Leader",
|
||||
"bd_leader_center.salary": "Salary",
|
||||
"bd_leader_center.withdraw_exchange": "Withdraw/Exchange",
|
||||
"bd_leader_center.salary_history": "Salary History",
|
||||
"bd_leader_center.invite_bd": "Invite BD",
|
||||
"bd_leader_center.bd_list": "BD List",
|
||||
"bd_leader_center.close": "Close",
|
||||
"bd_leader_center.enter_user_id": "Enter User ID",
|
||||
"bd_leader_center.search": "Search",
|
||||
"bd_leader_center.no_users_found": "No users found",
|
||||
"bd_leader_center.uid_prefix": "UID: {uid}",
|
||||
"bd_leader_center.bd_number": "BD number",
|
||||
"bd_leader_center.agencies": "Agencies",
|
||||
"bd_leader_center.agency_number": "Agency number",
|
||||
"bd_leader_center.team_salary": "Team salary",
|
||||
"bd_leader_center.team_recharge": "Team recharge",
|
||||
"bd_leader_center.total_income": "Total income",
|
||||
"bd_leader_center.previous_income": "Previous income",
|
||||
"bd_leader_center.in_progress": "In progress",
|
||||
"bd_leader_center.invite": "Invite",
|
||||
"bd_leader_center.invite_success": "Invitation submitted.",
|
||||
"bd_leader_center.tools": "BD Leader tools",
|
||||
"agency_center.title": "Agency Center",
|
||||
"agency_center.back": "Back",
|
||||
"agency_center.change_language": "Change language",
|
||||
|
||||
@ -111,8 +111,6 @@
|
||||
"invite.noRankData": "No hay datos de ranking",
|
||||
"invite.copied": "Copiado",
|
||||
"invite.copyFailed": "Error al copiar",
|
||||
"invite.notAvailable": "Aún no disponible",
|
||||
"invite.claimed": "Reclamado",
|
||||
"host_center.title": "Centro de anfitrión",
|
||||
"host_center.back": "Volver",
|
||||
"host_center.change_language": "Cambiar idioma",
|
||||
@ -339,31 +337,6 @@
|
||||
"bd_center.invitation_rejected": "Invitación rechazada.",
|
||||
"bd_center.load_messages_failed": "Error al cargar mensajes.",
|
||||
"bd_center.process_invitation_failed": "Error al procesar. Inténtalo de nuevo más tarde.",
|
||||
"bd_leader_center.back": "Volver",
|
||||
"bd_leader_center.title": "Centro de líder BD",
|
||||
"bd_leader_center.change_language": "Cambiar idioma",
|
||||
"bd_leader_center.role": "Líder BD",
|
||||
"bd_leader_center.salary": "Salario",
|
||||
"bd_leader_center.withdraw_exchange": "Retirar/Canjear",
|
||||
"bd_leader_center.salary_history": "Historial salarial",
|
||||
"bd_leader_center.invite_bd": "Invitar BD",
|
||||
"bd_leader_center.bd_list": "Lista BD",
|
||||
"bd_leader_center.close": "Cerrar",
|
||||
"bd_leader_center.enter_user_id": "Ingresa el ID de usuario",
|
||||
"bd_leader_center.search": "Buscar",
|
||||
"bd_leader_center.no_users_found": "No se encontraron usuarios",
|
||||
"bd_leader_center.uid_prefix": "UID: {uid}",
|
||||
"bd_leader_center.bd_number": "Número de BD",
|
||||
"bd_leader_center.agencies": "Agencias",
|
||||
"bd_leader_center.agency_number": "Número de agencias",
|
||||
"bd_leader_center.team_salary": "Salario del equipo",
|
||||
"bd_leader_center.team_recharge": "Recarga del equipo",
|
||||
"bd_leader_center.total_income": "Ingreso total",
|
||||
"bd_leader_center.previous_income": "Ingreso anterior",
|
||||
"bd_leader_center.in_progress": "En progreso",
|
||||
"bd_leader_center.invite": "Invitar",
|
||||
"bd_leader_center.invite_success": "Invitación enviada.",
|
||||
"bd_leader_center.tools": "Herramientas de líder BD",
|
||||
"agency_center.title": "Centro de agencia",
|
||||
"agency_center.back": "Volver",
|
||||
"agency_center.change_language": "Cambiar idioma",
|
||||
|
||||
@ -78,8 +78,6 @@
|
||||
"invite.noRankData": "Belum ada data peringkat",
|
||||
"invite.copied": "Disalin",
|
||||
"invite.copyFailed": "Gagal menyalin",
|
||||
"invite.notAvailable": "Belum tersedia",
|
||||
"invite.claimed": "Diklaim",
|
||||
"host_center.title": "Pusat Host",
|
||||
"host_center.back": "Kembali",
|
||||
"host_center.change_language": "Ganti bahasa",
|
||||
@ -306,31 +304,6 @@
|
||||
"bd_center.invitation_rejected": "Undangan ditolak.",
|
||||
"bd_center.load_messages_failed": "Gagal memuat pesan.",
|
||||
"bd_center.process_invitation_failed": "Gagal memproses. Coba lagi nanti.",
|
||||
"bd_leader_center.back": "Kembali",
|
||||
"bd_leader_center.title": "Pusat BD Leader",
|
||||
"bd_leader_center.change_language": "Ganti bahasa",
|
||||
"bd_leader_center.role": "BD Leader",
|
||||
"bd_leader_center.salary": "Gaji",
|
||||
"bd_leader_center.withdraw_exchange": "Tarik/Tukar",
|
||||
"bd_leader_center.salary_history": "Riwayat gaji",
|
||||
"bd_leader_center.invite_bd": "Undang BD",
|
||||
"bd_leader_center.bd_list": "Daftar BD",
|
||||
"bd_leader_center.close": "Tutup",
|
||||
"bd_leader_center.enter_user_id": "Masukkan ID Pengguna",
|
||||
"bd_leader_center.search": "Cari",
|
||||
"bd_leader_center.no_users_found": "Pengguna tidak ditemukan",
|
||||
"bd_leader_center.uid_prefix": "UID: {uid}",
|
||||
"bd_leader_center.bd_number": "Jumlah BD",
|
||||
"bd_leader_center.agencies": "Agency",
|
||||
"bd_leader_center.agency_number": "Jumlah agency",
|
||||
"bd_leader_center.team_salary": "Gaji tim",
|
||||
"bd_leader_center.team_recharge": "Recharge tim",
|
||||
"bd_leader_center.total_income": "Total pendapatan",
|
||||
"bd_leader_center.previous_income": "Pendapatan sebelumnya",
|
||||
"bd_leader_center.in_progress": "Sedang berjalan",
|
||||
"bd_leader_center.invite": "Undang",
|
||||
"bd_leader_center.invite_success": "Undangan terkirim.",
|
||||
"bd_leader_center.tools": "Alat BD Leader",
|
||||
"agency_center.title": "Pusat Agency",
|
||||
"agency_center.back": "Kembali",
|
||||
"agency_center.change_language": "Ganti bahasa",
|
||||
|
||||
@ -66,7 +66,7 @@
|
||||
"invite.claimed": "Alındı",
|
||||
"invite.claimSuccess": "Alındı",
|
||||
"invite.claimFailed": "Alma başarısız",
|
||||
"invite.notAvailable": "Henüz mevcut değil",
|
||||
"invite.notAvailable": "Henüz kullanılamaz",
|
||||
"invite.noRewardTasks": "Ödül görevi yok",
|
||||
"invite.rechargeMilestone": "Yükleme kilometre taşı {index}",
|
||||
"invite.validInviteMilestone": "Davet kilometre taşı {index}",
|
||||
@ -78,8 +78,6 @@
|
||||
"invite.noRankData": "Sıralama verisi yok",
|
||||
"invite.copied": "Kopyalandı",
|
||||
"invite.copyFailed": "Kopyalama başarısız",
|
||||
"invite.notAvailable": "Henüz kullanılamaz",
|
||||
"invite.claimed": "Alındı",
|
||||
"host_center.title": "Host Merkezi",
|
||||
"host_center.back": "Geri",
|
||||
"host_center.change_language": "Dili değiştir",
|
||||
@ -306,31 +304,6 @@
|
||||
"bd_center.invitation_rejected": "Davet reddedildi.",
|
||||
"bd_center.load_messages_failed": "Mesajlar yüklenemedi.",
|
||||
"bd_center.process_invitation_failed": "İşlem başarısız. Daha sonra tekrar deneyin.",
|
||||
"bd_leader_center.back": "Geri",
|
||||
"bd_leader_center.title": "BD Lider Merkezi",
|
||||
"bd_leader_center.change_language": "Dili değiştir",
|
||||
"bd_leader_center.role": "BD Lider",
|
||||
"bd_leader_center.salary": "Maaş",
|
||||
"bd_leader_center.withdraw_exchange": "Çek/Değiştir",
|
||||
"bd_leader_center.salary_history": "Maaş geçmişi",
|
||||
"bd_leader_center.invite_bd": "BD davet et",
|
||||
"bd_leader_center.bd_list": "BD listesi",
|
||||
"bd_leader_center.close": "Kapat",
|
||||
"bd_leader_center.enter_user_id": "Kullanıcı ID gir",
|
||||
"bd_leader_center.search": "Ara",
|
||||
"bd_leader_center.no_users_found": "Kullanıcı bulunamadı",
|
||||
"bd_leader_center.uid_prefix": "UID: {uid}",
|
||||
"bd_leader_center.bd_number": "BD sayısı",
|
||||
"bd_leader_center.agencies": "Ajanslar",
|
||||
"bd_leader_center.agency_number": "Ajans sayısı",
|
||||
"bd_leader_center.team_salary": "Takım maaşı",
|
||||
"bd_leader_center.team_recharge": "Takım yüklemesi",
|
||||
"bd_leader_center.total_income": "Toplam gelir",
|
||||
"bd_leader_center.previous_income": "Önceki gelir",
|
||||
"bd_leader_center.in_progress": "Devam ediyor",
|
||||
"bd_leader_center.invite": "Davet et",
|
||||
"bd_leader_center.invite_success": "Davet gönderildi.",
|
||||
"bd_leader_center.tools": "BD Lider araçları",
|
||||
"agency_center.title": "Ajans Merkezi",
|
||||
"agency_center.back": "Geri",
|
||||
"agency_center.change_language": "Dili değiştir",
|
||||
|
||||
@ -66,7 +66,7 @@
|
||||
"invite.claimed": "已领取",
|
||||
"invite.claimSuccess": "领取成功",
|
||||
"invite.claimFailed": "领取失败",
|
||||
"invite.notAvailable": "暂未达成",
|
||||
"invite.notAvailable": "暂不可领取",
|
||||
"invite.noRewardTasks": "暂无奖励任务",
|
||||
"invite.rechargeMilestone": "充值里程碑 {index}",
|
||||
"invite.validInviteMilestone": "邀请里程碑 {index}",
|
||||
@ -78,8 +78,6 @@
|
||||
"invite.noRankData": "暂无排行榜数据",
|
||||
"invite.copied": "已复制",
|
||||
"invite.copyFailed": "复制失败",
|
||||
"invite.notAvailable": "暂不可领取",
|
||||
"invite.claimed": "已领取",
|
||||
"host_center.title": "主播中心",
|
||||
"host_center.back": "返回",
|
||||
"host_center.change_language": "切换语言",
|
||||
@ -312,31 +310,6 @@
|
||||
"bd_center.invitation_rejected": "已拒绝邀请。",
|
||||
"bd_center.load_messages_failed": "消息加载失败。",
|
||||
"bd_center.process_invitation_failed": "处理失败,请稍后重试。",
|
||||
"bd_leader_center.back": "返回",
|
||||
"bd_leader_center.title": "BD Leader 中心",
|
||||
"bd_leader_center.change_language": "切换语言",
|
||||
"bd_leader_center.role": "BD Leader",
|
||||
"bd_leader_center.salary": "薪资",
|
||||
"bd_leader_center.withdraw_exchange": "提现/兑换",
|
||||
"bd_leader_center.salary_history": "薪资记录",
|
||||
"bd_leader_center.invite_bd": "邀请 BD",
|
||||
"bd_leader_center.bd_list": "BD 列表",
|
||||
"bd_leader_center.close": "关闭",
|
||||
"bd_leader_center.enter_user_id": "输入用户 ID",
|
||||
"bd_leader_center.search": "搜索",
|
||||
"bd_leader_center.no_users_found": "未找到用户",
|
||||
"bd_leader_center.uid_prefix": "UID: {uid}",
|
||||
"bd_leader_center.bd_number": "BD 数量",
|
||||
"bd_leader_center.agencies": "Agency",
|
||||
"bd_leader_center.agency_number": "Agency 数量",
|
||||
"bd_leader_center.team_salary": "团队薪资",
|
||||
"bd_leader_center.team_recharge": "团队充值",
|
||||
"bd_leader_center.total_income": "总收入",
|
||||
"bd_leader_center.previous_income": "上期收入",
|
||||
"bd_leader_center.in_progress": "进行中",
|
||||
"bd_leader_center.invite": "邀请",
|
||||
"bd_leader_center.invite_success": "邀请已提交。",
|
||||
"bd_leader_center.tools": "BD Leader 工具",
|
||||
"agency_center.title": "Agency Center",
|
||||
"agency_center.back": "返回",
|
||||
"agency_center.change_language": "切换语言",
|
||||
|
||||
@ -6,322 +6,16 @@
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"
|
||||
/>
|
||||
<title>BD Leader Center</title>
|
||||
<link rel="stylesheet" href="../../common/theme.css" />
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="../common/center.css?v=20260604-bd-leader"
|
||||
/>
|
||||
<link rel="stylesheet" href="./style.css?v=20260604-bd-only" />
|
||||
<title>Superadmin Center</title>
|
||||
<script>
|
||||
(function () {
|
||||
var query = window.location.search || '';
|
||||
var hash = window.location.hash || '';
|
||||
window.location.replace(
|
||||
'../superadmin-center/index.html' + query + hash
|
||||
);
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="bd-leader-center" aria-label="BD Leader Center">
|
||||
<div class="hero-bg" aria-hidden="true"></div>
|
||||
|
||||
<nav class="title-bar">
|
||||
<button
|
||||
class="back-button"
|
||||
id="backButton"
|
||||
type="button"
|
||||
aria-label="Back"
|
||||
data-i18n-aria="bd_leader_center.back"
|
||||
>
|
||||
<svg viewBox="0 0 32 32" aria-hidden="true">
|
||||
<path d="M20 8 12 16l8 8" />
|
||||
</svg>
|
||||
</button>
|
||||
<h1 data-i18n="bd_leader_center.title">BD Leader Center</h1>
|
||||
<div class="language-switcher">
|
||||
<button
|
||||
class="language-button"
|
||||
type="button"
|
||||
aria-label="Change language"
|
||||
aria-expanded="false"
|
||||
data-language-toggle
|
||||
data-current-lang
|
||||
data-i18n-aria="bd_leader_center.change_language"
|
||||
>
|
||||
EN
|
||||
</button>
|
||||
<div class="language-menu" data-language-menu hidden>
|
||||
<button type="button" data-lang-option="en">EN</button>
|
||||
<button type="button" data-lang-option="ar">AR</button>
|
||||
<button type="button" data-lang-option="tr">TR</button>
|
||||
<button type="button" data-lang-option="es">ES</button>
|
||||
<button type="button" data-lang-option="zh">ZH</button>
|
||||
<button type="button" data-lang-option="id">ID</button>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<main class="content">
|
||||
<section class="card profile-card">
|
||||
<div class="avatar-shell">
|
||||
<img class="avatar-image" id="profileAvatar" alt="" />
|
||||
<div
|
||||
class="avatar-fallback"
|
||||
id="profileAvatarFallback"
|
||||
aria-hidden="true"
|
||||
hidden
|
||||
>
|
||||
S
|
||||
</div>
|
||||
</div>
|
||||
<div class="profile-copy">
|
||||
<div
|
||||
class="role-pill"
|
||||
data-i18n="bd_leader_center.role"
|
||||
>
|
||||
BD Leader
|
||||
</div>
|
||||
<div class="name" id="profileName">-</div>
|
||||
<div class="meta" id="profileUID">UID: -</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="card salary-card">
|
||||
<div class="salary-head">
|
||||
<h2 data-i18n="bd_leader_center.salary">Salary</h2>
|
||||
<button
|
||||
class="text-link"
|
||||
id="withdrawExchangeButton"
|
||||
type="button"
|
||||
data-i18n="bd_leader_center.withdraw_exchange"
|
||||
>
|
||||
Withdraw/Exchange
|
||||
</button>
|
||||
</div>
|
||||
<div class="salary-value">
|
||||
<span class="coin-icon" aria-hidden="true">$</span>
|
||||
<strong id="availableBalance">0.00</strong>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section
|
||||
class="card menu-card"
|
||||
aria-label="BD Leader tools"
|
||||
data-i18n-aria="bd_leader_center.tools"
|
||||
>
|
||||
<button
|
||||
class="menu-row"
|
||||
type="button"
|
||||
data-action="history"
|
||||
>
|
||||
<span class="menu-icon" aria-hidden="true">
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path d="M12 4a8 8 0 1 1-7.2 4.5" />
|
||||
<path d="M5 4v5h5" />
|
||||
<path d="M12 8v5l3 2" />
|
||||
</svg>
|
||||
</span>
|
||||
<span
|
||||
class="menu-label"
|
||||
data-i18n="bd_leader_center.salary_history"
|
||||
>Salary History</span
|
||||
>
|
||||
<span class="chevron" aria-hidden="true">›</span>
|
||||
</button>
|
||||
<button
|
||||
class="menu-row"
|
||||
type="button"
|
||||
data-action="invite-bd"
|
||||
>
|
||||
<span class="menu-icon" aria-hidden="true">
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path d="M10 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8Z" />
|
||||
<path
|
||||
d="M3 21c.9-4.7 3.2-7 7-7 2 0 3.7.7 5 2"
|
||||
/>
|
||||
<path d="M19 9v8" />
|
||||
<path d="M15 13h8" />
|
||||
</svg>
|
||||
</span>
|
||||
<span
|
||||
class="menu-label"
|
||||
data-i18n="bd_leader_center.invite_bd"
|
||||
>Invite BD</span
|
||||
>
|
||||
<span class="chevron" aria-hidden="true">›</span>
|
||||
</button>
|
||||
</section>
|
||||
|
||||
<section class="card team-card">
|
||||
<div class="team-head">
|
||||
<h2 data-i18n="bd_leader_center.bd_list">BD List</h2>
|
||||
</div>
|
||||
<div class="team-summary" id="teamSummary"></div>
|
||||
<div class="team-list" id="teamList"></div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<div class="home-indicator" aria-hidden="true"></div>
|
||||
|
||||
<div
|
||||
class="sheet-modal"
|
||||
id="historyModal"
|
||||
hidden
|
||||
aria-hidden="true"
|
||||
>
|
||||
<button
|
||||
class="modal-backdrop"
|
||||
type="button"
|
||||
data-close-modal="historyModal"
|
||||
aria-label="Close"
|
||||
data-i18n-aria="bd_leader_center.close"
|
||||
></button>
|
||||
<section
|
||||
class="bottom-sheet history-sheet"
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-labelledby="historyTitle"
|
||||
>
|
||||
<div class="sheet-head">
|
||||
<h2
|
||||
id="historyTitle"
|
||||
data-i18n="bd_leader_center.salary_history"
|
||||
>
|
||||
Salary History
|
||||
</h2>
|
||||
<button
|
||||
class="sheet-close"
|
||||
type="button"
|
||||
data-close-modal="historyModal"
|
||||
aria-label="Close"
|
||||
data-i18n-aria="bd_leader_center.close"
|
||||
>
|
||||
×
|
||||
</button>
|
||||
</div>
|
||||
<div class="history-summary" id="historySummary"></div>
|
||||
<div class="history-list" id="historyList"></div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="sheet-modal"
|
||||
id="detailsModal"
|
||||
hidden
|
||||
aria-hidden="true"
|
||||
>
|
||||
<button
|
||||
class="modal-backdrop"
|
||||
type="button"
|
||||
data-close-modal="detailsModal"
|
||||
aria-label="Close"
|
||||
data-i18n-aria="bd_leader_center.close"
|
||||
></button>
|
||||
<section
|
||||
class="bottom-sheet history-sheet"
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-labelledby="detailsTitle"
|
||||
>
|
||||
<div class="sheet-head">
|
||||
<h2 id="detailsTitle">-</h2>
|
||||
<button
|
||||
class="sheet-close"
|
||||
type="button"
|
||||
data-close-modal="detailsModal"
|
||||
aria-label="Close"
|
||||
data-i18n-aria="bd_leader_center.close"
|
||||
>
|
||||
×
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="history-summary compact"
|
||||
id="detailsSummary"
|
||||
></div>
|
||||
<div class="history-list" id="detailsList"></div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="invite-modal"
|
||||
id="inviteModal"
|
||||
hidden
|
||||
aria-hidden="true"
|
||||
>
|
||||
<button
|
||||
class="modal-backdrop"
|
||||
type="button"
|
||||
data-close-modal="inviteModal"
|
||||
aria-label="Close"
|
||||
data-i18n-aria="bd_leader_center.close"
|
||||
></button>
|
||||
<section
|
||||
class="invite-dialog"
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-labelledby="inviteModalTitle"
|
||||
>
|
||||
<div class="invite-head">
|
||||
<h2
|
||||
id="inviteModalTitle"
|
||||
data-i18n="bd_leader_center.invite_bd"
|
||||
>
|
||||
Invite BD
|
||||
</h2>
|
||||
<button
|
||||
class="invite-close"
|
||||
type="button"
|
||||
data-close-modal="inviteModal"
|
||||
aria-label="Close"
|
||||
data-i18n-aria="bd_leader_center.close"
|
||||
>
|
||||
×
|
||||
</button>
|
||||
</div>
|
||||
<div class="invite-body">
|
||||
<form class="invite-search-form" id="inviteSearchForm">
|
||||
<label class="invite-field">
|
||||
<span
|
||||
data-i18n="bd_leader_center.enter_user_id"
|
||||
>Enter User ID</span
|
||||
>
|
||||
<div class="invite-search-control">
|
||||
<input
|
||||
id="inviteSearchInput"
|
||||
type="text"
|
||||
inputmode="text"
|
||||
autocomplete="off"
|
||||
placeholder="Enter User ID"
|
||||
data-i18n-placeholder="bd_leader_center.enter_user_id"
|
||||
/>
|
||||
<button
|
||||
id="inviteSearchButton"
|
||||
type="submit"
|
||||
data-i18n="bd_leader_center.search"
|
||||
>
|
||||
Search
|
||||
</button>
|
||||
</div>
|
||||
</label>
|
||||
</form>
|
||||
<div
|
||||
class="invite-status"
|
||||
id="inviteStatus"
|
||||
role="status"
|
||||
hidden
|
||||
></div>
|
||||
<div class="invite-list" id="inviteList"></div>
|
||||
<div
|
||||
class="invite-empty"
|
||||
id="inviteEmpty"
|
||||
data-i18n="bd_leader_center.no_users_found"
|
||||
>
|
||||
No users found
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="../../common/toast.js"></script>
|
||||
<script src="../../common/jsbridge.js"></script>
|
||||
<script src="../../common/api.js?v=20260604-bd-leader-api"></script>
|
||||
<script src="../../common/i18n.js?v=20260604"></script>
|
||||
<script src="./script.js?v=20260604-bd-only"></script>
|
||||
</body>
|
||||
<body></body>
|
||||
</html>
|
||||
|
||||
@ -1,876 +0,0 @@
|
||||
(function () {
|
||||
var query = new URLSearchParams(window.location.search);
|
||||
var state = {
|
||||
inviteQuery: '',
|
||||
inviteStatus: '',
|
||||
inviteStatusType: '',
|
||||
inviteSearchResults: [],
|
||||
inviteSubmitting: {},
|
||||
selectedDetails: null,
|
||||
isMock: query.get('mock') === '1',
|
||||
};
|
||||
|
||||
var mock = {
|
||||
profile: {
|
||||
name: 'Leader Sophia',
|
||||
uid: 'BL-100001',
|
||||
avatar: avatarData('L', '#dbc8ff', '#7d57c7'),
|
||||
},
|
||||
balance: {
|
||||
available: 168250.5,
|
||||
},
|
||||
overview: {
|
||||
totalBD: 8,
|
||||
totalAgency: 36,
|
||||
totalHosts: 428,
|
||||
teamSalary: 586420.8,
|
||||
teamRecharge: 1268800,
|
||||
},
|
||||
bdList: [
|
||||
{
|
||||
id: '880001',
|
||||
userId: '3200901',
|
||||
name: 'Mila BD',
|
||||
avatar: avatarData('M', '#dbc8ff', '#7d57c7'),
|
||||
agencies: 12,
|
||||
hosts: 126,
|
||||
salary: 128450.35,
|
||||
recharge: 356900,
|
||||
},
|
||||
{
|
||||
id: '880018',
|
||||
userId: '3200918',
|
||||
name: 'Jasmine BD',
|
||||
avatar: avatarData('J', '#f4ebff', '#7d57c7'),
|
||||
agencies: 9,
|
||||
hosts: 104,
|
||||
salary: 106280.4,
|
||||
recharge: 298520,
|
||||
},
|
||||
{
|
||||
id: '880026',
|
||||
userId: '3200926',
|
||||
name: 'Omar BD',
|
||||
avatar: avatarData('O', '#efe4ff', '#7d57c7'),
|
||||
agencies: 7,
|
||||
hosts: 82,
|
||||
salary: 86140,
|
||||
recharge: 214330,
|
||||
},
|
||||
],
|
||||
history: [
|
||||
{
|
||||
month: '2026-06',
|
||||
status: 'In progress',
|
||||
bdCount: 8,
|
||||
agencyCount: 36,
|
||||
totalSalary: 586420.8,
|
||||
totalRecharge: 1268800,
|
||||
},
|
||||
{
|
||||
month: '2026-05',
|
||||
status: 'Completed',
|
||||
bdCount: 7,
|
||||
agencyCount: 31,
|
||||
totalSalary: 520180.25,
|
||||
totalRecharge: 1112900,
|
||||
},
|
||||
{
|
||||
month: '2026-04',
|
||||
status: 'Completed',
|
||||
bdCount: 6,
|
||||
agencyCount: 26,
|
||||
totalSalary: 462300,
|
||||
totalRecharge: 980400,
|
||||
},
|
||||
],
|
||||
inviteRecords: {
|
||||
bd: [
|
||||
{
|
||||
id: 'bd-inv-01',
|
||||
status: 'Success',
|
||||
profile: {
|
||||
userId: '3200901',
|
||||
id: '3200901',
|
||||
name: 'BD_River',
|
||||
account: '880099',
|
||||
avatar: avatarData('R', '#dbc8ff', '#7d57c7'),
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
searchPool: {
|
||||
bd: [
|
||||
{
|
||||
userId: '3200902',
|
||||
id: '3200902',
|
||||
name: 'BD_Kai',
|
||||
account: '880102',
|
||||
avatar: avatarData('K', '#dbc8ff', '#7d57c7'),
|
||||
},
|
||||
{
|
||||
userId: '3200903',
|
||||
id: '3200903',
|
||||
name: 'BD_Ayla',
|
||||
account: '880103',
|
||||
avatar: avatarData('A', '#efe4ff', '#7d57c7'),
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
var data = {
|
||||
profile: mock.profile,
|
||||
balance: mock.balance,
|
||||
overview: mock.overview,
|
||||
bdList: mock.bdList,
|
||||
history: mock.history,
|
||||
inviteRecords: mock.inviteRecords,
|
||||
};
|
||||
|
||||
function $(id) {
|
||||
return document.getElementById(id);
|
||||
}
|
||||
|
||||
function avatarData(text, background, foreground) {
|
||||
var value =
|
||||
String(text || 'S')
|
||||
.trim()
|
||||
.charAt(0) || 'S';
|
||||
var letter = value.replace(/[<>&"']/g, '');
|
||||
var svg =
|
||||
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96">' +
|
||||
'<rect width="96" height="96" rx="48" fill="' +
|
||||
background +
|
||||
'"/>' +
|
||||
'<text x="50%" y="54%" text-anchor="middle" dominant-baseline="middle" fill="' +
|
||||
foreground +
|
||||
'" font-family="Arial, sans-serif" font-size="38" font-weight="800">' +
|
||||
letter +
|
||||
'</text>' +
|
||||
'</svg>';
|
||||
return 'data:image/svg+xml;charset=UTF-8,' + encodeURIComponent(svg);
|
||||
}
|
||||
|
||||
function t(key, fallback) {
|
||||
return window.HyAppI18n && window.HyAppI18n.t
|
||||
? window.HyAppI18n.t(key, fallback)
|
||||
: fallback || key;
|
||||
}
|
||||
|
||||
function money(value) {
|
||||
return Number(value || 0).toLocaleString('en-US', {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
});
|
||||
}
|
||||
|
||||
function compactMoney(value) {
|
||||
var amount = Number(value || 0);
|
||||
var abs = Math.abs(amount);
|
||||
if (abs >= 1000000) {
|
||||
return (
|
||||
(amount / 1000000).toLocaleString('en-US', {
|
||||
minimumFractionDigits: 0,
|
||||
maximumFractionDigits: 2,
|
||||
}) + 'M'
|
||||
);
|
||||
}
|
||||
if (abs >= 1000) {
|
||||
return (
|
||||
(amount / 1000).toLocaleString('en-US', {
|
||||
minimumFractionDigits: 0,
|
||||
maximumFractionDigits: 2,
|
||||
}) + 'K'
|
||||
);
|
||||
}
|
||||
return money(amount);
|
||||
}
|
||||
|
||||
function count(value) {
|
||||
return Number(value || 0).toLocaleString('en-US', {
|
||||
maximumFractionDigits: 0,
|
||||
});
|
||||
}
|
||||
|
||||
function initial(text) {
|
||||
return String(text || '')
|
||||
.trim()
|
||||
.charAt(0)
|
||||
.toUpperCase();
|
||||
}
|
||||
|
||||
function displayName(user, fallback) {
|
||||
return (
|
||||
(user && (user.username || user.name || user.display_user_id)) ||
|
||||
fallback ||
|
||||
'-'
|
||||
);
|
||||
}
|
||||
|
||||
function displayID(user) {
|
||||
return (
|
||||
(user && (user.display_user_id || user.displayUserID)) ||
|
||||
(user && (user.user_id || user.userId)) ||
|
||||
'-'
|
||||
);
|
||||
}
|
||||
|
||||
function displayAmount(salary) {
|
||||
if (!salary) return 0;
|
||||
if (salary.display_amount !== undefined) return salary.display_amount;
|
||||
if (salary.displayAmount !== undefined) return salary.displayAmount;
|
||||
return Number(salary.available_amount || salary.availableAmount || 0) / 100;
|
||||
}
|
||||
|
||||
function toast(message) {
|
||||
if (!message) return;
|
||||
if (window.HyAppToast && window.HyAppToast.show) {
|
||||
window.HyAppToast.show(message);
|
||||
return;
|
||||
}
|
||||
window.alert(message);
|
||||
}
|
||||
|
||||
function setImage(image, fallback, src, name) {
|
||||
if (!image || !fallback) return;
|
||||
fallback.textContent = initial(name) || 'S';
|
||||
if (!src) {
|
||||
image.hidden = true;
|
||||
fallback.hidden = false;
|
||||
return;
|
||||
}
|
||||
image.onload = function () {
|
||||
image.hidden = false;
|
||||
fallback.hidden = true;
|
||||
};
|
||||
image.onerror = function () {
|
||||
image.hidden = true;
|
||||
fallback.hidden = false;
|
||||
};
|
||||
image.src = src;
|
||||
}
|
||||
|
||||
function makeAvatar(item) {
|
||||
var avatar = document.createElement('div');
|
||||
var fallback = document.createElement('span');
|
||||
avatar.className = 'member-avatar';
|
||||
fallback.className = 'member-fallback';
|
||||
fallback.textContent = initial(item.name) || 'S';
|
||||
avatar.appendChild(fallback);
|
||||
if (item.avatar) {
|
||||
var image = document.createElement('img');
|
||||
image.src = item.avatar;
|
||||
image.alt = '';
|
||||
image.addEventListener('load', function () {
|
||||
fallback.hidden = true;
|
||||
});
|
||||
image.addEventListener('error', function () {
|
||||
image.remove();
|
||||
fallback.hidden = false;
|
||||
});
|
||||
avatar.appendChild(image);
|
||||
}
|
||||
return avatar;
|
||||
}
|
||||
|
||||
function replaceChildren(node, children) {
|
||||
node.textContent = '';
|
||||
children.forEach(function (child) {
|
||||
node.appendChild(child);
|
||||
});
|
||||
}
|
||||
|
||||
function applyMockData() {
|
||||
data.profile = mock.profile;
|
||||
data.balance = mock.balance;
|
||||
data.overview = mock.overview;
|
||||
data.bdList = mock.bdList;
|
||||
data.history = mock.history;
|
||||
data.inviteRecords = mock.inviteRecords;
|
||||
}
|
||||
|
||||
function applyEmptyData() {
|
||||
data.profile = { name: '-', uid: '-', avatar: '' };
|
||||
data.balance = { available: 0 };
|
||||
data.overview = {
|
||||
totalBD: 0,
|
||||
totalAgency: 0,
|
||||
totalHosts: 0,
|
||||
teamSalary: 0,
|
||||
teamRecharge: 0,
|
||||
};
|
||||
data.bdList = [];
|
||||
data.history = [];
|
||||
data.inviteRecords = { bd: [] };
|
||||
}
|
||||
|
||||
function normalizeOverview(payload) {
|
||||
var overview = payload && payload.overview ? payload.overview : {};
|
||||
return {
|
||||
totalBD: overview.total_bd || overview.totalBD || 0,
|
||||
totalAgency: overview.total_agency || overview.totalAgency || 0,
|
||||
totalHosts: overview.total_hosts || overview.totalHosts || 0,
|
||||
teamSalary: overview.team_salary || overview.teamSalary || 0,
|
||||
teamRecharge: overview.team_recharge || overview.teamRecharge || 0,
|
||||
};
|
||||
}
|
||||
|
||||
function normalizeBDItem(item) {
|
||||
var name = displayName(item, 'BD ' + displayID(item));
|
||||
return {
|
||||
id: displayID(item),
|
||||
userId: item.user_id || item.userId || '',
|
||||
name: name,
|
||||
avatar: item.avatar || '',
|
||||
agencies: item.agency_count || item.agencies || 0,
|
||||
hosts: item.host_count || item.hosts || 0,
|
||||
salary: item.salary === undefined ? null : item.salary,
|
||||
recharge: item.recharge === undefined ? null : item.recharge,
|
||||
sideValue:
|
||||
count(item.agency_count || item.agencies || 0) +
|
||||
' ' +
|
||||
t('bd_leader_center.agencies', 'Agencies'),
|
||||
sideSub: '',
|
||||
};
|
||||
}
|
||||
|
||||
function normalizeInviteProfile(payload) {
|
||||
var user = payload && (payload.user || payload.profile || payload);
|
||||
if (!user || !(user.user_id || user.userId)) return null;
|
||||
var id = displayID(user);
|
||||
return {
|
||||
userId: user.user_id || user.userId,
|
||||
id: user.user_id || user.userId,
|
||||
name: displayName(user, 'User ' + id),
|
||||
account: id,
|
||||
avatar: user.avatar || '',
|
||||
};
|
||||
}
|
||||
|
||||
function commandID(prefix, targetUserID) {
|
||||
return [
|
||||
prefix,
|
||||
targetUserID,
|
||||
Date.now(),
|
||||
Math.random().toString(16).slice(2),
|
||||
].join('-');
|
||||
}
|
||||
|
||||
function api() {
|
||||
return window.HyAppAPI || {};
|
||||
}
|
||||
|
||||
function loadRealData() {
|
||||
var centerAPI = api().bdLeaderCenter;
|
||||
if (!centerAPI) {
|
||||
toast('API module is not ready.');
|
||||
return Promise.reject(new Error('api_not_ready'));
|
||||
}
|
||||
return Promise.all([
|
||||
centerAPI.overview(),
|
||||
centerAPI.bds(50),
|
||||
])
|
||||
.then(function (results) {
|
||||
var overviewPayload = results[0] || {};
|
||||
var bdPayload = results[1] || {};
|
||||
var profile = overviewPayload.profile || {};
|
||||
var overview = normalizeOverview(overviewPayload);
|
||||
var bds = (bdPayload.items || []).map(normalizeBDItem);
|
||||
overview.teamSalary = displayAmount(overviewPayload.salary);
|
||||
data.profile = {
|
||||
name: displayName(profile, 'BD Leader'),
|
||||
uid: displayID(profile),
|
||||
avatar: profile.avatar || '',
|
||||
};
|
||||
data.balance = {
|
||||
available: displayAmount(overviewPayload.salary),
|
||||
};
|
||||
data.overview = overview;
|
||||
data.bdList = bds;
|
||||
data.history = [
|
||||
{
|
||||
month: new Date().toISOString().slice(0, 7),
|
||||
status: 'In progress',
|
||||
bdCount: overview.totalBD,
|
||||
agencyCount: overview.totalAgency,
|
||||
totalSalary: overview.teamSalary,
|
||||
totalRecharge: overview.teamRecharge,
|
||||
},
|
||||
];
|
||||
data.inviteRecords = { bd: [] };
|
||||
render();
|
||||
})
|
||||
.catch(function (error) {
|
||||
toast(error.message || 'Load failed.');
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
|
||||
function renderProfile() {
|
||||
$('profileName').textContent = data.profile.name;
|
||||
$('profileUID').textContent = t(
|
||||
'bd_leader_center.uid_prefix',
|
||||
'UID: {id}'
|
||||
).replace('{id}', data.profile.uid);
|
||||
setImage(
|
||||
$('profileAvatar'),
|
||||
$('profileAvatarFallback'),
|
||||
data.profile.avatar,
|
||||
data.profile.name
|
||||
);
|
||||
}
|
||||
|
||||
function renderBalance() {
|
||||
$('availableBalance').textContent = money(data.balance.available);
|
||||
}
|
||||
|
||||
function summaryCell(label, value) {
|
||||
var cell = document.createElement('div');
|
||||
var labelNode = document.createElement('span');
|
||||
var valueNode = document.createElement('strong');
|
||||
labelNode.textContent = label;
|
||||
valueNode.textContent = value;
|
||||
cell.appendChild(labelNode);
|
||||
cell.appendChild(valueNode);
|
||||
return cell;
|
||||
}
|
||||
|
||||
function renderTeamSummary() {
|
||||
$('teamSummary').classList.add('is-two');
|
||||
var cells = [
|
||||
summaryCell(
|
||||
t('bd_leader_center.bd_number', 'BD number'),
|
||||
count(data.overview.totalBD)
|
||||
),
|
||||
summaryCell(
|
||||
t('bd_leader_center.agencies', 'Agencies'),
|
||||
count(data.overview.totalAgency)
|
||||
),
|
||||
];
|
||||
replaceChildren($('teamSummary'), cells);
|
||||
}
|
||||
|
||||
function createMemberRow(item) {
|
||||
var row = document.createElement('article');
|
||||
var main = document.createElement('div');
|
||||
var name = document.createElement('div');
|
||||
var meta = document.createElement('div');
|
||||
var side = document.createElement('div');
|
||||
var salary = document.createElement('strong');
|
||||
var sub = document.createElement('span');
|
||||
var sideValue =
|
||||
item.sideValue ||
|
||||
(item.salary === null || item.salary === undefined
|
||||
? ''
|
||||
: '$' + money(item.salary));
|
||||
var subText =
|
||||
item.sideSub !== undefined
|
||||
? item.sideSub
|
||||
: count(item.agencies) +
|
||||
' ' +
|
||||
t('bd_leader_center.agencies', 'Agencies');
|
||||
|
||||
row.className = 'member-row';
|
||||
main.className = 'member-main';
|
||||
name.className = 'member-name';
|
||||
meta.className = 'member-meta';
|
||||
side.className = 'member-side';
|
||||
|
||||
name.textContent = item.name;
|
||||
meta.textContent = 'ID: ' + item.id;
|
||||
salary.textContent = sideValue || subText;
|
||||
sub.textContent = sideValue ? subText : '';
|
||||
|
||||
main.appendChild(name);
|
||||
main.appendChild(meta);
|
||||
side.appendChild(salary);
|
||||
if (sub.textContent) side.appendChild(sub);
|
||||
row.appendChild(makeAvatar(item));
|
||||
row.appendChild(main);
|
||||
row.appendChild(side);
|
||||
row.addEventListener('click', function () {
|
||||
state.selectedDetails = item;
|
||||
renderDetails();
|
||||
openModal('detailsModal');
|
||||
});
|
||||
return row;
|
||||
}
|
||||
|
||||
function renderTeamList() {
|
||||
renderTeamSummary();
|
||||
replaceChildren(
|
||||
$('teamList'),
|
||||
data.bdList.map(function (item) {
|
||||
return createMemberRow(item);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function renderHistory() {
|
||||
var previous = data.history[1] || { totalSalary: 0 };
|
||||
replaceChildren($('historySummary'), [
|
||||
summaryCell(
|
||||
t('bd_leader_center.total_income', 'Total income'),
|
||||
'$' + money(data.overview.teamSalary)
|
||||
),
|
||||
summaryCell(
|
||||
t('bd_leader_center.previous_income', 'Previous income'),
|
||||
'$' + money(previous.totalSalary)
|
||||
),
|
||||
]);
|
||||
replaceChildren(
|
||||
$('historyList'),
|
||||
data.history.map(function (item) {
|
||||
var row = document.createElement('article');
|
||||
var title = document.createElement('div');
|
||||
var status = document.createElement('span');
|
||||
var grid = document.createElement('div');
|
||||
row.className = 'history-row';
|
||||
title.className = 'history-title';
|
||||
status.className = 'status-tag';
|
||||
grid.className = 'history-grid';
|
||||
title.textContent = item.month;
|
||||
status.textContent = item.status;
|
||||
grid.appendChild(
|
||||
summaryCell(
|
||||
t('bd_leader_center.bd_number', 'BD number'),
|
||||
count(item.bdCount)
|
||||
)
|
||||
);
|
||||
grid.appendChild(
|
||||
summaryCell(
|
||||
t('bd_leader_center.agency_number', 'Agency number'),
|
||||
count(item.agencyCount)
|
||||
)
|
||||
);
|
||||
grid.appendChild(
|
||||
summaryCell(
|
||||
t('bd_leader_center.team_salary', 'Team salary'),
|
||||
'$' + compactMoney(item.totalSalary)
|
||||
)
|
||||
);
|
||||
row.appendChild(status);
|
||||
row.appendChild(title);
|
||||
row.appendChild(grid);
|
||||
return row;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function renderDetails() {
|
||||
var item = state.selectedDetails;
|
||||
var summaryRows;
|
||||
if (!item) return;
|
||||
$('detailsTitle').textContent = item.name;
|
||||
summaryRows = [summaryCell('ID', item.id)];
|
||||
if (item.salary !== null && item.salary !== undefined) {
|
||||
summaryRows.push(
|
||||
summaryCell(
|
||||
t('bd_leader_center.team_salary', 'Team salary'),
|
||||
'$' + money(item.salary)
|
||||
)
|
||||
);
|
||||
}
|
||||
if (item.recharge !== null && item.recharge !== undefined) {
|
||||
summaryRows.push(
|
||||
summaryCell(
|
||||
t('bd_leader_center.team_recharge', 'Team recharge'),
|
||||
'$' + money(item.recharge)
|
||||
)
|
||||
);
|
||||
}
|
||||
replaceChildren($('detailsSummary'), summaryRows);
|
||||
replaceChildren($('detailsList'), [
|
||||
createReadonlyLine(
|
||||
t('bd_leader_center.agencies', 'Agencies'),
|
||||
count(item.agencies)
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
function createReadonlyLine(label, value) {
|
||||
var row = document.createElement('div');
|
||||
var labelNode = document.createElement('span');
|
||||
var valueNode = document.createElement('strong');
|
||||
row.className = 'readonly-line';
|
||||
labelNode.textContent = label;
|
||||
valueNode.textContent = value;
|
||||
row.appendChild(labelNode);
|
||||
row.appendChild(valueNode);
|
||||
return row;
|
||||
}
|
||||
|
||||
function inviteTitle() {
|
||||
return t('bd_leader_center.invite_bd', 'Invite BD');
|
||||
}
|
||||
|
||||
function inviteRecords() {
|
||||
if (!state.inviteQuery) return data.inviteRecords.bd || [];
|
||||
if (!state.isMock) return state.inviteSearchResults;
|
||||
var keyword = state.inviteQuery.toLowerCase();
|
||||
return mock.searchPool.bd.filter(function (item) {
|
||||
return (
|
||||
item.name.toLowerCase().indexOf(keyword) >= 0 ||
|
||||
item.account.indexOf(keyword) >= 0 ||
|
||||
item.id.indexOf(keyword) >= 0
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function renderInvite() {
|
||||
$('inviteModalTitle').textContent = inviteTitle();
|
||||
var status = $('inviteStatus');
|
||||
var records = inviteRecords();
|
||||
status.hidden = !state.inviteStatus;
|
||||
status.textContent = state.inviteStatus;
|
||||
status.className =
|
||||
'invite-status' +
|
||||
(state.inviteStatusType ? ' ' + state.inviteStatusType : '');
|
||||
|
||||
$('inviteEmpty').hidden = records.length > 0 || !!state.inviteStatus;
|
||||
replaceChildren(
|
||||
$('inviteList'),
|
||||
records.map(function (record) {
|
||||
var profile = record.profile || record;
|
||||
var card = document.createElement('article');
|
||||
var main = document.createElement('div');
|
||||
var name = document.createElement('div');
|
||||
var meta = document.createElement('div');
|
||||
var action = document.createElement('button');
|
||||
var submitting = !!state.inviteSubmitting[profile.userId];
|
||||
card.className = 'invite-card';
|
||||
main.className = 'invite-main';
|
||||
name.className = 'invite-name';
|
||||
meta.className = 'invite-meta';
|
||||
action.className = 'invite-action';
|
||||
action.type = 'button';
|
||||
name.textContent = profile.name;
|
||||
meta.textContent = 'ID: ' + profile.account;
|
||||
action.textContent =
|
||||
record.status ||
|
||||
(submitting
|
||||
? t('bd_leader_center.in_progress', 'In progress')
|
||||
: t('bd_leader_center.invite', 'Invite'));
|
||||
action.disabled = !!record.status || submitting;
|
||||
action.addEventListener('click', function () {
|
||||
submitInvite(record, profile);
|
||||
});
|
||||
main.appendChild(name);
|
||||
main.appendChild(meta);
|
||||
card.appendChild(makeAvatar(profile));
|
||||
card.appendChild(main);
|
||||
card.appendChild(action);
|
||||
return card;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function searchInviteProfile(queryValue) {
|
||||
if (state.isMock) {
|
||||
renderInvite();
|
||||
return;
|
||||
}
|
||||
if (!api().user || !api().user.resolveDisplayUserID) {
|
||||
state.inviteStatus = 'API module is not ready.';
|
||||
state.inviteStatusType = 'warning';
|
||||
renderInvite();
|
||||
return;
|
||||
}
|
||||
state.inviteSearchResults = [];
|
||||
state.inviteStatus = t('bd_leader_center.in_progress', 'In progress');
|
||||
state.inviteStatusType = '';
|
||||
renderInvite();
|
||||
api()
|
||||
.user.resolveDisplayUserID(queryValue)
|
||||
.then(function (payload) {
|
||||
var profile = normalizeInviteProfile(payload);
|
||||
state.inviteStatus = '';
|
||||
state.inviteStatusType = '';
|
||||
state.inviteSearchResults = profile ? [profile] : [];
|
||||
renderInvite();
|
||||
})
|
||||
.catch(function (error) {
|
||||
state.inviteSearchResults = [];
|
||||
state.inviteStatus =
|
||||
error.message ||
|
||||
t('bd_leader_center.no_users_found', 'No users found');
|
||||
state.inviteStatusType = 'warning';
|
||||
renderInvite();
|
||||
});
|
||||
}
|
||||
|
||||
function submitInvite(record, profile) {
|
||||
var targetUserID = String(profile.userId || profile.id || '');
|
||||
var centerAPI = api().bdLeaderCenter;
|
||||
if (!targetUserID) return;
|
||||
if (state.isMock) {
|
||||
record.status = 'Success';
|
||||
state.inviteStatus = t(
|
||||
'bd_leader_center.invite_success',
|
||||
'Invitation submitted.'
|
||||
);
|
||||
state.inviteStatusType = 'success';
|
||||
renderInvite();
|
||||
return;
|
||||
}
|
||||
if (!centerAPI) {
|
||||
state.inviteStatus = 'API module is not ready.';
|
||||
state.inviteStatusType = 'warning';
|
||||
renderInvite();
|
||||
return;
|
||||
}
|
||||
state.inviteSubmitting[targetUserID] = true;
|
||||
renderInvite();
|
||||
var payload = {
|
||||
command_id: commandID('bd', targetUserID),
|
||||
target_user_id: targetUserID,
|
||||
};
|
||||
centerAPI
|
||||
.inviteBD(payload)
|
||||
.then(function () {
|
||||
record.status = 'Success';
|
||||
state.inviteStatus = t(
|
||||
'bd_leader_center.invite_success',
|
||||
'Invitation submitted.'
|
||||
);
|
||||
state.inviteStatusType = 'success';
|
||||
loadRealData().catch(function () {});
|
||||
renderInvite();
|
||||
})
|
||||
.catch(function (error) {
|
||||
state.inviteStatus = error.message || 'Invite failed.';
|
||||
state.inviteStatusType = 'warning';
|
||||
renderInvite();
|
||||
})
|
||||
.finally(function () {
|
||||
delete state.inviteSubmitting[targetUserID];
|
||||
renderInvite();
|
||||
});
|
||||
}
|
||||
|
||||
function openModal(id) {
|
||||
var modal = $(id);
|
||||
if (!modal) return;
|
||||
modal.hidden = false;
|
||||
modal.setAttribute('aria-hidden', 'false');
|
||||
document.body.classList.add('modal-open');
|
||||
}
|
||||
|
||||
function closeModal(id) {
|
||||
var modal = $(id);
|
||||
if (!modal) return;
|
||||
modal.hidden = true;
|
||||
modal.setAttribute('aria-hidden', 'true');
|
||||
var hasOpen = Array.prototype.some.call(
|
||||
document.querySelectorAll('.sheet-modal, .invite-modal'),
|
||||
function (node) {
|
||||
return !node.hidden;
|
||||
}
|
||||
);
|
||||
document.body.classList.toggle('modal-open', hasOpen);
|
||||
}
|
||||
|
||||
function navigateToWithdrawExchange() {
|
||||
var params = new URLSearchParams(window.location.search);
|
||||
params.set('identity', 'BD_LEADER');
|
||||
params.set('salaryType', 'ADMIN_SALARY_USD');
|
||||
if (!params.has('mode')) params.set('mode', 'withdraw');
|
||||
window.location.href =
|
||||
'../withdraw-exchange/index.html?' + params.toString();
|
||||
}
|
||||
|
||||
function bindEvents() {
|
||||
$('backButton').addEventListener('click', function () {
|
||||
if (window.HyAppBridge) window.HyAppBridge.back();
|
||||
});
|
||||
$('withdrawExchangeButton').addEventListener(
|
||||
'click',
|
||||
navigateToWithdrawExchange
|
||||
);
|
||||
document.querySelectorAll('.menu-row').forEach(function (button) {
|
||||
button.addEventListener('click', function () {
|
||||
var action = button.getAttribute('data-action');
|
||||
if (action === 'history') {
|
||||
renderHistory();
|
||||
openModal('historyModal');
|
||||
return;
|
||||
}
|
||||
if (action === 'invite-bd') {
|
||||
state.inviteQuery = '';
|
||||
state.inviteStatus = '';
|
||||
state.inviteStatusType = '';
|
||||
state.inviteSearchResults = [];
|
||||
$('inviteSearchInput').value = '';
|
||||
renderInvite();
|
||||
openModal('inviteModal');
|
||||
}
|
||||
});
|
||||
});
|
||||
document
|
||||
.querySelectorAll('[data-close-modal]')
|
||||
.forEach(function (node) {
|
||||
node.addEventListener('click', function () {
|
||||
closeModal(node.getAttribute('data-close-modal'));
|
||||
});
|
||||
});
|
||||
$('inviteSearchForm').addEventListener('submit', function (event) {
|
||||
event.preventDefault();
|
||||
state.inviteQuery = $('inviteSearchInput').value.trim();
|
||||
state.inviteStatus = state.inviteQuery
|
||||
? ''
|
||||
: t('bd_leader_center.enter_user_id', 'Enter User ID');
|
||||
state.inviteStatusType = state.inviteQuery ? '' : 'warning';
|
||||
state.inviteSearchResults = [];
|
||||
if (state.inviteQuery) {
|
||||
searchInviteProfile(state.inviteQuery);
|
||||
} else {
|
||||
renderInvite();
|
||||
}
|
||||
});
|
||||
document.addEventListener('keydown', function (event) {
|
||||
if (event.key !== 'Escape') return;
|
||||
closeModal('historyModal');
|
||||
closeModal('detailsModal');
|
||||
closeModal('inviteModal');
|
||||
});
|
||||
}
|
||||
|
||||
function render() {
|
||||
renderProfile();
|
||||
renderBalance();
|
||||
renderTeamList();
|
||||
}
|
||||
|
||||
function init() {
|
||||
if (state.isMock) {
|
||||
applyMockData();
|
||||
} else {
|
||||
applyEmptyData();
|
||||
}
|
||||
render();
|
||||
bindEvents();
|
||||
if (!state.isMock) {
|
||||
loadRealData().catch(function () {});
|
||||
}
|
||||
if (window.HyAppBridge) {
|
||||
window.HyAppBridge.ready({
|
||||
page: 'bd-leader-center',
|
||||
mock: state.isMock,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', init);
|
||||
} else {
|
||||
init();
|
||||
}
|
||||
|
||||
window.addEventListener('hyapp:i18n-ready', function () {
|
||||
render();
|
||||
if (!$('historyModal').hidden) renderHistory();
|
||||
if (!$('inviteModal').hidden) renderInvite();
|
||||
if (!$('detailsModal').hidden) renderDetails();
|
||||
});
|
||||
})();
|
||||
@ -1,521 +0,0 @@
|
||||
.role-pill {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
min-height: 24px;
|
||||
padding: 0 10px;
|
||||
border-radius: 999px;
|
||||
background: var(--hy-theme-primary-soft, #f4ebff);
|
||||
color: var(--primary-deep);
|
||||
font-size: 12px;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.bd-leader-center .name {
|
||||
margin-top: 7px;
|
||||
}
|
||||
|
||||
.salary-card,
|
||||
.team-card {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.salary-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.salary-head h2 {
|
||||
margin: 0;
|
||||
color: var(--text);
|
||||
font-size: 18px;
|
||||
font-weight: 950;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.salary-value {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
margin-top: 18px;
|
||||
color: #23272d;
|
||||
font-size: 34px;
|
||||
font-weight: 950;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.coin-icon {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
flex: 0 0 28px;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(145deg, #ffe179 0%, #ffb62d 52%, #f49b20 100%);
|
||||
color: #fff;
|
||||
font-size: 19px;
|
||||
font-weight: 950;
|
||||
box-shadow:
|
||||
inset 0 1px 2px rgba(255, 255, 255, 0.7),
|
||||
0 1px 2px rgba(195, 117, 12, 0.24);
|
||||
}
|
||||
|
||||
.salary-value strong {
|
||||
min-width: 0;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.menu-card {
|
||||
display: grid;
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
.menu-row {
|
||||
display: grid;
|
||||
grid-template-columns: 38px minmax(0, 1fr) 24px;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
min-height: 64px;
|
||||
border-bottom: 1px solid var(--line);
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.menu-row:last-child {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.menu-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
border-radius: 50%;
|
||||
background: var(--primary-soft);
|
||||
color: var(--primary-deep);
|
||||
}
|
||||
|
||||
.menu-icon svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.menu-icon path {
|
||||
fill: none;
|
||||
stroke: currentColor;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
stroke-width: 2;
|
||||
}
|
||||
|
||||
.menu-label {
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
color: #464951;
|
||||
font-size: 16px;
|
||||
font-weight: 850;
|
||||
line-height: 1.2;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.team-card {
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.team-head h2 {
|
||||
margin: 0;
|
||||
color: var(--text);
|
||||
font-size: 18px;
|
||||
font-weight: 950;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.team-summary,
|
||||
.history-summary {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.team-summary.is-two {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.history-summary.compact {
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.team-summary > div,
|
||||
.history-summary > div {
|
||||
min-width: 0;
|
||||
padding: 10px;
|
||||
border-radius: 8px;
|
||||
background: var(--hy-theme-primary-soft, #f4ebff);
|
||||
}
|
||||
|
||||
.team-summary span,
|
||||
.history-summary span {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
color: var(--muted);
|
||||
font-size: 11px;
|
||||
font-weight: 850;
|
||||
line-height: 1.2;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.team-summary strong,
|
||||
.history-summary strong {
|
||||
display: block;
|
||||
margin-top: 5px;
|
||||
overflow-wrap: anywhere;
|
||||
color: var(--text);
|
||||
font-size: 15px;
|
||||
font-weight: 950;
|
||||
line-height: 1.15;
|
||||
}
|
||||
|
||||
.team-list,
|
||||
.history-list,
|
||||
.invite-list {
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.team-list {
|
||||
max-height: 360px;
|
||||
overflow-y: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
.member-row,
|
||||
.invite-card {
|
||||
display: grid;
|
||||
grid-template-columns: 44px minmax(0, 1fr) auto;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
padding: 12px;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 8px;
|
||||
background: #fbfcfc;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.member-avatar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
overflow: hidden;
|
||||
border-radius: 50%;
|
||||
background: var(--primary);
|
||||
}
|
||||
|
||||
.member-avatar img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.member-fallback {
|
||||
color: var(--primary-deep);
|
||||
font-size: 18px;
|
||||
font-weight: 950;
|
||||
}
|
||||
|
||||
.member-main,
|
||||
.invite-main {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.member-name,
|
||||
.invite-name {
|
||||
overflow: hidden;
|
||||
color: var(--text);
|
||||
font-size: 15px;
|
||||
font-weight: 900;
|
||||
line-height: 1.2;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.member-meta,
|
||||
.invite-meta {
|
||||
margin-top: 4px;
|
||||
overflow: hidden;
|
||||
color: var(--muted);
|
||||
font-size: 12px;
|
||||
font-weight: 800;
|
||||
line-height: 1.2;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.member-side {
|
||||
display: grid;
|
||||
gap: 3px;
|
||||
color: #555b64;
|
||||
font-size: 12px;
|
||||
font-weight: 850;
|
||||
line-height: 1.2;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.member-side strong {
|
||||
color: var(--primary-deep);
|
||||
font-size: 14px;
|
||||
font-weight: 950;
|
||||
}
|
||||
|
||||
.history-sheet {
|
||||
max-height: 82vh;
|
||||
max-height: 82dvh;
|
||||
}
|
||||
|
||||
.history-summary,
|
||||
.history-list {
|
||||
padding: 0 18px 14px;
|
||||
}
|
||||
|
||||
.history-row {
|
||||
display: grid;
|
||||
gap: 9px;
|
||||
padding: 12px;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 8px;
|
||||
background: #fbfcfc;
|
||||
}
|
||||
|
||||
.history-title {
|
||||
color: var(--text);
|
||||
font-size: 16px;
|
||||
font-weight: 950;
|
||||
}
|
||||
|
||||
.status-tag {
|
||||
justify-self: flex-start;
|
||||
padding: 5px 9px;
|
||||
border-radius: 999px;
|
||||
background: var(--primary-soft);
|
||||
color: var(--primary-deep);
|
||||
font-size: 12px;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.history-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.readonly-line {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
min-height: 48px;
|
||||
padding: 0 12px;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 8px;
|
||||
background: #fbfcfc;
|
||||
color: var(--muted);
|
||||
font-size: 14px;
|
||||
font-weight: 850;
|
||||
}
|
||||
|
||||
.readonly-line strong {
|
||||
color: var(--text);
|
||||
font-weight: 950;
|
||||
}
|
||||
|
||||
.invite-modal {
|
||||
position: fixed;
|
||||
z-index: 24;
|
||||
inset: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 18px;
|
||||
}
|
||||
|
||||
.invite-dialog {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: min(394px, 100%);
|
||||
max-height: 80vh;
|
||||
max-height: 80dvh;
|
||||
overflow: hidden;
|
||||
border-radius: 14px;
|
||||
background: #fff;
|
||||
box-shadow: 0 18px 44px rgba(23, 31, 42, 0.2);
|
||||
}
|
||||
|
||||
.invite-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
padding: 18px 18px 12px;
|
||||
}
|
||||
|
||||
.invite-head h2 {
|
||||
margin: 0;
|
||||
color: var(--text);
|
||||
font-size: 20px;
|
||||
font-weight: 950;
|
||||
}
|
||||
|
||||
.invite-close {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
flex: 0 0 34px;
|
||||
border-radius: 50%;
|
||||
background: #f1f4f4;
|
||||
color: #5d6570;
|
||||
font-size: 25px;
|
||||
font-weight: 400;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.invite-body {
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
min-height: 0;
|
||||
overflow-y: auto;
|
||||
padding: 0 18px 18px;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
.invite-field {
|
||||
display: grid;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.invite-field > span {
|
||||
color: var(--text);
|
||||
font-size: 14px;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.invite-search-control {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) 96px;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.invite-search-control input {
|
||||
min-width: 0;
|
||||
height: 44px;
|
||||
padding: 0 12px;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 8px;
|
||||
background: #fbfcfc;
|
||||
color: var(--text);
|
||||
font-size: 14px;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.invite-search-control button,
|
||||
.invite-action {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 44px;
|
||||
border-radius: 8px;
|
||||
background: var(--button);
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
font-weight: 950;
|
||||
}
|
||||
|
||||
.invite-action {
|
||||
min-width: 82px;
|
||||
padding: 0 12px;
|
||||
}
|
||||
|
||||
.invite-action:disabled {
|
||||
background: var(--hy-theme-button-disabled, #eadffc);
|
||||
color: var(--hy-theme-button-disabled-text, #9a8faa);
|
||||
}
|
||||
|
||||
.invite-status,
|
||||
.invite-empty {
|
||||
min-height: 42px;
|
||||
padding: 11px 12px;
|
||||
border-radius: 8px;
|
||||
background: var(--primary-soft);
|
||||
color: var(--primary-deep);
|
||||
font-size: 13px;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.invite-status.warning {
|
||||
background: #fff5e8;
|
||||
color: #ba791c;
|
||||
}
|
||||
|
||||
.invite-status.success {
|
||||
background: #ecfbef;
|
||||
color: #219251;
|
||||
}
|
||||
|
||||
.invite-empty {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
body.modal-open {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
[dir='rtl'] .menu-row,
|
||||
[dir='rtl'] .member-row,
|
||||
[dir='rtl'] .invite-card {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
[dir='rtl'] .member-side {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
[dir='rtl'] .chevron {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
@media (max-width: 360px) {
|
||||
.salary-card,
|
||||
.team-card {
|
||||
padding-right: 14px;
|
||||
padding-left: 14px;
|
||||
}
|
||||
|
||||
.team-summary,
|
||||
.history-summary,
|
||||
.history-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.member-row,
|
||||
.invite-card {
|
||||
grid-template-columns: 40px minmax(0, 1fr);
|
||||
}
|
||||
|
||||
.member-side,
|
||||
.invite-action {
|
||||
grid-column: 2;
|
||||
justify-self: start;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
@ -795,9 +795,105 @@
|
||||
};
|
||||
}
|
||||
|
||||
function fallbackLevelProgress() {
|
||||
return {
|
||||
loading: false,
|
||||
current: 0,
|
||||
nextLevelNo: 0,
|
||||
currentRequired: 0,
|
||||
currentValue: 0,
|
||||
nextValue: 1,
|
||||
needed: 0,
|
||||
};
|
||||
}
|
||||
|
||||
function levelProgressFromPolicy(policy, progress) {
|
||||
var levels =
|
||||
policy && Array.isArray(policy.levels) ? policy.levels : [];
|
||||
var currentValue = toNumber(
|
||||
firstValue(progress, [
|
||||
'total_diamonds',
|
||||
'totalDiamonds',
|
||||
'gift_diamond_total',
|
||||
'giftDiamondTotal',
|
||||
])
|
||||
);
|
||||
if (!levels.length) {
|
||||
return Object.assign(fallbackLevelProgress(), {
|
||||
currentValue: currentValue,
|
||||
});
|
||||
}
|
||||
|
||||
var current = null;
|
||||
var next = null;
|
||||
levels.forEach(function (level) {
|
||||
if (!level) return;
|
||||
var required = toNumber(
|
||||
firstValue(level, ['required_diamonds', 'requiredDiamonds'])
|
||||
);
|
||||
if (required <= currentValue) {
|
||||
if (
|
||||
!current ||
|
||||
required >
|
||||
toNumber(
|
||||
firstValue(current, [
|
||||
'required_diamonds',
|
||||
'requiredDiamonds',
|
||||
])
|
||||
)
|
||||
) {
|
||||
current = level;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (
|
||||
!next ||
|
||||
required <
|
||||
toNumber(
|
||||
firstValue(next, [
|
||||
'required_diamonds',
|
||||
'requiredDiamonds',
|
||||
])
|
||||
)
|
||||
) {
|
||||
next = level;
|
||||
}
|
||||
});
|
||||
|
||||
var currentRequired = current
|
||||
? toNumber(
|
||||
firstValue(current, ['required_diamonds', 'requiredDiamonds'])
|
||||
)
|
||||
: 0;
|
||||
var nextRequired = next
|
||||
? toNumber(
|
||||
firstValue(next, ['required_diamonds', 'requiredDiamonds'])
|
||||
)
|
||||
: currentRequired;
|
||||
var currentLevel = current
|
||||
? toNumber(firstValue(current, ['level_no', 'levelNo', 'level']))
|
||||
: 0;
|
||||
var nextLevel = next
|
||||
? toNumber(firstValue(next, ['level_no', 'levelNo', 'level']))
|
||||
: currentLevel;
|
||||
|
||||
return {
|
||||
current_level: currentLevel,
|
||||
current_required_diamonds: currentRequired,
|
||||
current_value: currentValue,
|
||||
next_level: nextLevel,
|
||||
next_required_diamonds: nextRequired,
|
||||
needed_for_next_level: next
|
||||
? Math.max(0, nextRequired - currentValue)
|
||||
: 0,
|
||||
};
|
||||
}
|
||||
|
||||
function applyPolicy(payload) {
|
||||
var data = unwrapData(payload);
|
||||
if (!data || !data.found || !data.policy) {
|
||||
// 线上策略未配置或旧网关返回空数据时,等级区域不能停在骨架态;展示空进度比持续 loading 更能说明真实状态。
|
||||
state.level = fallbackLevelProgress();
|
||||
state.policy = {
|
||||
loading: false,
|
||||
loaded: true,
|
||||
@ -806,8 +902,17 @@
|
||||
};
|
||||
return;
|
||||
}
|
||||
// 新网关直接返回 level_progress;旧网关只有 policy/progress 时,H5 按同一套档位和当前钻石累计计算目标进度。
|
||||
applyLevelProgress(
|
||||
firstValue(data, ['level_progress', 'levelProgress'])
|
||||
firstValue(data, ['level_progress', 'levelProgress']) ||
|
||||
levelProgressFromPolicy(
|
||||
data.policy,
|
||||
firstValue(data, [
|
||||
'progress',
|
||||
'salary_progress',
|
||||
'salaryProgress',
|
||||
])
|
||||
)
|
||||
);
|
||||
state.policy = {
|
||||
loading: false,
|
||||
@ -841,8 +946,10 @@
|
||||
if (payload) {
|
||||
applyPolicy(payload);
|
||||
} else {
|
||||
// 失败分支同样要结束主卡片 loading,否则页面会像线上截图一样一直显示紫色骨架条。
|
||||
state.level = fallbackLevelProgress();
|
||||
state.policy = {
|
||||
loading: true,
|
||||
loading: false,
|
||||
loaded: false,
|
||||
found: false,
|
||||
policy: null,
|
||||
@ -993,6 +1100,8 @@
|
||||
applyWallet(results[2]);
|
||||
if (results[3]) {
|
||||
applyPolicy(results[3]);
|
||||
} else {
|
||||
applyPolicy(null);
|
||||
}
|
||||
render();
|
||||
|
||||
@ -1013,7 +1122,10 @@
|
||||
|
||||
function openWithdrawExchange() {
|
||||
var params = new URLSearchParams(window.location.search);
|
||||
params.set('mode', params.get('mode') || 'transfer');
|
||||
params.set('identity', 'HOST');
|
||||
params.set('salaryType', HOST_SALARY_USD);
|
||||
params.set('asset_type', HOST_SALARY_USD);
|
||||
if (!params.has('mode')) params.set('mode', 'withdraw');
|
||||
window.location.href =
|
||||
'../withdraw-exchange/index.html?' + params.toString();
|
||||
}
|
||||
|
||||
@ -868,8 +868,9 @@
|
||||
|
||||
function navigateToWithdrawExchange() {
|
||||
var params = new URLSearchParams(window.location.search);
|
||||
params.set('identity', 'SUPER_ADMIN');
|
||||
params.set('salaryType', 'SUPER_ADMIN_SALARY');
|
||||
params.set('identity', 'BD_LEADER');
|
||||
params.set('salaryType', 'ADMIN_SALARY_USD');
|
||||
params.set('asset_type', 'ADMIN_SALARY_USD');
|
||||
if (!params.has('mode')) params.set('mode', 'withdraw');
|
||||
window.location.href =
|
||||
'../withdraw-exchange/index.html?' + params.toString();
|
||||
|
||||
@ -115,6 +115,8 @@
|
||||
}
|
||||
|
||||
function api() {
|
||||
if (window.HyAppAPI && window.HyAppAPI.salaryWallet)
|
||||
return window.HyAppAPI.salaryWallet;
|
||||
return window.HyApp && window.HyApp.api
|
||||
? window.HyApp.api.salaryWallet
|
||||
: null;
|
||||
@ -682,7 +684,8 @@
|
||||
var query = nextParams.toString();
|
||||
var centerPath = '../host-center/index.html';
|
||||
if (identity === 'BD') centerPath = '../bd-center/index.html';
|
||||
if (identity === 'BD_LEADER') centerPath = '../bd-leader/index.html';
|
||||
if (identity === 'BD_LEADER')
|
||||
centerPath = '../superadmin-center/index.html';
|
||||
if (identity === 'AGENCY') centerPath = '../agency-center/index.html';
|
||||
window.location.href = centerPath + (query ? '?' + query : '');
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user