(function () { 'use strict'; var state = { range: null, data: null, tab: 'agency', loading: false, mutating: false, removingHost: null, }; function $(id) { return document.getElementById(id); } function t(key, fallback) { return window.HyAppI18n && window.HyAppI18n.t ? window.HyAppI18n.t(key, fallback) : fallback || key; } function toast(message) { if (window.HyAppToast) window.HyAppToast.show(message); } function count(value) { if (value === null || value === undefined || !Number.isFinite(value)) { return '—'; } return Number(value).toLocaleString(undefined, { maximumFractionDigits: 0, }); } function duration(value) { if (!Number.isFinite(value)) return '—'; var minutes = Math.max(0, Math.floor(Number(value) / 60000)); var hours = Math.floor(minutes / 60); var rest = minutes % 60; if (!hours) return rest + t('fami_unit.minute_short', 'm'); return ( hours + t('fami_unit.hour_short', 'h') + (rest ? ' ' + rest + t('fami_unit.minute_short', 'm') : '') ); } function dateTime(value) { if (!Number(value)) return '—'; return new Date(Number(value)).toLocaleString(undefined, { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', }); } function renderIdentity() { if (!state.data) return; var agency = state.data.agency || {}; $('agencyName').textContent = agency.name || '—'; $('agencyID').textContent = t('fami_agency.id_prefix', 'Agency ID:') + ' ' + (agency.shortId || agency.id || '—'); $('createdAt').textContent = t('fami_agency.created_prefix', 'Created:') + ' ' + dateTime(agency.createdAtMS); $('agencyInitial').textContent = String(agency.name || 'A') .trim() .charAt(0) .toUpperCase(); $('agencyAvatar').hidden = !agency.avatar; $('agencyInitial').hidden = !!agency.avatar; if (agency.avatar) $('agencyAvatar').src = agency.avatar; $('contactValue').textContent = state.data.contact || '—'; $('diamondBalance').textContent = count(state.data.pointBalance); } function renderSummary() { var summary = state.data && state.data.stats ? state.data.stats.summary || {} : {}; $('totalEarnings').textContent = count(summary.total_earnings); $('giftIncome').textContent = count(summary.gift_income); $('shareIncome').textContent = count(summary.share_income); $('totalHosts').textContent = count(summary.total_hosts); $('giftedHosts').textContent = count(summary.gifted_host_count); var statsError = state.data && state.data.errors.stats; $('statsStatus').hidden = !statsError; if (statsError) { $('statsStatus').textContent = t( 'fami_common.stats_unavailable', 'Statistics are temporarily unavailable.' ); } } function hostAvatar(host) { var shell = document.createElement('span'); shell.className = 'host-avatar'; if (host.avatar) { var image = document.createElement('img'); image.src = host.avatar; image.alt = ''; shell.appendChild(image); } else { shell.textContent = String(host.name || 'H') .charAt(0) .toUpperCase(); } return shell; } function textCell(row, value) { var cell = document.createElement('td'); cell.textContent = value; row.appendChild(cell); } function renderHosts() { var hosts = state.data && state.data.stats ? state.data.stats.hosts || [] : []; var body = $('hostTableBody'); body.textContent = ''; hosts.forEach(function (host) { var row = document.createElement('tr'); var identityCell = document.createElement('td'); var identity = document.createElement('div'); identity.className = 'host-identity'; identity.appendChild(hostAvatar(host)); var copy = document.createElement('span'); copy.className = 'host-copy'; var name = document.createElement('strong'); name.textContent = host.name || '—'; var id = document.createElement('span'); id.textContent = t('fami_common.uid_prefix', 'UID:') + ' ' + (host.displayUserId || host.userId || '—'); copy.appendChild(name); copy.appendChild(id); identity.appendChild(copy); identityCell.appendChild(identity); row.appendChild(identityCell); textCell(row, count(host.diamondEarnings)); textCell(row, count(host.diamondExchanged)); textCell(row, count(host.giftSenders)); textCell(row, duration(host.onlineDurationMS)); textCell(row, duration(host.validMicDurationMS)); textCell(row, count(host.validMicDays)); textCell(row, dateTime(host.joinedAtMS)); var actionCell = document.createElement('td'); var remove = document.createElement('button'); remove.type = 'button'; remove.className = 'remove-button'; if (host.removable) { remove.setAttribute('data-remove-host', host.userId); remove.textContent = t('fami_agency.remove', 'Remove'); } else { remove.disabled = true; remove.textContent = t('fami_agency.owner', 'Owner'); } actionCell.appendChild(remove); row.appendChild(actionCell); body.appendChild(row); }); $('hostEmpty').hidden = hosts.length > 0; $('hostCountLabel').textContent = t( 'fami_agency.host_count', '{count} hosts' ).replace('{count}', count(hosts.length)); } function renderRange() { document.querySelectorAll('[data-range]').forEach(function (button) { button.setAttribute( 'aria-pressed', button.getAttribute('data-range') === state.range.preset ? 'true' : 'false' ); button.disabled = state.loading; }); $('rangeCaption').textContent = state.range.startDate === state.range.endDate ? state.range.startDate : state.range.startDate + ' – ' + state.range.endDate; } function renderTabs() { document.querySelectorAll('[data-tab]').forEach(function (button) { button.setAttribute( 'aria-selected', button.getAttribute('data-tab') === state.tab ? 'true' : 'false' ); }); $('agencyPanel').hidden = state.tab !== 'agency'; $('hostsPanel').hidden = state.tab !== 'hosts'; $('dataTitle').textContent = state.tab === 'agency' ? t('fami_agency.tab_agency', 'Agency data') : t('fami_agency.tab_hosts', 'Host data'); } function renderAll() { renderIdentity(); renderSummary(); renderHosts(); renderRange(); renderTabs(); } function setLoading(value) { state.loading = value; document.body.classList.toggle('is-loading', value); renderRange(); } function setMutating(value) { state.mutating = value; document.body.classList.toggle('is-mutating', value); } function load() { setLoading(true); return window.HyGuild.agencyCenter .load(state.range) .then(function (data) { state.data = data; renderAll(); }) .catch(function () { toast( t( 'fami_agency.load_failed', 'Unable to load Agency Center.' ) ); $('statsStatus').hidden = false; $('statsStatus').textContent = t( 'fami_agency.load_failed', 'Unable to load Agency Center.' ); }) .finally(function () { setLoading(false); }); } function selectRange(preset) { if (preset === 'custom') { $('rangeStart').value = state.range.startDate; $('rangeEnd').value = state.range.endDate; $('rangeDialog').showModal(); return; } state.range = window.HyGuild.dateRange.create(preset); renderRange(); load(); } function applyCustomRange(event) { event.preventDefault(); try { state.range = window.HyGuild.dateRange.create('custom', { start: $('rangeStart').value, end: $('rangeEnd').value, }); } catch (_) { toast(t('fami_range.invalid', 'Choose a valid date range.')); return; } $('rangeDialog').close(); load(); } function saveContact(event) { event.preventDefault(); if (state.mutating) return; var value = String($('contactInput').value || '').trim(); if (!value) { toast(t('fami_agency.contact_required', 'Enter a contact number.')); return; } setMutating(true); window.HyGuild.agencyCenter .saveContact(value) .then(function () { state.data.contact = value; $('contactDialog').close(); renderIdentity(); toast(t('fami_agency.contact_saved', 'Contact saved.')); }) .catch(function () { toast( t( 'fami_agency.contact_save_failed', 'Unable to save contact.' ) ); }) .finally(function () { setMutating(false); }); } function inviteHost(event) { event.preventDefault(); if (state.mutating) return; var displayID = String($('inviteHostID').value || '').trim(); if (!displayID) return; setMutating(true); window.HyGuild.agencyCenter .inviteHost(displayID) .then(function () { $('inviteDialog').close(); toast( t( 'fami_agency.invite_sent', 'Invitation sent. The host must accept it.' ) ); }) .catch(function () { toast(t('fami_agency.invite_failed', 'Unable to invite host.')); }) .finally(function () { setMutating(false); }); } function openRemove(hostUserID) { var hosts = state.data.stats.hosts || []; state.removingHost = hosts.find(function (host) { return host.userId === hostUserID; }); if (!state.removingHost) return; $('removeMessage').textContent = t( 'fami_agency.remove_confirm', 'Remove {name} from this agency? Historical earnings will remain unchanged.' ).replace('{name}', state.removingHost.name || hostUserID); $('removeDialog').showModal(); } function removeHost(event) { event.preventDefault(); if (state.mutating || !state.removingHost) return; var target = state.removingHost; setMutating(true); window.HyGuild.agencyCenter .removeHost(target.userId) .then(function () { // 成员关系由后端原子结束;成功后重拉统计,不能只在本地删行伪造 total_hosts。 $('removeDialog').close(); state.removingHost = null; toast(t('fami_agency.host_removed', 'Host removed.')); return load(); }) .catch(function () { toast(t('fami_agency.remove_failed', 'Unable to remove host.')); }) .finally(function () { setMutating(false); }); } function bind() { $('backButton').addEventListener('click', function () { if (window.history.length > 1) window.history.back(); else if (window.HyAppBridge) window.HyAppBridge.back(); }); $('withdrawButton').addEventListener('click', function () { window.location.href = window.HyGuild.product.buildURL('../wallet/'); }); $('editContactButton').addEventListener('click', function () { $('contactInput').value = (state.data && state.data.contact) || ''; $('contactDialog').showModal(); }); $('cancelContactButton').addEventListener('click', function () { $('contactDialog').close(); }); $('contactForm').addEventListener('submit', saveContact); document .querySelector('.data-tabs') .addEventListener('click', function (event) { var button = event.target.closest('[data-tab]'); if (!button) return; state.tab = button.getAttribute('data-tab'); renderTabs(); }); $('rangeFilters').addEventListener('click', function (event) { var button = event.target.closest('[data-range]'); if (button && !state.loading) selectRange(button.getAttribute('data-range')); }); $('cancelRangeButton').addEventListener('click', function () { $('rangeDialog').close(); }); $('rangeForm').addEventListener('submit', applyCustomRange); $('addHostButton').addEventListener('click', function () { $('inviteHostID').value = ''; $('inviteDialog').showModal(); }); $('cancelInviteButton').addEventListener('click', function () { $('inviteDialog').close(); }); $('inviteForm').addEventListener('submit', inviteHost); $('hostTableBody').addEventListener('click', function (event) { var button = event.target.closest('[data-remove-host]'); if (button) openRemove(button.getAttribute('data-remove-host')); }); $('cancelRemoveButton').addEventListener('click', function () { $('removeDialog').close(); }); $('removeForm').addEventListener('submit', removeHost); window.addEventListener('hyapp:i18n-ready', renderAll); } function init() { state.range = window.HyGuild.dateRange.create('today'); bind(); renderRange(); load(); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();