1029 lines
33 KiB
JavaScript
1029 lines
33 KiB
JavaScript
(function () {
|
|
var AGENCY_SALARY_USD = 'AGENCY_SALARY_USD';
|
|
var HOST_SALARY_USD = 'HOST_SALARY_USD';
|
|
|
|
var state = emptyState();
|
|
|
|
function emptyState() {
|
|
return {
|
|
hosts: [],
|
|
messages: [],
|
|
hostSearch: '',
|
|
pendingRemoveHost: null,
|
|
profile: {
|
|
loading: true,
|
|
name: '',
|
|
shortId: '',
|
|
avatar: '',
|
|
bd: null,
|
|
},
|
|
salary: {
|
|
loading: true,
|
|
available: 0,
|
|
},
|
|
policy: {
|
|
loading: true,
|
|
loaded: false,
|
|
found: false,
|
|
policy: null,
|
|
},
|
|
loading: true,
|
|
};
|
|
}
|
|
|
|
function $(id) {
|
|
return document.getElementById(id);
|
|
}
|
|
|
|
function api() {
|
|
return window.HyAppAPI || {};
|
|
}
|
|
|
|
function agencyAPI() {
|
|
return api().agencyCenter || null;
|
|
}
|
|
|
|
function avatarData(text, background, foreground) {
|
|
var letter = encodeURIComponent(String(text || 'A').charAt(0));
|
|
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 toast(message) {
|
|
if (!message) return;
|
|
if (window.HyAppToast) {
|
|
window.HyAppToast.show(message);
|
|
return;
|
|
}
|
|
window.alert(message);
|
|
}
|
|
|
|
function formatMoney(value) {
|
|
var number = Number(value || 0);
|
|
return number.toLocaleString('en-US', {
|
|
minimumFractionDigits: 2,
|
|
maximumFractionDigits: 2,
|
|
});
|
|
}
|
|
|
|
function formatCount(value) {
|
|
var number = Number(value || 0);
|
|
return number.toLocaleString('en-US', {
|
|
maximumFractionDigits: 0,
|
|
});
|
|
}
|
|
|
|
function toNumber(value) {
|
|
var number = Number(value || 0);
|
|
return Number.isFinite(number) ? number : 0;
|
|
}
|
|
|
|
function commandID(prefix) {
|
|
return (
|
|
prefix +
|
|
'-' +
|
|
Date.now().toString(36) +
|
|
'-' +
|
|
Math.random().toString(36).slice(2, 8)
|
|
);
|
|
}
|
|
|
|
function firstValue(source, keys) {
|
|
if (!source) return '';
|
|
for (var i = 0; i < keys.length; i += 1) {
|
|
var value = source[keys[i]];
|
|
if (value !== undefined && value !== null && value !== '') {
|
|
return value;
|
|
}
|
|
}
|
|
return '';
|
|
}
|
|
|
|
function unwrapData(payload) {
|
|
if (!payload || typeof payload !== 'object') return payload;
|
|
return Object.prototype.hasOwnProperty.call(payload, 'data')
|
|
? payload.data
|
|
: payload;
|
|
}
|
|
|
|
function salaryDisplayAmount(salary, assetType) {
|
|
if (!salary) return 0;
|
|
if (
|
|
salary.display_amount !== undefined &&
|
|
salary.display_amount !== null
|
|
) {
|
|
return toNumber(salary.display_amount);
|
|
}
|
|
if (assetType === AGENCY_SALARY_USD || assetType === HOST_SALARY_USD) {
|
|
return toNumber(salary.available_amount) / 100;
|
|
}
|
|
return toNumber(salary.available_amount);
|
|
}
|
|
|
|
function initial(text) {
|
|
return String(text || '')
|
|
.trim()
|
|
.charAt(0)
|
|
.toUpperCase();
|
|
}
|
|
|
|
function currentLocale() {
|
|
var lang =
|
|
window.HyAppI18n && window.HyAppI18n.lang
|
|
? window.HyAppI18n.lang()
|
|
: 'en';
|
|
var map = {
|
|
en: 'en-US',
|
|
ar: 'ar',
|
|
tr: 'tr-TR',
|
|
es: 'es-ES',
|
|
zh: 'zh-CN',
|
|
id: 'id-ID',
|
|
};
|
|
return map[lang] || 'en-US';
|
|
}
|
|
|
|
function formatMode(value) {
|
|
var text = String(value || '')
|
|
.replace(/[_-]+/g, ' ')
|
|
.trim();
|
|
if (!text) return '-';
|
|
return text.replace(/\b\w/g, function (letter) {
|
|
return letter.toUpperCase();
|
|
});
|
|
}
|
|
|
|
function formatDate(ms) {
|
|
var value = toNumber(ms);
|
|
if (!value) return '';
|
|
try {
|
|
return new Date(value).toLocaleDateString(currentLocale(), {
|
|
year: 'numeric',
|
|
month: 'short',
|
|
day: 'numeric',
|
|
});
|
|
} catch (_) {
|
|
return '';
|
|
}
|
|
}
|
|
|
|
function policyAmount(minor) {
|
|
return '$' + formatMoney(toNumber(minor) / 100);
|
|
}
|
|
|
|
function setSkeleton(element, loading, text) {
|
|
if (!element) return;
|
|
element.classList.toggle('skeleton-line', Boolean(loading));
|
|
if (loading) {
|
|
element.textContent = '';
|
|
return;
|
|
}
|
|
element.textContent = text || '';
|
|
}
|
|
|
|
function setImage(image, fallback, src, name) {
|
|
if (!image || !fallback) return;
|
|
fallback.textContent = initial(name) || 'A';
|
|
if (!src) {
|
|
image.hidden = true;
|
|
image.removeAttribute('src');
|
|
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 setAvatarSkeleton(image, fallback, loading) {
|
|
if (!image || !fallback) return;
|
|
fallback.classList.toggle('avatar-skeleton', Boolean(loading));
|
|
if (!loading) return;
|
|
image.hidden = true;
|
|
image.removeAttribute('src');
|
|
fallback.hidden = false;
|
|
fallback.textContent = '';
|
|
}
|
|
|
|
function makeAvatar(item) {
|
|
var avatar = document.createElement('div');
|
|
var fallback = document.createElement('span');
|
|
avatar.className = 'small-avatar';
|
|
fallback.textContent = initial(item.name) || 'A';
|
|
avatar.appendChild(fallback);
|
|
if (item.avatar) {
|
|
var image = document.createElement('img');
|
|
image.src = item.avatar;
|
|
image.alt = '';
|
|
image.addEventListener('error', function () {
|
|
image.remove();
|
|
});
|
|
avatar.appendChild(image);
|
|
}
|
|
return avatar;
|
|
}
|
|
|
|
function displayName(user, fallback) {
|
|
if (!user) return fallback || '-';
|
|
return (
|
|
firstValue(user, ['username', 'name', 'display_user_id']) ||
|
|
fallback ||
|
|
'-'
|
|
);
|
|
}
|
|
|
|
function normalizeOverview(payload) {
|
|
var data = unwrapData(payload) || {};
|
|
var agency = data.agency || {};
|
|
var bd = data.bd || null;
|
|
state.profile = {
|
|
loading: false,
|
|
name: agency.name || '-',
|
|
shortId:
|
|
firstValue(agency, [
|
|
'agency_id',
|
|
'agencyId',
|
|
'short_id',
|
|
'shortId',
|
|
'display_user_id',
|
|
]) || '-',
|
|
avatar:
|
|
agency.avatar ||
|
|
avatarData(initial(agency.name) || 'A', '#dbc8ff', '#7d57c7'),
|
|
bd: bd
|
|
? {
|
|
name: displayName(bd, ''),
|
|
shortId: firstValue(bd, [
|
|
'display_user_id',
|
|
'displayUserID',
|
|
'user_id',
|
|
'userId',
|
|
]),
|
|
avatar: bd.avatar || '',
|
|
}
|
|
: null,
|
|
};
|
|
state.salary = {
|
|
loading: false,
|
|
available: salaryDisplayAmount(data.salary, AGENCY_SALARY_USD),
|
|
};
|
|
}
|
|
|
|
function normalizeHost(item) {
|
|
var userId = String(item.host_user_id || item.user_id || item.id || '');
|
|
var displayId = String(item.display_user_id || userId);
|
|
return {
|
|
id: displayId,
|
|
userId: userId,
|
|
name: item.username || displayId || userId || '-',
|
|
avatar: item.avatar || '',
|
|
salary: salaryDisplayAmount(item.salary, HOST_SALARY_USD),
|
|
};
|
|
}
|
|
|
|
function normalizeMessage(item) {
|
|
var applicant = item.applicant || {};
|
|
var applicantUserId = String(
|
|
item.applicant_user_id || applicant.user_id || ''
|
|
);
|
|
return {
|
|
id: String(item.application_id || item.id || ''),
|
|
applicationId: String(item.application_id || item.id || ''),
|
|
name: displayName(applicant, applicantUserId),
|
|
account: applicant.display_user_id || applicantUserId,
|
|
avatar: applicant.avatar || '',
|
|
};
|
|
}
|
|
|
|
function applyPolicy(payload) {
|
|
var data = unwrapData(payload);
|
|
if (!data || !data.found || !data.policy) {
|
|
state.policy = {
|
|
loading: false,
|
|
loaded: true,
|
|
found: false,
|
|
policy: null,
|
|
};
|
|
return;
|
|
}
|
|
state.policy = {
|
|
loading: false,
|
|
loaded: true,
|
|
found: true,
|
|
policy: data.policy,
|
|
};
|
|
}
|
|
|
|
function markLoadedEmpty() {
|
|
state.profile = {
|
|
loading: false,
|
|
name: '-',
|
|
shortId: '-',
|
|
avatar: '',
|
|
bd: null,
|
|
};
|
|
state.salary = { loading: false, available: 0 };
|
|
state.hosts = [];
|
|
state.messages = [];
|
|
state.policy = {
|
|
loading: false,
|
|
loaded: true,
|
|
found: false,
|
|
policy: null,
|
|
};
|
|
state.loading = false;
|
|
}
|
|
|
|
function renderProfile() {
|
|
var profile = state.profile;
|
|
var bd = profile.bd || null;
|
|
var bdRow = $('bdRow');
|
|
var loading = Boolean(profile.loading);
|
|
setSkeleton($('agencyName'), loading, profile.name || '-');
|
|
setSkeleton(
|
|
$('agencyShortId'),
|
|
loading,
|
|
t('agency_center.agency_short_id', 'ID: {id}').replace(
|
|
'{id}',
|
|
profile.shortId || '-'
|
|
)
|
|
);
|
|
setAvatarSkeleton($('agencyAvatar'), $('agencyAvatarFallback'), loading);
|
|
if (loading) {
|
|
bdRow.hidden = true;
|
|
return;
|
|
}
|
|
if (bd && bd.shortId) {
|
|
bdRow.hidden = false;
|
|
$('bdShortId').textContent = bd.shortId;
|
|
setImage($('bdAvatar'), $('bdAvatarFallback'), bd.avatar, bd.name);
|
|
} else {
|
|
bdRow.hidden = true;
|
|
$('bdShortId').textContent = '';
|
|
}
|
|
setImage(
|
|
$('agencyAvatar'),
|
|
$('agencyAvatarFallback'),
|
|
profile.avatar,
|
|
profile.name
|
|
);
|
|
}
|
|
|
|
function renderSalary() {
|
|
var loading = Boolean(state.salary.loading);
|
|
var currency = document.querySelector('.salary-currency');
|
|
if (currency) currency.classList.toggle('skeleton-coin', loading);
|
|
setSkeleton(
|
|
$('currentSalary'),
|
|
loading,
|
|
formatMoney(state.salary.available)
|
|
);
|
|
}
|
|
|
|
function renderHostCount() {
|
|
setSkeleton(
|
|
$('hostCount'),
|
|
Boolean(state.loading),
|
|
formatCount(state.hosts.length)
|
|
);
|
|
}
|
|
|
|
function renderUnread() {
|
|
var dot = $('messageUnreadDot');
|
|
if (dot) dot.hidden = state.messages.length <= 0;
|
|
}
|
|
|
|
function filteredHosts() {
|
|
var keyword = state.hostSearch.trim();
|
|
if (!keyword) return state.hosts;
|
|
return state.hosts.filter(function (host) {
|
|
return (
|
|
host.id.indexOf(keyword) >= 0 ||
|
|
String(host.userId || '').indexOf(keyword) >= 0 ||
|
|
host.name.toLowerCase().indexOf(keyword.toLowerCase()) >= 0
|
|
);
|
|
});
|
|
}
|
|
|
|
function skeletonHostRow() {
|
|
var row = document.createElement('div');
|
|
var user = document.createElement('div');
|
|
var avatar = document.createElement('div');
|
|
var copy = document.createElement('div');
|
|
var name = document.createElement('div');
|
|
var meta = document.createElement('div');
|
|
var side = document.createElement('div');
|
|
row.className = 'host-row is-skeleton';
|
|
user.className = 'host-user';
|
|
avatar.className = 'small-avatar avatar-skeleton';
|
|
copy.className = 'host-copy';
|
|
name.className = 'host-name skeleton-line';
|
|
meta.className = 'host-meta skeleton-line';
|
|
side.className = 'host-side-skeleton skeleton-line';
|
|
copy.appendChild(name);
|
|
copy.appendChild(meta);
|
|
user.appendChild(avatar);
|
|
user.appendChild(copy);
|
|
row.appendChild(user);
|
|
row.appendChild(side);
|
|
return row;
|
|
}
|
|
|
|
function renderHostList() {
|
|
var list = $('hostList');
|
|
var empty = $('hostListEmpty');
|
|
var hosts = filteredHosts();
|
|
list.textContent = '';
|
|
if (state.loading) {
|
|
empty.hidden = true;
|
|
list.appendChild(skeletonHostRow());
|
|
list.appendChild(skeletonHostRow());
|
|
list.appendChild(skeletonHostRow());
|
|
return;
|
|
}
|
|
empty.hidden = hosts.length > 0;
|
|
empty.textContent = t('agency_center.no_hosts', 'No hosts');
|
|
hosts.forEach(function (host) {
|
|
var row = document.createElement('div');
|
|
var user = document.createElement('div');
|
|
var copy = document.createElement('div');
|
|
var name = document.createElement('div');
|
|
var meta = document.createElement('div');
|
|
var remove = document.createElement('button');
|
|
row.className = 'host-row';
|
|
user.className = 'host-user';
|
|
copy.className = 'host-copy';
|
|
name.className = 'host-name';
|
|
meta.className = 'host-meta';
|
|
remove.className = 'remove-host-button';
|
|
remove.type = 'button';
|
|
name.textContent = host.name;
|
|
meta.textContent =
|
|
'UID: ' +
|
|
host.id +
|
|
' · ' +
|
|
t('agency_center.salary', 'Salary') +
|
|
': ' +
|
|
'$' +
|
|
formatMoney(host.salary);
|
|
remove.textContent = t('agency_center.remove', 'Remove');
|
|
remove.addEventListener('click', function () {
|
|
state.pendingRemoveHost = host;
|
|
renderRemoveConfirm();
|
|
openSheet('removeConfirmModal');
|
|
});
|
|
user.appendChild(makeAvatar(host));
|
|
copy.appendChild(name);
|
|
copy.appendChild(meta);
|
|
user.appendChild(copy);
|
|
row.appendChild(user);
|
|
row.appendChild(remove);
|
|
list.appendChild(row);
|
|
});
|
|
}
|
|
|
|
function renderRemoveConfirm() {
|
|
var host = state.pendingRemoveHost;
|
|
var text = $('removeConfirmText');
|
|
if (!text) return;
|
|
text.textContent = t(
|
|
'agency_center.remove_confirm_message',
|
|
'Confirm remove {name} from your agency?'
|
|
).replace('{name}', host ? host.name : '-');
|
|
}
|
|
|
|
function confirmRemoveHost() {
|
|
var host = state.pendingRemoveHost;
|
|
var service = agencyAPI();
|
|
if (!host || !service || !service.removeHost) {
|
|
toast(t('agency_center.api_not_ready', 'API module is not ready.'));
|
|
return;
|
|
}
|
|
service
|
|
.removeHost(host.userId || host.id, {
|
|
command_id: commandID('agency-remove-host'),
|
|
reason: 'agency_center',
|
|
})
|
|
.then(function () {
|
|
state.pendingRemoveHost = null;
|
|
closeSheet('removeConfirmModal');
|
|
toast(t('agency_center.host_removed', 'Host removed.'));
|
|
return loadAgencyCenter();
|
|
})
|
|
.catch(function (error) {
|
|
if (error && error.status === 409) return;
|
|
toast(
|
|
t(
|
|
'agency_center.remove_failed',
|
|
'Remove failed. Try again later.'
|
|
)
|
|
);
|
|
});
|
|
}
|
|
|
|
function renderMessages() {
|
|
var list = $('messageList');
|
|
var empty = $('messageEmpty');
|
|
list.textContent = '';
|
|
empty.hidden = state.messages.length > 0;
|
|
empty.textContent = t('agency_center.no_messages', 'No messages');
|
|
state.messages.forEach(function (message) {
|
|
var card = document.createElement('div');
|
|
var user = document.createElement('div');
|
|
var copy = document.createElement('div');
|
|
var name = document.createElement('div');
|
|
var id = document.createElement('div');
|
|
var actions = document.createElement('div');
|
|
var agree = document.createElement('button');
|
|
var refuse = document.createElement('button');
|
|
card.className = 'message-card';
|
|
user.className = 'message-user';
|
|
copy.className = 'message-copy';
|
|
name.className = 'message-name';
|
|
id.className = 'message-id';
|
|
actions.className = 'message-actions';
|
|
agree.className = 'message-action agree';
|
|
refuse.className = 'message-action refuse';
|
|
agree.type = 'button';
|
|
refuse.type = 'button';
|
|
name.textContent = message.name;
|
|
id.textContent = 'ID: ' + message.account;
|
|
agree.textContent = t('agency_center.agree', 'Agree');
|
|
refuse.textContent = t('agency_center.refuse', 'Refuse');
|
|
agree.addEventListener('click', function () {
|
|
processMessage(message, 'agree');
|
|
});
|
|
refuse.addEventListener('click', function () {
|
|
processMessage(message, 'refuse');
|
|
});
|
|
user.appendChild(makeAvatar(message));
|
|
copy.appendChild(name);
|
|
copy.appendChild(id);
|
|
user.appendChild(copy);
|
|
actions.appendChild(agree);
|
|
actions.appendChild(refuse);
|
|
card.appendChild(user);
|
|
card.appendChild(actions);
|
|
list.appendChild(card);
|
|
});
|
|
}
|
|
|
|
function processMessage(message, action) {
|
|
var service = agencyAPI();
|
|
if (!service || !service.reviewApplication) {
|
|
toast(t('agency_center.api_not_ready', 'API module is not ready.'));
|
|
return;
|
|
}
|
|
var decision = action === 'agree' ? 'approve' : 'reject';
|
|
service
|
|
.reviewApplication(message.applicationId || message.id, {
|
|
command_id: commandID('agency-review-application'),
|
|
decision: decision,
|
|
reason: 'agency_center',
|
|
})
|
|
.then(function () {
|
|
var key =
|
|
action === 'agree'
|
|
? 'agency_center.approved_application'
|
|
: 'agency_center.rejected_application';
|
|
var fallback =
|
|
action === 'agree'
|
|
? "Approved {name}'s application."
|
|
: "Rejected {name}'s application.";
|
|
toast(t(key, fallback).replace('{name}', message.name));
|
|
return loadAgencyCenter();
|
|
})
|
|
.catch(function (error) {
|
|
if (error && error.status === 409) return;
|
|
toast(
|
|
t(
|
|
'agency_center.review_failed',
|
|
'Review failed. Try again later.'
|
|
)
|
|
);
|
|
});
|
|
}
|
|
|
|
function appendPolicyCell(parent, label, value) {
|
|
var cell = document.createElement('div');
|
|
var labelNode = document.createElement('span');
|
|
var valueNode = document.createElement('strong');
|
|
cell.className = 'policy-cell';
|
|
labelNode.className = 'policy-cell-label';
|
|
labelNode.textContent = label;
|
|
valueNode.className = 'policy-cell-value';
|
|
valueNode.textContent = value;
|
|
cell.appendChild(labelNode);
|
|
cell.appendChild(valueNode);
|
|
parent.appendChild(cell);
|
|
}
|
|
|
|
function renderPolicy() {
|
|
var summary = state.policy || {};
|
|
var policy = summary.policy || {};
|
|
var list = $('policyLevelList');
|
|
var empty = $('policyEmpty');
|
|
if (!list || !empty) return;
|
|
|
|
list.textContent = '';
|
|
if (summary.loading) {
|
|
setSkeleton($('policyName'), true, '');
|
|
setSkeleton($('policyMeta'), true, '');
|
|
empty.hidden = false;
|
|
empty.textContent = '';
|
|
empty.classList.add('policy-skeleton-block');
|
|
return;
|
|
}
|
|
$('policyName').classList.remove('skeleton-line');
|
|
$('policyMeta').classList.remove('skeleton-line');
|
|
empty.classList.remove('policy-skeleton-block');
|
|
if (!summary.found || !policy || !policy.name) {
|
|
$('policyName').textContent = t(
|
|
'agency_center.agency_policy',
|
|
'Agency Policy'
|
|
);
|
|
$('policyMeta').textContent = '';
|
|
empty.hidden = false;
|
|
empty.textContent = 'No agency policy configured.';
|
|
return;
|
|
}
|
|
|
|
var from = formatDate(policy.effective_from_ms);
|
|
var to = formatDate(policy.effective_to_ms);
|
|
var meta = [
|
|
'Status: ' + formatMode(policy.status),
|
|
'Mode: ' + formatMode(policy.settlement_mode),
|
|
'Trigger: ' + formatMode(policy.settlement_trigger_mode),
|
|
'Gift ratio: ' + (policy.gift_coin_to_diamond_ratio || '-'),
|
|
'Residual rate: ' + (policy.residual_diamond_to_usd_rate || '-'),
|
|
];
|
|
if (from || to) {
|
|
meta.push('Effective: ' + (from || '-') + ' - ' + (to || 'No end'));
|
|
}
|
|
$('policyName').textContent = policy.name || 'Current policy';
|
|
$('policyMeta').textContent = meta.join(' / ');
|
|
empty.hidden = true;
|
|
empty.textContent = '';
|
|
|
|
var levels = Array.isArray(policy.levels) ? policy.levels : [];
|
|
if (!levels.length) {
|
|
empty.hidden = false;
|
|
empty.textContent = 'No policy levels configured.';
|
|
return;
|
|
}
|
|
|
|
levels.forEach(function (level) {
|
|
var row = document.createElement('div');
|
|
var head = document.createElement('div');
|
|
var title = document.createElement('strong');
|
|
var required = document.createElement('span');
|
|
var grid = document.createElement('div');
|
|
var levelNo = toNumber(level.level_no);
|
|
row.className = 'policy-level-row';
|
|
head.className = 'policy-row-head';
|
|
title.className = 'policy-level';
|
|
required.className = 'policy-effective';
|
|
grid.className = 'policy-grid';
|
|
title.textContent = 'Lv. ' + (levelNo || '-');
|
|
required.textContent =
|
|
formatCount(level.required_diamonds) + ' diamonds';
|
|
head.appendChild(title);
|
|
head.appendChild(required);
|
|
appendPolicyCell(
|
|
grid,
|
|
'Host salary',
|
|
policyAmount(level.host_salary_usd_minor)
|
|
);
|
|
appendPolicyCell(
|
|
grid,
|
|
'Host coin reward',
|
|
formatCount(level.host_coin_reward)
|
|
);
|
|
appendPolicyCell(
|
|
grid,
|
|
'Agency salary',
|
|
policyAmount(level.agency_salary_usd_minor)
|
|
);
|
|
appendPolicyCell(grid, 'Status', formatMode(level.status));
|
|
row.appendChild(head);
|
|
row.appendChild(grid);
|
|
list.appendChild(row);
|
|
});
|
|
}
|
|
|
|
function openSheet(id) {
|
|
var sheet = $(id);
|
|
if (!sheet) return;
|
|
sheet.hidden = false;
|
|
sheet.setAttribute('aria-hidden', 'false');
|
|
document.body.classList.add('modal-open');
|
|
}
|
|
|
|
function closeSheet(id) {
|
|
var sheet = $(id);
|
|
if (!sheet) return;
|
|
sheet.hidden = true;
|
|
sheet.setAttribute('aria-hidden', 'true');
|
|
var hasOpen = Array.prototype.some.call(
|
|
document.querySelectorAll(
|
|
'.sheet-modal, .message-modal, .confirm-modal'
|
|
),
|
|
function (modal) {
|
|
return !modal.hidden;
|
|
}
|
|
);
|
|
document.body.classList.toggle('modal-open', hasOpen);
|
|
}
|
|
|
|
function openPolicy() {
|
|
var modal = $('policyModal');
|
|
if (!modal) return;
|
|
modal.hidden = false;
|
|
modal.setAttribute('aria-hidden', 'false');
|
|
document.body.classList.add('modal-open');
|
|
renderPolicy();
|
|
if (!state.policy.loaded) loadPolicy();
|
|
}
|
|
|
|
function closePolicy() {
|
|
var modal = $('policyModal');
|
|
if (!modal) return;
|
|
modal.hidden = true;
|
|
modal.setAttribute('aria-hidden', 'true');
|
|
document.body.classList.remove('modal-open');
|
|
}
|
|
|
|
function closeAllSheets() {
|
|
document
|
|
.querySelectorAll(
|
|
'.sheet-modal, .message-modal, .confirm-modal'
|
|
)
|
|
.forEach(function (sheet) {
|
|
sheet.hidden = true;
|
|
sheet.setAttribute('aria-hidden', 'true');
|
|
});
|
|
state.pendingRemoveHost = null;
|
|
document.body.classList.remove('modal-open');
|
|
}
|
|
|
|
function navigateToWithdrawExchange() {
|
|
var params = new URLSearchParams(window.location.search);
|
|
params.set('identity', 'AGENCY');
|
|
params.set('salaryType', AGENCY_SALARY_USD);
|
|
params.set('asset_type', AGENCY_SALARY_USD);
|
|
if (!params.has('mode')) params.set('mode', 'withdraw');
|
|
window.location.href =
|
|
'../withdraw-exchange/index.html?' + params.toString();
|
|
}
|
|
|
|
function safeRequest(factory) {
|
|
return factory().catch(function (error) {
|
|
if (window.console && window.console.warn) {
|
|
window.console.warn('[agency-center] api failed', error);
|
|
}
|
|
return null;
|
|
});
|
|
}
|
|
|
|
function setLoading(loading) {
|
|
state.loading = Boolean(loading);
|
|
state.profile.loading = Boolean(loading);
|
|
state.salary.loading = Boolean(loading);
|
|
state.policy = Object.assign({}, state.policy, {
|
|
loading: Boolean(loading),
|
|
});
|
|
render();
|
|
}
|
|
|
|
function applyAgencyCenterPayload(overview, hosts, applications, policy) {
|
|
if (overview) {
|
|
normalizeOverview(overview);
|
|
} else {
|
|
state.profile.loading = false;
|
|
state.salary.loading = false;
|
|
}
|
|
state.hosts = ((hosts && hosts.items) || []).map(normalizeHost);
|
|
state.messages = ((applications && applications.items) || []).map(
|
|
normalizeMessage
|
|
);
|
|
if (policy) {
|
|
applyPolicy(policy);
|
|
} else {
|
|
state.policy = {
|
|
loading: false,
|
|
loaded: true,
|
|
found: false,
|
|
policy: null,
|
|
};
|
|
}
|
|
}
|
|
|
|
function loadPolicy() {
|
|
var service = agencyAPI();
|
|
if (!service || !service.platformPolicy) {
|
|
state.policy = {
|
|
loading: false,
|
|
loaded: true,
|
|
found: false,
|
|
policy: null,
|
|
};
|
|
renderPolicy();
|
|
return Promise.resolve(false);
|
|
}
|
|
state.policy = Object.assign({}, state.policy, { loading: true });
|
|
renderPolicy();
|
|
return safeRequest(function () {
|
|
return service.platformPolicy();
|
|
}).then(function (payload) {
|
|
if (payload) {
|
|
applyPolicy(payload);
|
|
} else {
|
|
state.policy = {
|
|
loading: false,
|
|
loaded: true,
|
|
found: false,
|
|
policy: null,
|
|
};
|
|
}
|
|
renderPolicy();
|
|
return Boolean(payload);
|
|
});
|
|
}
|
|
|
|
function loadAgencyCenter() {
|
|
var service = agencyAPI();
|
|
setLoading(true);
|
|
if (
|
|
!service ||
|
|
!service.overview ||
|
|
!service.hosts ||
|
|
!service.applications ||
|
|
!service.platformPolicy
|
|
) {
|
|
markLoadedEmpty();
|
|
render();
|
|
toast(t('agency_center.api_not_ready', 'API module is not ready.'));
|
|
return Promise.resolve(false);
|
|
}
|
|
if (window.HyAppParams && window.HyAppParams.parse) {
|
|
window.HyAppParams.parse();
|
|
}
|
|
return Promise.all([
|
|
safeRequest(function () {
|
|
return service.overview();
|
|
}),
|
|
safeRequest(function () {
|
|
return service.hosts();
|
|
}),
|
|
safeRequest(function () {
|
|
return service.applications('pending');
|
|
}),
|
|
safeRequest(function () {
|
|
return service.platformPolicy();
|
|
}),
|
|
]).then(function (results) {
|
|
applyAgencyCenterPayload(
|
|
results[0],
|
|
results[1],
|
|
results[2],
|
|
results[3]
|
|
);
|
|
state.loading = false;
|
|
render();
|
|
if (
|
|
!results[0] &&
|
|
!results[1] &&
|
|
!results[2] &&
|
|
!results[3]
|
|
) {
|
|
toast(
|
|
t(
|
|
'agency_center.load_failed',
|
|
'Load failed. Try again later.'
|
|
)
|
|
);
|
|
return false;
|
|
}
|
|
return true;
|
|
});
|
|
}
|
|
|
|
function bindEvents() {
|
|
$('backButton').addEventListener('click', function () {
|
|
if (window.HyAppBridge) window.HyAppBridge.back();
|
|
});
|
|
$('messageButton').addEventListener('click', function () {
|
|
renderMessages();
|
|
openSheet('messageModal');
|
|
});
|
|
$('withdrawExchangeButton').addEventListener(
|
|
'click',
|
|
navigateToWithdrawExchange
|
|
);
|
|
$('salaryValueButton').addEventListener(
|
|
'click',
|
|
navigateToWithdrawExchange
|
|
);
|
|
$('hostSearchForm').addEventListener('submit', function (event) {
|
|
event.preventDefault();
|
|
state.hostSearch = $('hostSearchInput').value || '';
|
|
renderHostList();
|
|
});
|
|
$('confirmRemoveButton').addEventListener('click', confirmRemoveHost);
|
|
document
|
|
.querySelectorAll('[data-close-sheet]')
|
|
.forEach(function (node) {
|
|
node.addEventListener('click', function () {
|
|
if (
|
|
node.getAttribute('data-close-sheet') ===
|
|
'removeConfirmModal'
|
|
) {
|
|
state.pendingRemoveHost = null;
|
|
}
|
|
closeSheet(node.getAttribute('data-close-sheet'));
|
|
});
|
|
});
|
|
document
|
|
.querySelectorAll('[data-close-policy]')
|
|
.forEach(function (button) {
|
|
button.addEventListener('click', closePolicy);
|
|
});
|
|
document.querySelectorAll('.menu-row').forEach(function (button) {
|
|
button.addEventListener('click', function () {
|
|
var action = button.getAttribute('data-action');
|
|
if (action === 'host-list') {
|
|
state.hostSearch = '';
|
|
$('hostSearchInput').value = '';
|
|
renderHostList();
|
|
openSheet('hostSheet');
|
|
return;
|
|
}
|
|
if (action === 'policy') {
|
|
openPolicy();
|
|
return;
|
|
}
|
|
if (action === 'invite') {
|
|
openSheet('inviteSheet');
|
|
}
|
|
});
|
|
});
|
|
document.addEventListener('keydown', function (event) {
|
|
if (event.key === 'Escape') closeAllSheets();
|
|
});
|
|
}
|
|
|
|
function render() {
|
|
renderProfile();
|
|
renderSalary();
|
|
renderHostCount();
|
|
renderUnread();
|
|
renderHostList();
|
|
renderMessages();
|
|
renderPolicy();
|
|
}
|
|
|
|
function initPage() {
|
|
render();
|
|
bindEvents();
|
|
loadAgencyCenter().finally(function () {
|
|
if (window.HyAppBridge) {
|
|
window.HyAppBridge.ready({
|
|
page: 'agency-center',
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', initPage);
|
|
} else {
|
|
initPage();
|
|
}
|
|
|
|
window.addEventListener('hyapp:i18n-ready', function () {
|
|
render();
|
|
});
|
|
})();
|