280 lines
9.3 KiB
JavaScript
280 lines
9.3 KiB
JavaScript
(function () {
|
||
'use strict';
|
||
|
||
var state = {
|
||
range: null,
|
||
data: null,
|
||
loading: false,
|
||
savingContact: false,
|
||
};
|
||
|
||
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 (value === null || value === undefined || !Number.isFinite(value)) {
|
||
return '—';
|
||
}
|
||
var minutes = Math.max(0, Math.floor(Number(value) / 60000));
|
||
var days = Math.floor(minutes / 1440);
|
||
var hours = Math.floor((minutes % 1440) / 60);
|
||
var rest = minutes % 60;
|
||
var parts = [];
|
||
if (days) parts.push(days + t('fami_unit.day_short', 'd'));
|
||
if (hours) parts.push(hours + t('fami_unit.hour_short', 'h'));
|
||
if (!days && rest) parts.push(rest + t('fami_unit.minute_short', 'm'));
|
||
return parts.length
|
||
? parts.join(' ')
|
||
: '0' + 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 renderProfile() {
|
||
if (!state.data) return;
|
||
var profile = state.data.profile || {};
|
||
var agency = state.data.agency;
|
||
$('profileName').textContent = profile.name || '—';
|
||
$('profileUID').textContent =
|
||
t('fami_host.uid_prefix', 'UID:') +
|
||
' ' +
|
||
(profile.displayUserId || profile.userId || '—');
|
||
$('profileInitial').textContent = String(profile.name || 'H')
|
||
.trim()
|
||
.charAt(0)
|
||
.toUpperCase();
|
||
$('profileAvatar').hidden = !profile.avatar;
|
||
$('profileInitial').hidden = !!profile.avatar;
|
||
if (profile.avatar) $('profileAvatar').src = profile.avatar;
|
||
|
||
$('agencyPill').hidden = !agency;
|
||
$('joinTime').hidden = !agency || !agency.joinedAtMS;
|
||
if (agency) {
|
||
$('agencyPill').textContent =
|
||
t('fami_host.agency_id_prefix', 'Agency ID:') +
|
||
' ' +
|
||
(agency.shortId || agency.id || '—');
|
||
if (agency.joinedAtMS) {
|
||
$('joinTime').textContent =
|
||
t('fami_host.joined_at_prefix', 'Joined:') +
|
||
' ' +
|
||
dateTime(agency.joinedAtMS);
|
||
}
|
||
}
|
||
$('contactValue').textContent = profile.contact || '—';
|
||
$('diamondBalance').textContent = count(state.data.pointBalance);
|
||
}
|
||
|
||
function renderMetrics() {
|
||
var metrics =
|
||
state.data && state.data.stats ? state.data.stats.metrics : {};
|
||
window.HyGuild.hostCenter.metrics.forEach(function (definition) {
|
||
var node = document.querySelector(
|
||
'[data-metric="' + definition.key + '"] strong'
|
||
);
|
||
if (!node) return;
|
||
node.textContent =
|
||
definition.format === 'duration'
|
||
? duration(metrics[definition.key])
|
||
: count(metrics[definition.key]);
|
||
});
|
||
var statsError =
|
||
state.data && state.data.errors ? state.data.errors.stats : null;
|
||
$('statsStatus').hidden = !statsError;
|
||
if (statsError) {
|
||
$('statsStatus').textContent = t(
|
||
'fami_host.stats_unavailable',
|
||
'Statistics are temporarily unavailable.'
|
||
);
|
||
}
|
||
}
|
||
|
||
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 setLoading(loading) {
|
||
state.loading = loading;
|
||
document.body.classList.toggle('is-loading', loading);
|
||
renderRange();
|
||
}
|
||
|
||
function load() {
|
||
setLoading(true);
|
||
return window.HyGuild.hostCenter
|
||
.load(state.range)
|
||
.then(function (data) {
|
||
state.data = data;
|
||
renderProfile();
|
||
renderMetrics();
|
||
})
|
||
.catch(function () {
|
||
toast(
|
||
t('fami_host.load_failed', 'Unable to load Host Center.')
|
||
);
|
||
$('statsStatus').hidden = false;
|
||
$('statsStatus').textContent = t(
|
||
'fami_host.load_failed',
|
||
'Unable to load Host 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 saveContact(event) {
|
||
event.preventDefault();
|
||
if (state.savingContact) return;
|
||
var value = String($('contactInput').value || '').trim();
|
||
if (!value) {
|
||
toast(t('fami_host.contact_required', 'Enter a contact number.'));
|
||
return;
|
||
}
|
||
state.savingContact = true;
|
||
window.HyGuild.hostCenter
|
||
.saveContact(value)
|
||
.then(function () {
|
||
state.data.profile.contact = value;
|
||
$('contactValue').textContent = value;
|
||
$('contactDialog').close();
|
||
toast(t('fami_host.contact_saved', 'Contact saved.'));
|
||
})
|
||
.catch(function () {
|
||
toast(
|
||
t(
|
||
'fami_host.contact_save_failed',
|
||
'Unable to save contact.'
|
||
)
|
||
);
|
||
})
|
||
.finally(function () {
|
||
state.savingContact = false;
|
||
});
|
||
}
|
||
|
||
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();
|
||
renderRange();
|
||
load();
|
||
}
|
||
|
||
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 () {
|
||
// 钱包是独立页面包;统一 URL builder 继承 token/env/lang 并强制 app_code=fami。
|
||
window.location.href =
|
||
window.HyGuild.product.buildURL('../wallet/');
|
||
});
|
||
$('editContactButton').addEventListener('click', function () {
|
||
$('contactInput').value =
|
||
(state.data && state.data.profile.contact) || '';
|
||
$('contactDialog').showModal();
|
||
});
|
||
$('cancelContactButton').addEventListener('click', function () {
|
||
$('contactDialog').close();
|
||
});
|
||
$('contactForm').addEventListener('submit', saveContact);
|
||
$('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);
|
||
window.addEventListener('hyapp:i18n-ready', function () {
|
||
renderProfile();
|
||
renderMetrics();
|
||
});
|
||
}
|
||
|
||
function init() {
|
||
state.range = window.HyGuild.dateRange.create('today');
|
||
bind();
|
||
renderRange();
|
||
load().finally(function () {
|
||
if (window.HyAppBridge) {
|
||
window.HyAppBridge.ready({
|
||
page: 'fami-host-center',
|
||
app_code: 'fami',
|
||
});
|
||
}
|
||
});
|
||
}
|
||
|
||
if (document.readyState === 'loading') {
|
||
document.addEventListener('DOMContentLoaded', init);
|
||
} else {
|
||
init();
|
||
}
|
||
})();
|