hyapp-h5/gonghui/common/contact-card.js
2026-06-29 18:27:25 +08:00

216 lines
8.5 KiB
JavaScript

(function () {
var mounted = false;
function t(key, fallback) {
return window.HyAppI18n && window.HyAppI18n.t
? window.HyAppI18n.t(key, fallback)
: fallback;
}
function toast(message) {
if (window.HyAppToast && window.HyAppToast.show) {
window.HyAppToast.show(message);
}
}
function contactFrom(value) {
if (!value || typeof value !== 'object') return '';
var source = value.profile || value.user || value;
var keys = [
'contact_info',
'contactInfo',
'whatsapp_phone',
'whatsappPhone',
'contact',
];
for (var i = 0; i < keys.length; i += 1) {
var text = String(source[keys[i]] || '').trim();
if (text) return text;
}
return '';
}
function render(mount) {
mount.innerHTML =
'<section class="card contact-card">' +
' <button class="contact-row" type="button" data-contact-open data-i18n-aria="contact_card.open" aria-label="Edit WhatsApp contact">' +
' <span class="contact-icon" aria-hidden="true">' +
' <svg viewBox="0 0 24 24"><path d="M7 18.5 4 20l.8-3.5A8 8 0 1 1 12 20a8.8 8.8 0 0 1-5-1.5Z"/><path d="M9 8.8c.2 3 2.2 5 5.2 5.4l1-1.6c.2-.3.6-.4.9-.2l1.3.7"/><path d="M8.4 7.4 9 8.8"/></svg>' +
' </span>' +
' <span class="contact-copy">' +
' <span class="contact-title" data-i18n="contact_card.title">WhatsApp</span>' +
' <span class="contact-value" data-contact-value data-i18n="contact_card.add_whatsapp">Add WhatsApp</span>' +
' </span>' +
' <span class="contact-action" data-contact-action data-i18n="contact_card.add">Add</span>' +
' </button>' +
'</section>' +
'<div class="sheet-modal contact-modal" data-contact-modal hidden aria-hidden="true">' +
' <button class="modal-backdrop" type="button" data-contact-close data-i18n-aria="contact_card.close" aria-label="Close"></button>' +
' <section class="bottom-sheet contact-sheet" role="dialog" aria-modal="true" aria-labelledby="contactSheetTitle">' +
' <div class="sheet-head">' +
' <h2 id="contactSheetTitle" data-i18n="contact_card.sheet_title">WhatsApp Contact</h2>' +
' <button class="sheet-close" type="button" data-contact-close data-i18n-aria="contact_card.close" aria-label="Close">&times;</button>' +
' </div>' +
' <form data-contact-form>' +
' <label class="contact-field">' +
' <span data-i18n="contact_card.field_label">WhatsApp phone or link</span>' +
' <input class="contact-input" data-contact-input type="text" inputmode="text" autocomplete="off" placeholder="+6512345678" data-i18n-placeholder="contact_card.placeholder" />' +
' </label>' +
' <button class="contact-save" type="submit" data-contact-save data-i18n="contact_card.save">Save</button>' +
' <div class="contact-status" data-contact-status hidden></div>' +
' </form>' +
' </section>' +
'</div>';
if (window.HyAppI18n && window.HyAppI18n.apply) {
window.HyAppI18n.apply(mount);
}
}
function setModalOpen(root, open) {
var modal = root.querySelector('[data-contact-modal]');
if (!modal) return;
modal.hidden = !open;
modal.setAttribute('aria-hidden', open ? 'false' : 'true');
document.body.classList.toggle('modal-open', open);
if (open) {
var input = root.querySelector('[data-contact-input]');
if (input) input.focus();
}
}
function setContact(root, value) {
var contact = String(value || '').trim();
var valueNode = root.querySelector('[data-contact-value]');
var actionNode = root.querySelector('[data-contact-action]');
if (valueNode) {
valueNode.textContent =
contact || t('contact_card.add_whatsapp', 'Add WhatsApp');
if (contact) {
valueNode.removeAttribute('data-i18n');
} else {
valueNode.setAttribute('data-i18n', 'contact_card.add_whatsapp');
}
}
if (actionNode) {
actionNode.textContent = contact
? t('contact_card.edit', 'Edit')
: t('contact_card.add', 'Add');
if (contact) {
actionNode.removeAttribute('data-i18n');
} else {
actionNode.setAttribute('data-i18n', 'contact_card.add');
}
}
root.dataset.contactValue = contact;
}
function setStatus(root, message) {
var status = root.querySelector('[data-contact-status]');
if (!status) return;
status.textContent = message || '';
status.hidden = !message;
}
function setSaving(root, saving) {
var button = root.querySelector('[data-contact-save]');
if (!button) return;
button.disabled = saving;
button.textContent = saving
? t('contact_card.saving', 'Saving...')
: t('contact_card.save', 'Save');
}
function loadCurrentContact(root) {
var api = window.HyAppAPI && window.HyAppAPI.user;
if (!api || !api.me) return;
api.me()
.then(function (profile) {
setContact(root, contactFrom(profile));
})
.catch(function () {
setContact(root, '');
});
}
function bind(root) {
root.addEventListener('click', function (event) {
if (event.target.closest('[data-contact-open]')) {
var input = root.querySelector('[data-contact-input]');
if (input) input.value = root.dataset.contactValue || '';
setStatus(root, '');
setModalOpen(root, true);
return;
}
if (event.target.closest('[data-contact-close]')) {
setModalOpen(root, false);
}
});
var form = root.querySelector('[data-contact-form]');
if (!form) return;
form.addEventListener('submit', function (event) {
event.preventDefault();
var api = window.HyAppAPI && window.HyAppAPI.user;
var input = root.querySelector('[data-contact-input]');
var contact = input ? String(input.value || '').trim() : '';
if (!contact) {
setStatus(
root,
t('contact_card.required', 'Enter WhatsApp contact.')
);
return;
}
if (!api || !api.updateContact) {
setStatus(
root,
t('contact_card.api_unavailable', 'Contact API unavailable.')
);
return;
}
// 联系方式是用户主资料,不依赖当前中心页身份;保存成功后用后端返回值刷新展示,避免本地输入和服务端裁剪值不一致。
setSaving(root, true);
setStatus(root, '');
api.updateContact({ contact_info: contact })
.then(function (response) {
setContact(root, contactFrom(response) || contact);
setModalOpen(root, false);
toast(t('contact_card.saved', 'Saved.'));
})
.catch(function () {
setStatus(
root,
t('contact_card.save_failed', 'Save failed.')
);
})
.finally(function () {
setSaving(root, false);
});
});
}
function init() {
if (mounted) return;
var mounts = document.querySelectorAll('[data-contact-card]');
if (!mounts.length) return;
mounted = true;
mounts.forEach(function (mount) {
render(mount);
bind(mount);
loadCurrentContact(mount);
});
}
window.addEventListener('hyapp:i18n-ready', function () {
document.querySelectorAll('[data-contact-card]').forEach(function (root) {
setContact(root, root.dataset.contactValue || '');
});
});
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();