feat: add role invitation messages

This commit is contained in:
zhx 2026-06-12 18:09:03 +08:00
parent 51645bf47a
commit 605eafa78d
16 changed files with 2016 additions and 11 deletions

View File

@ -480,6 +480,12 @@ var default_api = 'https://api.global-interaction.com/';
}
);
},
inviteHost: function (payload) {
return request('/api/v1/agency-center/invitations/host', {
method: 'POST',
body: payload || {},
});
},
};
var hostCenterAPI = {
@ -547,6 +553,26 @@ var default_api = 'https://api.global-interaction.com/';
},
};
var roleInvitationAPI = {
list: function (status, pageSize) {
return request('/api/v1/role-invitations', {
method: 'GET',
query: { status: status || 'pending', page_size: pageSize || 50 },
});
},
process: function (invitationID, payload) {
return request(
'/api/v1/role-invitations/' +
encodeURIComponent(invitationID || '') +
'/process',
{
method: 'POST',
body: payload || {},
}
);
},
};
var managerCenterAPI = {
overview: function () {
return request('/api/v1/manager-center/overview', {
@ -852,6 +878,7 @@ var default_api = 'https://api.global-interaction.com/';
agencyCenter: agencyCenterAPI,
bdCenter: bdCenterAPI,
bdLeaderCenter: bdLeaderCenterAPI,
roleInvitations: roleInvitationAPI,
managerCenter: managerCenterAPI,
superadminCenter: superadminCenterAPI,
level: levelAPI,

View File

@ -168,6 +168,30 @@
"host_center.leave_agency": "مغادرة الوكالة",
"host_center.leave_confirm_message": "هل أنت متأكد أنك تريد مغادرة وكالتك؟",
"host_center.confirm": "تأكيد",
"host_center.open_messages": "فتح الرسائل",
"host_center.messages": "الرسائل",
"host_center.no_messages": "لا توجد رسائل",
"host_center.loading_messages": "جارٍ التحميل...",
"host_center.agree": "موافقة",
"host_center.refuse": "رفض",
"host_center.processing": "جارٍ المعالجة...",
"host_center.host_invitation_title": "دعوة مضيف",
"host_center.agency_invitation_title": "دعوة وكالة",
"host_center.bd_invitation_title": "دعوة BD",
"host_center.invitation_title": "دعوة",
"host_center.host_invitation": "{name} دعاك للانضمام إلى {agency}",
"host_center.agency_invitation": "{name} دعاك لإنشاء وكالة {agency}",
"host_center.bd_invitation": "{name} دعاك لتصبح BD",
"host_center.role_invitation": "{name} أرسل لك دعوة",
"host_center.host_invitation_message": "{name} دعاك للانضمام إلى {agency}.",
"host_center.agency_invitation_message": "{name} دعاك لتصبح مالك وكالة.",
"host_center.bd_invitation_message": "{name} دعاك لتصبح BD.",
"host_center.invitation_message": "{name} أرسل لك دعوة.",
"host_center.invitation_accepted": "تم قبول الدعوة.",
"host_center.invitation_rejected": "تم رفض الدعوة.",
"host_center.load_messages_failed": "فشل تحميل الرسائل.",
"host_center.process_failed": "فشلت المعالجة. حاول مرة أخرى لاحقًا.",
"host_center.process_invitation_failed": "فشلت المعالجة. حاول مرة أخرى لاحقًا.",
"host_center.close": "إغلاق",
"host_center.leave_success_mock": "تم إرسال طلب مغادرة الوكالة.",
"host_center.mock_navigation": "انتقال تجريبي: {label}",
@ -293,6 +317,28 @@
"bd_center.invite_failed": "فشلت الدعوة. حاول مرة أخرى لاحقًا.",
"bd_center.agency_added": "تمت إضافة الوكالة.",
"bd_center.tools": "أدوات BD",
"bd_center.messages": "الرسائل",
"bd_center.no_messages": "لا توجد رسائل",
"bd_center.loading_messages": "جارٍ التحميل...",
"bd_center.agree": "موافقة",
"bd_center.refuse": "رفض",
"bd_center.processing": "جارٍ المعالجة...",
"bd_center.host_invitation_title": "دعوة مضيف",
"bd_center.agency_invitation_title": "دعوة وكالة",
"bd_center.bd_invitation_title": "دعوة BD",
"bd_center.invitation_title": "دعوة",
"bd_center.host_invitation": "{name} دعاك للانضمام إلى {agency}",
"bd_center.agency_invitation": "{name} دعاك لإنشاء وكالة {agency}",
"bd_center.bd_invitation": "{name} دعاك لتصبح BD",
"bd_center.role_invitation": "{name} أرسل لك دعوة",
"bd_center.host_invitation_message": "{name} دعاك للانضمام إلى {agency}.",
"bd_center.agency_invitation_message": "{name} دعاك لتصبح مالك وكالة.",
"bd_center.bd_invitation_message": "{name} دعاك لتصبح BD.",
"bd_center.invitation_message": "{name} أرسل لك دعوة.",
"bd_center.invitation_accepted": "تم قبول الدعوة.",
"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": "تغيير اللغة",
@ -513,5 +559,39 @@
"tasks.loadFailed": "فشل التحميل.",
"tasks.claimSuccess": "تم استلام المكافأة.",
"tasks.claimFailed": "فشل الاستلام.",
"tasks.noAction": "لم يتم إعداد الانتقال."
"tasks.noAction": "لم يتم إعداد الانتقال.",
"agencyOpening.pageTitle": "فعالية افتتاح الوكالة الجديدة",
"agencyOpening.pageLabel": "فعالية افتتاح الوكالة الجديدة",
"agencyOpening.heroSubtitle": "حصري للوكالات الجديدة",
"agencyOpening.days": "أيام",
"agencyOpening.hours": "ساعات",
"agencyOpening.minutes": "دقائق",
"agencyOpening.seconds": "ثوان",
"agencyOpening.qualificationTitle": "شروط الافتتاح",
"agencyOpening.agencyIdentity": "هوية الوكالة",
"agencyOpening.hostCount": "عدد المضيفين",
"agencyOpening.openingStatus": "حالة الافتتاح",
"agencyOpening.apply": "تقديم طلب الافتتاح",
"agencyOpening.eligible": "مؤهل للتقديم",
"agencyOpening.notEligible": "غير مؤهل",
"agencyOpening.joined": "تم الانضمام",
"agencyOpening.notJoined": "لم ينضم",
"agencyOpening.applied": "تم التقديم",
"agencyOpening.applySuccess": "تم إرسال الطلب.",
"agencyOpening.applyFailed": "فشل الطلب. حاول لاحقا.",
"agencyOpening.rewardsTitle": "مكافآت الافتتاح",
"agencyOpening.openingRevenue": "إيراد الافتتاح",
"agencyOpening.rewardCoins": "عملات المكافأة",
"agencyOpening.rulesTitle": "قواعد الفعالية",
"agencyOpening.rule1": "يمكن لحسابات الوكالات فقط التقديم.",
"agencyOpening.rule2": "يجب أن يكون عدد المضيفين أكثر من 10.",
"agencyOpening.rule3": "يجب أن يكون عمر الوكالة أقل من 7 أيام.",
"agencyOpening.rule4": "يمكن لكل وكالة المشاركة مرة واحدة فقط.",
"agencyOpening.rule5": "لا يمكن تشغيل فعالية الافتتاح مع برنامج دعم الوكالات في نفس الوقت.",
"agencyOpening.rule6": "ترسل المكافآت خلال 7 أيام بعد المراجعة.",
"agencyOpening.recordTitle": "سجل الافتتاح",
"agencyOpening.guildName": "اسم النقابة:",
"agencyOpening.created": "تاريخ الإنشاء:",
"agencyOpening.recordRevenue": "إيراد الافتتاح:",
"agencyOpening.recordReward": "المكافأة:"
}

View File

@ -168,6 +168,30 @@
"host_center.leave_agency": "Leave Agency",
"host_center.leave_confirm_message": "Are you sure you want to leave your agency?",
"host_center.confirm": "Confirm",
"host_center.open_messages": "Open messages",
"host_center.messages": "Messages",
"host_center.no_messages": "No messages",
"host_center.loading_messages": "Loading...",
"host_center.agree": "Agree",
"host_center.refuse": "Refuse",
"host_center.processing": "Processing...",
"host_center.host_invitation_title": "Host invitation",
"host_center.agency_invitation_title": "Agency invitation",
"host_center.bd_invitation_title": "BD invitation",
"host_center.invitation_title": "Invitation",
"host_center.host_invitation": "{name} invited you to join {agency}",
"host_center.agency_invitation": "{name} invited you to create agency {agency}",
"host_center.bd_invitation": "{name} invited you to become BD",
"host_center.role_invitation": "{name} sent you an invitation",
"host_center.host_invitation_message": "{name} invited you to join {agency}.",
"host_center.agency_invitation_message": "{name} invited you to become an Agency owner.",
"host_center.bd_invitation_message": "{name} invited you to become a BD.",
"host_center.invitation_message": "{name} sent you an invitation.",
"host_center.invitation_accepted": "Invitation accepted.",
"host_center.invitation_rejected": "Invitation rejected.",
"host_center.load_messages_failed": "Load messages failed.",
"host_center.process_failed": "Process failed. Try again later.",
"host_center.process_invitation_failed": "Process failed. Try again later.",
"host_center.close": "Close",
"host_center.leave_success_mock": "Agency leave submitted.",
"host_center.mock_navigation": "Mock navigation: {label}",
@ -299,6 +323,28 @@
"bd_center.invite_failed": "Invite failed. Try again later.",
"bd_center.agency_added": "Agency added.",
"bd_center.tools": "BD tools",
"bd_center.messages": "Messages",
"bd_center.no_messages": "No messages",
"bd_center.loading_messages": "Loading...",
"bd_center.agree": "Agree",
"bd_center.refuse": "Refuse",
"bd_center.processing": "Processing...",
"bd_center.host_invitation_title": "Host invitation",
"bd_center.agency_invitation_title": "Agency invitation",
"bd_center.bd_invitation_title": "BD invitation",
"bd_center.invitation_title": "Invitation",
"bd_center.host_invitation": "{name} invited you to join {agency}",
"bd_center.agency_invitation": "{name} invited you to create agency {agency}",
"bd_center.bd_invitation": "{name} invited you to become BD",
"bd_center.role_invitation": "{name} sent you an invitation",
"bd_center.host_invitation_message": "{name} invited you to join {agency}.",
"bd_center.agency_invitation_message": "{name} invited you to become an Agency owner.",
"bd_center.bd_invitation_message": "{name} invited you to become a BD.",
"bd_center.invitation_message": "{name} sent you an invitation.",
"bd_center.invitation_accepted": "Invitation accepted.",
"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",
@ -519,5 +565,39 @@
"tasks.loadFailed": "Load failed.",
"tasks.claimSuccess": "Reward claimed.",
"tasks.claimFailed": "Claim failed.",
"tasks.noAction": "No action configured."
"tasks.noAction": "No action configured.",
"agencyOpening.pageTitle": "New Agency Opening Event",
"agencyOpening.pageLabel": "New Agency Opening Event",
"agencyOpening.heroSubtitle": "Exclusive for New Agencies",
"agencyOpening.days": "Days",
"agencyOpening.hours": "Hours",
"agencyOpening.minutes": "Minutes",
"agencyOpening.seconds": "Seconds",
"agencyOpening.qualificationTitle": "Opening Qualification",
"agencyOpening.agencyIdentity": "Agency Identity",
"agencyOpening.hostCount": "Host Count",
"agencyOpening.openingStatus": "Opening Status",
"agencyOpening.apply": "Apply Opening Event",
"agencyOpening.eligible": "Eligible To Apply",
"agencyOpening.notEligible": "Not Eligible",
"agencyOpening.joined": "Joined",
"agencyOpening.notJoined": "Not Joined",
"agencyOpening.applied": "Applied",
"agencyOpening.applySuccess": "Application submitted.",
"agencyOpening.applyFailed": "Application failed. Try again later.",
"agencyOpening.rewardsTitle": "Opening Rewards",
"agencyOpening.openingRevenue": "Opening Revenue",
"agencyOpening.rewardCoins": "Reward Coins",
"agencyOpening.rulesTitle": "Activity Rules",
"agencyOpening.rule1": "Only agency accounts can apply.",
"agencyOpening.rule2": "Host count must be more than 10.",
"agencyOpening.rule3": "Agency age must be less than 7 days.",
"agencyOpening.rule4": "Each agency can join only once in lifetime.",
"agencyOpening.rule5": "Opening Event cannot run with Agency Support Program at the same time.",
"agencyOpening.rule6": "Rewards will be sent within 7 days after review.",
"agencyOpening.recordTitle": "Opening Record",
"agencyOpening.guildName": "Guild Name:",
"agencyOpening.created": "Created:",
"agencyOpening.recordRevenue": "Opening Revenue:",
"agencyOpening.recordReward": "Reward:"
}

View File

@ -168,6 +168,30 @@
"host_center.leave_agency": "Salir de la agencia",
"host_center.leave_confirm_message": "¿Seguro que quieres salir de tu agencia?",
"host_center.confirm": "Confirmar",
"host_center.open_messages": "Abrir mensajes",
"host_center.messages": "Mensajes",
"host_center.no_messages": "Sin mensajes",
"host_center.loading_messages": "Cargando...",
"host_center.agree": "Aceptar",
"host_center.refuse": "Rechazar",
"host_center.processing": "Procesando...",
"host_center.host_invitation_title": "Invitación de host",
"host_center.agency_invitation_title": "Invitación de agency",
"host_center.bd_invitation_title": "Invitación de BD",
"host_center.invitation_title": "Invitación",
"host_center.host_invitation": "{name} te invitó a unirte a {agency}",
"host_center.agency_invitation": "{name} te invitó a crear la agency {agency}",
"host_center.bd_invitation": "{name} te invitó a convertirte en BD",
"host_center.role_invitation": "{name} te envió una invitación",
"host_center.host_invitation_message": "{name} te invitó a unirte a {agency}.",
"host_center.agency_invitation_message": "{name} te invitó a ser responsable de una Agency.",
"host_center.bd_invitation_message": "{name} te invitó a convertirte en BD.",
"host_center.invitation_message": "{name} te envió una invitación.",
"host_center.invitation_accepted": "Invitación aceptada.",
"host_center.invitation_rejected": "Invitación rechazada.",
"host_center.load_messages_failed": "Error al cargar mensajes.",
"host_center.process_failed": "Error al procesar. Inténtalo de nuevo más tarde.",
"host_center.process_invitation_failed": "Error al procesar. Inténtalo de nuevo más tarde.",
"host_center.close": "Cerrar",
"host_center.leave_success_mock": "Solicitud de salida enviada.",
"host_center.mock_navigation": "Navegación mock: {label}",
@ -293,6 +317,28 @@
"bd_center.invite_failed": "Error al invitar. Inténtalo de nuevo más tarde.",
"bd_center.agency_added": "Agencia agregada.",
"bd_center.tools": "Herramientas BD",
"bd_center.messages": "Mensajes",
"bd_center.no_messages": "Sin mensajes",
"bd_center.loading_messages": "Cargando...",
"bd_center.agree": "Aceptar",
"bd_center.refuse": "Rechazar",
"bd_center.processing": "Procesando...",
"bd_center.host_invitation_title": "Invitación de host",
"bd_center.agency_invitation_title": "Invitación de agency",
"bd_center.bd_invitation_title": "Invitación de BD",
"bd_center.invitation_title": "Invitación",
"bd_center.host_invitation": "{name} te invitó a unirte a {agency}",
"bd_center.agency_invitation": "{name} te invitó a crear la agency {agency}",
"bd_center.bd_invitation": "{name} te invitó a convertirte en BD",
"bd_center.role_invitation": "{name} te envió una invitación",
"bd_center.host_invitation_message": "{name} te invitó a unirte a {agency}.",
"bd_center.agency_invitation_message": "{name} te invitó a ser responsable de una Agency.",
"bd_center.bd_invitation_message": "{name} te invitó a convertirte en BD.",
"bd_center.invitation_message": "{name} te envió una invitación.",
"bd_center.invitation_accepted": "Invitación aceptada.",
"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",
@ -513,5 +559,39 @@
"tasks.loadFailed": "Error al cargar.",
"tasks.claimSuccess": "Recompensa reclamada.",
"tasks.claimFailed": "Error al reclamar.",
"tasks.noAction": "No hay acción configurada."
"tasks.noAction": "No hay acción configurada.",
"agencyOpening.pageTitle": "Evento de apertura de nueva agencia",
"agencyOpening.pageLabel": "Evento de apertura de nueva agencia",
"agencyOpening.heroSubtitle": "Exclusivo para agencias nuevas",
"agencyOpening.days": "Días",
"agencyOpening.hours": "Horas",
"agencyOpening.minutes": "Minutos",
"agencyOpening.seconds": "Segundos",
"agencyOpening.qualificationTitle": "Requisitos de apertura",
"agencyOpening.agencyIdentity": "Identidad de agencia",
"agencyOpening.hostCount": "Cantidad de hosts",
"agencyOpening.openingStatus": "Estado de apertura",
"agencyOpening.apply": "Solicitar evento de apertura",
"agencyOpening.eligible": "Elegible para solicitar",
"agencyOpening.notEligible": "No elegible",
"agencyOpening.joined": "Unido",
"agencyOpening.notJoined": "No unido",
"agencyOpening.applied": "Solicitado",
"agencyOpening.applySuccess": "Solicitud enviada.",
"agencyOpening.applyFailed": "Solicitud fallida. Inténtalo más tarde.",
"agencyOpening.rewardsTitle": "Recompensas de apertura",
"agencyOpening.openingRevenue": "Ingresos de apertura",
"agencyOpening.rewardCoins": "Monedas de recompensa",
"agencyOpening.rulesTitle": "Reglas de actividad",
"agencyOpening.rule1": "Solo las cuentas de agencia pueden solicitar.",
"agencyOpening.rule2": "La cantidad de hosts debe ser mayor que 10.",
"agencyOpening.rule3": "La agencia debe tener menos de 7 días.",
"agencyOpening.rule4": "Cada agencia solo puede participar una vez.",
"agencyOpening.rule5": "El evento de apertura no puede ejecutarse junto con el Programa de soporte de agencias.",
"agencyOpening.rule6": "Las recompensas se enviarán dentro de 7 días después de la revisión.",
"agencyOpening.recordTitle": "Registro de apertura",
"agencyOpening.guildName": "Nombre del gremio:",
"agencyOpening.created": "Creado:",
"agencyOpening.recordRevenue": "Ingresos de apertura:",
"agencyOpening.recordReward": "Recompensa:"
}

View File

@ -135,6 +135,30 @@
"host_center.leave_agency": "Keluar dari Agency",
"host_center.leave_confirm_message": "Apakah Anda yakin ingin keluar dari agency Anda?",
"host_center.confirm": "Konfirmasi",
"host_center.open_messages": "Buka pesan",
"host_center.messages": "Pesan",
"host_center.no_messages": "Tidak ada pesan",
"host_center.loading_messages": "Memuat...",
"host_center.agree": "Setuju",
"host_center.refuse": "Tolak",
"host_center.processing": "Memproses...",
"host_center.host_invitation_title": "Undangan host",
"host_center.agency_invitation_title": "Undangan Agency",
"host_center.bd_invitation_title": "Undangan BD",
"host_center.invitation_title": "Undangan",
"host_center.host_invitation": "{name} mengundang Anda bergabung ke {agency}",
"host_center.agency_invitation": "{name} mengundang Anda membuat Agency {agency}",
"host_center.bd_invitation": "{name} mengundang Anda menjadi BD",
"host_center.role_invitation": "{name} mengirim undangan kepada Anda",
"host_center.host_invitation_message": "{name} mengundang Anda bergabung ke {agency}.",
"host_center.agency_invitation_message": "{name} mengundang Anda menjadi pemilik Agency.",
"host_center.bd_invitation_message": "{name} mengundang Anda menjadi BD.",
"host_center.invitation_message": "{name} mengirim undangan kepada Anda.",
"host_center.invitation_accepted": "Undangan diterima.",
"host_center.invitation_rejected": "Undangan ditolak.",
"host_center.load_messages_failed": "Gagal memuat pesan.",
"host_center.process_failed": "Gagal memproses. Coba lagi nanti.",
"host_center.process_invitation_failed": "Gagal memproses. Coba lagi nanti.",
"host_center.close": "Tutup",
"host_center.leave_success_mock": "Pengajuan keluar agency terkirim.",
"host_center.mock_navigation": "Navigasi mock: {label}",
@ -260,6 +284,28 @@
"bd_center.invite_failed": "Undangan gagal. Coba lagi nanti.",
"bd_center.agency_added": "Agency ditambahkan.",
"bd_center.tools": "Alat BD",
"bd_center.messages": "Pesan",
"bd_center.no_messages": "Tidak ada pesan",
"bd_center.loading_messages": "Memuat...",
"bd_center.agree": "Setuju",
"bd_center.refuse": "Tolak",
"bd_center.processing": "Memproses...",
"bd_center.host_invitation_title": "Undangan host",
"bd_center.agency_invitation_title": "Undangan Agency",
"bd_center.bd_invitation_title": "Undangan BD",
"bd_center.invitation_title": "Undangan",
"bd_center.host_invitation": "{name} mengundang Anda bergabung ke {agency}",
"bd_center.agency_invitation": "{name} mengundang Anda membuat Agency {agency}",
"bd_center.bd_invitation": "{name} mengundang Anda menjadi BD",
"bd_center.role_invitation": "{name} mengirim undangan kepada Anda",
"bd_center.host_invitation_message": "{name} mengundang Anda bergabung ke {agency}.",
"bd_center.agency_invitation_message": "{name} mengundang Anda menjadi pemilik Agency.",
"bd_center.bd_invitation_message": "{name} mengundang Anda menjadi BD.",
"bd_center.invitation_message": "{name} mengirim undangan kepada Anda.",
"bd_center.invitation_accepted": "Undangan diterima.",
"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",
@ -480,5 +526,39 @@
"tasks.loadFailed": "Gagal memuat.",
"tasks.claimSuccess": "Hadiah diklaim.",
"tasks.claimFailed": "Gagal klaim.",
"tasks.noAction": "Aksi belum dikonfigurasi."
"tasks.noAction": "Aksi belum dikonfigurasi.",
"agencyOpening.pageTitle": "Event Pembukaan Agensi Baru",
"agencyOpening.pageLabel": "Event Pembukaan Agensi Baru",
"agencyOpening.heroSubtitle": "Khusus agensi baru",
"agencyOpening.days": "Hari",
"agencyOpening.hours": "Jam",
"agencyOpening.minutes": "Menit",
"agencyOpening.seconds": "Detik",
"agencyOpening.qualificationTitle": "Syarat Pembukaan",
"agencyOpening.agencyIdentity": "Identitas agensi",
"agencyOpening.hostCount": "Jumlah host",
"agencyOpening.openingStatus": "Status pembukaan",
"agencyOpening.apply": "Ajukan Event Pembukaan",
"agencyOpening.eligible": "Memenuhi syarat",
"agencyOpening.notEligible": "Tidak memenuhi syarat",
"agencyOpening.joined": "Sudah bergabung",
"agencyOpening.notJoined": "Belum bergabung",
"agencyOpening.applied": "Sudah diajukan",
"agencyOpening.applySuccess": "Pengajuan terkirim.",
"agencyOpening.applyFailed": "Pengajuan gagal. Coba lagi nanti.",
"agencyOpening.rewardsTitle": "Hadiah Pembukaan",
"agencyOpening.openingRevenue": "Pendapatan pembukaan",
"agencyOpening.rewardCoins": "Coin hadiah",
"agencyOpening.rulesTitle": "Aturan Aktivitas",
"agencyOpening.rule1": "Hanya akun agensi yang dapat mengajukan.",
"agencyOpening.rule2": "Jumlah host harus lebih dari 10.",
"agencyOpening.rule3": "Usia agensi harus kurang dari 7 hari.",
"agencyOpening.rule4": "Setiap agensi hanya dapat ikut sekali seumur hidup.",
"agencyOpening.rule5": "Event Pembukaan tidak dapat berjalan bersama Program Dukungan Agensi.",
"agencyOpening.rule6": "Hadiah dikirim dalam 7 hari setelah peninjauan.",
"agencyOpening.recordTitle": "Catatan Pembukaan",
"agencyOpening.guildName": "Nama guild:",
"agencyOpening.created": "Dibuat:",
"agencyOpening.recordRevenue": "Pendapatan pembukaan:",
"agencyOpening.recordReward": "Hadiah:"
}

View File

@ -135,6 +135,30 @@
"host_center.leave_agency": "Ajanstan ayrıl",
"host_center.leave_confirm_message": "Ajansınızdan ayrılmak istediğinizden emin misiniz?",
"host_center.confirm": "Onayla",
"host_center.open_messages": "Mesajları aç",
"host_center.messages": "Mesajlar",
"host_center.no_messages": "Mesaj yok",
"host_center.loading_messages": "Yükleniyor...",
"host_center.agree": "Kabul et",
"host_center.refuse": "Reddet",
"host_center.processing": "İşleniyor...",
"host_center.host_invitation_title": "Host daveti",
"host_center.agency_invitation_title": "Agency daveti",
"host_center.bd_invitation_title": "BD daveti",
"host_center.invitation_title": "Davet",
"host_center.host_invitation": "{name}, sizi {agency} ajansına katılmaya davet etti",
"host_center.agency_invitation": "{name}, sizi {agency} ajansını oluşturmaya davet etti",
"host_center.bd_invitation": "{name}, sizi BD olmaya davet etti",
"host_center.role_invitation": "{name} size bir davet gönderdi",
"host_center.host_invitation_message": "{name}, sizi {agency} ajansına katılmaya davet etti.",
"host_center.agency_invitation_message": "{name}, sizi Agency sahibi olmaya davet etti.",
"host_center.bd_invitation_message": "{name}, sizi BD olmaya davet etti.",
"host_center.invitation_message": "{name} size bir davet gönderdi.",
"host_center.invitation_accepted": "Davet kabul edildi.",
"host_center.invitation_rejected": "Davet reddedildi.",
"host_center.load_messages_failed": "Mesajlar yüklenemedi.",
"host_center.process_failed": "İşlem başarısız. Daha sonra tekrar deneyin.",
"host_center.process_invitation_failed": "İşlem başarısız. Daha sonra tekrar deneyin.",
"host_center.close": "Kapat",
"host_center.leave_success_mock": "Ajanstan ayrılma isteği gönderildi.",
"host_center.mock_navigation": "Mock yönlendirme: {label}",
@ -260,6 +284,28 @@
"bd_center.invite_failed": "Davet başarısız. Daha sonra tekrar deneyin.",
"bd_center.agency_added": "Ajans eklendi.",
"bd_center.tools": "BD araçları",
"bd_center.messages": "Mesajlar",
"bd_center.no_messages": "Mesaj yok",
"bd_center.loading_messages": "Yükleniyor...",
"bd_center.agree": "Kabul et",
"bd_center.refuse": "Reddet",
"bd_center.processing": "İşleniyor...",
"bd_center.host_invitation_title": "Host daveti",
"bd_center.agency_invitation_title": "Agency daveti",
"bd_center.bd_invitation_title": "BD daveti",
"bd_center.invitation_title": "Davet",
"bd_center.host_invitation": "{name}, sizi {agency} ajansına katılmaya davet etti",
"bd_center.agency_invitation": "{name}, sizi {agency} ajansını oluşturmaya davet etti",
"bd_center.bd_invitation": "{name}, sizi BD olmaya davet etti",
"bd_center.role_invitation": "{name} size bir davet gönderdi",
"bd_center.host_invitation_message": "{name}, sizi {agency} ajansına katılmaya davet etti.",
"bd_center.agency_invitation_message": "{name}, sizi Agency sahibi olmaya davet etti.",
"bd_center.bd_invitation_message": "{name}, sizi BD olmaya davet etti.",
"bd_center.invitation_message": "{name} size bir davet gönderdi.",
"bd_center.invitation_accepted": "Davet kabul edildi.",
"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",
@ -480,5 +526,39 @@
"tasks.loadFailed": "Yükleme başarısız.",
"tasks.claimSuccess": "Ödül alındı.",
"tasks.claimFailed": "Alma başarısız.",
"tasks.noAction": "Eylem yapılandırılmadı."
"tasks.noAction": "Eylem yapılandırılmadı.",
"agencyOpening.pageTitle": "Yeni Ajans Açılış Etkinliği",
"agencyOpening.pageLabel": "Yeni Ajans Açılış Etkinliği",
"agencyOpening.heroSubtitle": "Yeni ajanslara özel",
"agencyOpening.days": "Gün",
"agencyOpening.hours": "Saat",
"agencyOpening.minutes": "Dakika",
"agencyOpening.seconds": "Saniye",
"agencyOpening.qualificationTitle": "Açılış Şartları",
"agencyOpening.agencyIdentity": "Ajans kimliği",
"agencyOpening.hostCount": "Host sayısı",
"agencyOpening.openingStatus": "Açılış durumu",
"agencyOpening.apply": "Açılış etkinliğine başvur",
"agencyOpening.eligible": "Başvuruya uygun",
"agencyOpening.notEligible": "Uygun değil",
"agencyOpening.joined": "Katıldı",
"agencyOpening.notJoined": "Katılmadı",
"agencyOpening.applied": "Başvuruldu",
"agencyOpening.applySuccess": "Başvuru gönderildi.",
"agencyOpening.applyFailed": "Başvuru başarısız. Daha sonra tekrar deneyin.",
"agencyOpening.rewardsTitle": "Açılış Ödülleri",
"agencyOpening.openingRevenue": "Açılış geliri",
"agencyOpening.rewardCoins": "Ödül coinleri",
"agencyOpening.rulesTitle": "Etkinlik Kuralları",
"agencyOpening.rule1": "Yalnızca ajans hesapları başvurabilir.",
"agencyOpening.rule2": "Host sayısı 10'dan fazla olmalıdır.",
"agencyOpening.rule3": "Ajans yaşı 7 günden az olmalıdır.",
"agencyOpening.rule4": "Her ajans ömür boyu yalnızca bir kez katılabilir.",
"agencyOpening.rule5": "Açılış Etkinliği Ajans Destek Programı ile aynı anda çalışamaz.",
"agencyOpening.rule6": "Ödüller incelemeden sonra 7 gün içinde gönderilir.",
"agencyOpening.recordTitle": "Açılış Kaydı",
"agencyOpening.guildName": "Lonca adı:",
"agencyOpening.created": "Oluşturuldu:",
"agencyOpening.recordRevenue": "Açılış geliri:",
"agencyOpening.recordReward": "Ödül:"
}

View File

@ -135,6 +135,30 @@
"host_center.leave_agency": "退出公会",
"host_center.leave_confirm_message": "确定要退出当前公会吗?",
"host_center.confirm": "确认",
"host_center.open_messages": "打开消息",
"host_center.messages": "消息",
"host_center.no_messages": "暂无消息",
"host_center.loading_messages": "加载中...",
"host_center.agree": "同意",
"host_center.refuse": "拒绝",
"host_center.processing": "处理中...",
"host_center.host_invitation_title": "主播邀请",
"host_center.agency_invitation_title": "Agency 邀请",
"host_center.bd_invitation_title": "BD 邀请",
"host_center.invitation_title": "邀请",
"host_center.host_invitation": "{name} 邀请你加入 {agency}",
"host_center.agency_invitation": "{name} 邀请你创建 Agency {agency}",
"host_center.bd_invitation": "{name} 邀请你成为 BD",
"host_center.role_invitation": "{name} 给你发来邀请",
"host_center.host_invitation_message": "{name} 邀请你加入 {agency}。",
"host_center.agency_invitation_message": "{name} 邀请你成为 Agency 负责人。",
"host_center.bd_invitation_message": "{name} 邀请你成为 BD。",
"host_center.invitation_message": "{name} 给你发来邀请。",
"host_center.invitation_accepted": "已同意邀请。",
"host_center.invitation_rejected": "已拒绝邀请。",
"host_center.load_messages_failed": "消息加载失败。",
"host_center.process_failed": "处理失败,请稍后重试。",
"host_center.process_invitation_failed": "处理失败,请稍后重试。",
"host_center.close": "关闭",
"host_center.leave_success_mock": "退出公会申请已提交。",
"host_center.mock_navigation": "Mock 跳转:{label}",
@ -266,6 +290,28 @@
"bd_center.invite_failed": "邀请失败,请稍后重试。",
"bd_center.agency_added": "Agency 已添加。",
"bd_center.tools": "BD 工具",
"bd_center.messages": "消息",
"bd_center.no_messages": "暂无消息",
"bd_center.loading_messages": "加载中...",
"bd_center.agree": "同意",
"bd_center.refuse": "拒绝",
"bd_center.processing": "处理中...",
"bd_center.host_invitation_title": "主播邀请",
"bd_center.agency_invitation_title": "Agency 邀请",
"bd_center.bd_invitation_title": "BD 邀请",
"bd_center.invitation_title": "邀请",
"bd_center.host_invitation": "{name} 邀请你加入 {agency}",
"bd_center.agency_invitation": "{name} 邀请你创建 Agency {agency}",
"bd_center.bd_invitation": "{name} 邀请你成为 BD",
"bd_center.role_invitation": "{name} 给你发来邀请",
"bd_center.host_invitation_message": "{name} 邀请你加入 {agency}。",
"bd_center.agency_invitation_message": "{name} 邀请你成为 Agency 负责人。",
"bd_center.bd_invitation_message": "{name} 邀请你成为 BD。",
"bd_center.invitation_message": "{name} 给你发来邀请。",
"bd_center.invitation_accepted": "已同意邀请。",
"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": "切换语言",
@ -486,5 +532,39 @@
"tasks.loadFailed": "加载失败",
"tasks.claimSuccess": "领取成功",
"tasks.claimFailed": "领取失败",
"tasks.noAction": "未配置跳转"
"tasks.noAction": "未配置跳转",
"agencyOpening.pageTitle": "新代理开业活动",
"agencyOpening.pageLabel": "新代理开业活动",
"agencyOpening.heroSubtitle": "新代理专属",
"agencyOpening.days": "天",
"agencyOpening.hours": "小时",
"agencyOpening.minutes": "分钟",
"agencyOpening.seconds": "秒",
"agencyOpening.qualificationTitle": "开业资格",
"agencyOpening.agencyIdentity": "代理身份",
"agencyOpening.hostCount": "主播数量",
"agencyOpening.openingStatus": "开业状态",
"agencyOpening.apply": "申请开业活动",
"agencyOpening.eligible": "符合申请条件",
"agencyOpening.notEligible": "不符合条件",
"agencyOpening.joined": "已参加",
"agencyOpening.notJoined": "未参加",
"agencyOpening.applied": "已申请",
"agencyOpening.applySuccess": "申请已提交",
"agencyOpening.applyFailed": "申请失败,请稍后再试",
"agencyOpening.rewardsTitle": "开业奖励",
"agencyOpening.openingRevenue": "开业流水",
"agencyOpening.rewardCoins": "奖励金币",
"agencyOpening.rulesTitle": "活动规则",
"agencyOpening.rule1": "只有代理账号可以申请。",
"agencyOpening.rule2": "主播数量必须大于 10。",
"agencyOpening.rule3": "代理创建时间必须小于 7 天。",
"agencyOpening.rule4": "每个代理终身只能参加一次。",
"agencyOpening.rule5": "开业活动不能和代理扶持计划同时进行。",
"agencyOpening.rule6": "奖励会在审核通过后 7 天内发放。",
"agencyOpening.recordTitle": "开业记录",
"agencyOpening.guildName": "公会名称:",
"agencyOpening.created": "创建时间:",
"agencyOpening.recordRevenue": "开业流水:",
"agencyOpening.recordReward": "奖励:"
}

View File

@ -9,6 +9,14 @@
hosts: [],
messages: [],
hostSearch: '',
inviteHost: {
query: '',
status: '',
statusType: '',
searched: [],
inviting: {},
searching: false,
},
pendingRemoveHost: null,
profile: {
loading: true,
@ -317,6 +325,24 @@
};
}
function normalizeInviteProfile(payload, fallbackID) {
var user = payload && (payload.user || payload.profile || payload);
if (!user) return null;
var userId = firstValue(user, ['user_id', 'userId', 'id']);
if (!userId) return null;
var account =
firstValue(user, ['display_user_id', 'displayUserID']) ||
String(fallbackID || userId);
var name = displayName(user, 'User ' + account);
return {
id: String(userId),
userId: String(userId),
name: name,
account: account,
avatar: user.avatar || '',
};
}
function applyPolicy(payload) {
var data = unwrapData(payload);
if (!data || !data.found || !data.policy) {
@ -590,6 +616,159 @@
});
}
function setInviteHostStatus(text, type) {
var node = $('inviteHostStatus');
if (!node) return;
node.textContent = text || '';
node.hidden = !text;
node.classList.toggle('is-error', type === 'error');
node.classList.toggle('is-success', type === 'success');
}
function renderInviteHostSheet() {
var invite = state.inviteHost;
var list = $('inviteHostList');
var empty = $('inviteHostEmpty');
var button = $('inviteHostSearchButton');
if (!list || !empty) return;
list.textContent = '';
setInviteHostStatus(invite.status, invite.statusType);
empty.hidden = invite.searched.length > 0 || Boolean(invite.status);
empty.textContent = t('agency_center.no_users_found', 'No users found');
if (button) {
button.disabled = !invite.query.trim() || invite.searching;
button.textContent = invite.searching
? t('agency_center.searching', 'Searching...')
: t('agency_center.search', 'Search');
}
invite.searched.forEach(function (profile) {
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 action = document.createElement('button');
var targetUserId = profile.userId || profile.id;
card.className = 'message-card';
user.className = 'message-user';
copy.className = 'message-copy';
name.className = 'message-name';
id.className = 'message-id';
action.className = 'message-action agree';
action.type = 'button';
action.disabled = Boolean(invite.inviting[targetUserId]);
name.textContent = profile.name;
id.textContent = 'ID: ' + profile.account;
action.textContent = action.disabled
? t('agency_center.pending', 'Pending')
: t('agency_center.invite', 'Invite');
action.addEventListener('click', function () {
submitHostInvite(profile);
});
user.appendChild(makeAvatar(profile));
copy.appendChild(name);
copy.appendChild(id);
user.appendChild(copy);
card.appendChild(user);
card.appendChild(action);
list.appendChild(card);
});
}
function searchInviteHost(event) {
if (event) event.preventDefault();
var invite = state.inviteHost;
var query = invite.query.trim();
invite.status = '';
invite.statusType = '';
invite.searched = [];
if (!query) {
renderInviteHostSheet();
return;
}
if (!api().user || !api().user.resolveDisplayUserID) {
invite.status = t(
'agency_center.api_not_ready',
'API module is not ready.'
);
invite.statusType = 'error';
renderInviteHostSheet();
return;
}
invite.status = t('agency_center.searching', 'Searching...');
invite.searching = true;
renderInviteHostSheet();
api()
.user.resolveDisplayUserID(query)
.then(function (payload) {
var profile = normalizeInviteProfile(payload, query);
invite.searched = profile ? [profile] : [];
invite.status = profile
? ''
: t('agency_center.no_users_found', 'No users found');
invite.statusType = '';
renderInviteHostSheet();
})
.catch(function (error) {
invite.searched = [];
invite.status =
(error && error.message) ||
t(
'agency_center.search_failed',
'Search failed. Try again later.'
);
invite.statusType = 'error';
renderInviteHostSheet();
})
.finally(function () {
invite.searching = false;
renderInviteHostSheet();
});
}
function submitHostInvite(profile) {
var service = agencyAPI();
var invite = state.inviteHost;
var targetUserId = String(profile.userId || profile.id || '');
if (!targetUserId) return;
if (!service || !service.inviteHost) {
toast(t('agency_center.api_not_ready', 'API module is not ready.'));
return;
}
invite.inviting[targetUserId] = true;
renderInviteHostSheet();
service
.inviteHost({
command_id: commandID('agency-invite-host'),
target_user_id: targetUserId,
})
.then(function () {
invite.status = t(
'agency_center.invite_sent',
'Invite sent. Waiting for confirmation.'
);
invite.statusType = 'success';
invite.searched = [];
$('inviteHostSearchInput').value = '';
invite.query = '';
renderInviteHostSheet();
})
.catch(function (error) {
invite.status =
(error && error.message) ||
t(
'agency_center.invite_failed',
'Invite failed. Try again later.'
);
invite.statusType = 'error';
renderInviteHostSheet();
})
.finally(function () {
delete invite.inviting[targetUserId];
renderInviteHostSheet();
});
}
function processMessage(message, action) {
var service = agencyAPI();
if (!service || !service.reviewApplication) {
@ -951,6 +1130,16 @@
state.hostSearch = $('hostSearchInput').value || '';
renderHostList();
});
$('inviteHostSearchInput').addEventListener('input', function (event) {
state.inviteHost.query = event.target.value || '';
if (!state.inviteHost.query.trim()) {
state.inviteHost.status = '';
state.inviteHost.statusType = '';
state.inviteHost.searched = [];
}
renderInviteHostSheet();
});
$('inviteHostSearchForm').addEventListener('submit', searchInviteHost);
$('confirmRemoveButton').addEventListener('click', confirmRemoveHost);
document
.querySelectorAll('[data-close-sheet]')
@ -985,6 +1174,13 @@
return;
}
if (action === 'invite') {
state.inviteHost.query = '';
state.inviteHost.status = '';
state.inviteHost.statusType = '';
state.inviteHost.searched = [];
state.inviteHost.searching = false;
$('inviteHostSearchInput').value = '';
renderInviteHostSheet();
openSheet('inviteSheet');
}
});
@ -1001,6 +1197,7 @@
renderUnread();
renderHostList();
renderMessages();
renderInviteHostSheet();
renderPolicy();
}

View File

@ -16,7 +16,10 @@
</head>
<body>
<div class="bd-center" aria-label="BD Center">
<div
class="bd-center"
aria-label="BD Center"
>
<div class="hero-bg" aria-hidden="true"></div>
<nav class="title-bar">
@ -100,6 +103,31 @@
aria-label="BD tools"
data-i18n-aria="bd_center.tools"
>
<button
class="menu-row"
id="messageButton"
type="button"
data-action="messages"
data-label="Messages"
>
<span class="menu-icon" aria-hidden="true">
<svg viewBox="0 0 24 24">
<path
d="M4 7a3 3 0 0 1 3-3h10a3 3 0 0 1 3 3v6a3 3 0 0 1-3 3h-5l-5 4v-4a3 3 0 0 1-3-3Z"
/>
<path d="M8 8h8M8 12h5" />
</svg>
</span>
<span class="menu-label" data-i18n="bd_center.messages"
>Messages</span
>
<span
class="message-unread-dot"
id="messageUnreadDot"
hidden
></span>
<span class="chevron" aria-hidden="true"></span>
</button>
<button
class="menu-row"
id="inviteAgentButton"
@ -169,6 +197,44 @@
<div class="home-indicator" aria-hidden="true"></div>
<div
class="message-modal"
id="messageModal"
hidden
aria-hidden="true"
>
<button
class="modal-backdrop"
id="messageBackdrop"
type="button"
aria-label="Close"
data-i18n-aria="bd_center.close"
></button>
<section
class="message-dialog"
role="dialog"
aria-modal="true"
aria-labelledby="messageTitle"
>
<div class="sheet-head">
<h2 id="messageTitle" data-i18n="bd_center.messages">
Messages
</h2>
<button
class="sheet-close"
id="messageCloseButton"
type="button"
aria-label="Close"
data-i18n-aria="bd_center.close"
>
×
</button>
</div>
<div class="message-list" id="messageList"></div>
<div class="sheet-empty" id="messageEmpty" hidden></div>
</section>
</div>
<div
class="invite-modal"
id="inviteModal"

View File

@ -23,6 +23,8 @@
inviteStatusType: '',
searched: [],
inviting: {},
messages: [],
processingMessages: {},
searching: false,
loading: true,
};
@ -550,6 +552,63 @@
].join('-');
}
function normalizeInvitationMessage(item) {
var invitation = (item && item.invitation) || item || {};
var inviter = (item && item.inviter) || {};
var id = String(invitation.invitation_id || invitation.invitationId || '');
var type = firstValue(invitation, [
'invitation_type',
'invitationType',
]);
var agencyName = firstValue(invitation, [
'agency_name',
'agencyName',
]);
var inviterName =
displayName(inviter, '') ||
firstValue(invitation, ['inviter_user_id', 'inviterUserId']) ||
t('bd_center.inviter', 'Inviter');
return {
id: id,
type: type,
name: inviterName,
account:
displayID(inviter, '') ||
firstValue(invitation, ['inviter_user_id', 'inviterUserId']),
avatar: firstValue(inviter, ['avatar']),
title: invitationMessageTitle(type, inviterName, agencyName),
};
}
function invitationMessageTitle(type, inviterName, agencyName) {
if (type === 'host') {
return t(
'bd_center.host_invitation',
'{name} invited you to join {agency}'
)
.replace('{name}', inviterName)
.replace('{agency}', agencyName || t('bd_center.agency', 'Agency'));
}
if (type === 'agency') {
return t(
'bd_center.agency_invitation',
'{name} invited you to create agency {agency}'
)
.replace('{name}', inviterName)
.replace('{agency}', agencyName || t('bd_center.agency', 'Agency'));
}
if (type === 'bd') {
return t(
'bd_center.bd_invitation',
'{name} invited you to become BD'
).replace('{name}', inviterName);
}
return t(
'bd_center.role_invitation',
'{name} sent you an invitation'
).replace('{name}', inviterName);
}
function inviteCard(item) {
var profile = inviteProfile(item);
var status = item.status || '';
@ -625,6 +684,62 @@
!state.inviteQuery.trim() || Boolean(state.searching);
}
function renderUnread() {
var dot = $('messageUnreadDot');
if (dot) dot.hidden = state.messages.length <= 0;
}
function renderMessages() {
var list = $('messageList');
var empty = $('messageEmpty');
if (!list || !empty) return;
list.textContent = '';
empty.hidden = state.messages.length > 0;
empty.textContent = t('bd_center.no_messages', 'No messages');
state.messages.forEach(function (message) {
var card = document.createElement('article');
var avatar = document.createElement('div');
var main = document.createElement('div');
var title = document.createElement('div');
var meta = document.createElement('div');
var side = document.createElement('div');
var agree = document.createElement('button');
var refuse = document.createElement('button');
card.className = 'message-card';
avatar.className = 'message-avatar';
main.className = 'message-main';
title.className = 'message-title';
meta.className = 'message-meta';
side.className = 'message-actions';
agree.className = 'message-action agree';
refuse.className = 'message-action refuse';
agree.type = 'button';
refuse.type = 'button';
agree.disabled = Boolean(state.processingMessages[message.id]);
refuse.disabled = Boolean(state.processingMessages[message.id]);
renderImageAvatar(avatar, message.avatar, message.name, 'message-fallback');
title.textContent = message.title;
meta.textContent = message.account ? 'ID: ' + message.account : '';
agree.textContent = t('bd_center.agree', 'Agree');
refuse.textContent = t('bd_center.refuse', 'Refuse');
agree.addEventListener('click', function () {
processInvitationMessage(message, 'accept');
});
refuse.addEventListener('click', function () {
processInvitationMessage(message, 'reject');
});
main.appendChild(title);
main.appendChild(meta);
side.appendChild(agree);
side.appendChild(refuse);
card.appendChild(avatar);
card.appendChild(main);
card.appendChild(side);
list.appendChild(card);
});
renderUnread();
}
function openInviteModal() {
state.inviteQuery = '';
state.inviteMode = 'records';
@ -724,7 +839,10 @@
});
state.inviteMode = 'records';
state.searched = [];
state.inviteStatus = t('bd_center.agency_added', 'Agency added.');
state.inviteStatus = t(
'bd_center.invitation_submitted',
'Invitation submitted'
);
state.inviteStatusType = 'success';
loadRealData().catch(function () {});
renderInviteModal();
@ -752,6 +870,97 @@
'../withdraw-exchange/index.html?' + params.toString();
}
function loadRoleInvitations() {
if (
!api().roleInvitations ||
!api().roleInvitations.list
) {
state.messages = [];
renderMessages();
return Promise.resolve(false);
}
return api()
.roleInvitations.list('pending', 50)
.then(function (payload) {
var items =
(payload && (payload.items || payload.invitations)) || [];
state.messages = items
.map(normalizeInvitationMessage)
.filter(function (item) {
return !!item.id;
});
renderMessages();
return true;
})
.catch(function () {
state.messages = [];
renderMessages();
return false;
});
}
function processInvitationMessage(message, action) {
if (
!message ||
!message.id ||
!api().roleInvitations ||
!api().roleInvitations.process
) {
return;
}
state.processingMessages[message.id] = true;
renderMessages();
api()
.roleInvitations.process(message.id, {
command_id: commandID('role-invite-' + action, message.id),
action: action,
reason: 'h5_message_center',
})
.then(function () {
state.messages = state.messages.filter(function (item) {
return item.id !== message.id;
});
toast(
t(
action === 'accept'
? 'bd_center.invitation_accepted'
: 'bd_center.invitation_rejected',
action === 'accept'
? 'Invitation accepted.'
: 'Invitation rejected.'
)
);
renderMessages();
return loadRealData();
})
.catch(function (error) {
toast(
(error && error.message) ||
t(
'bd_center.process_failed',
'Process failed. Try again later.'
)
);
})
.finally(function () {
delete state.processingMessages[message.id];
renderMessages();
});
}
function openMessages() {
$('messageModal').hidden = false;
$('messageModal').setAttribute('aria-hidden', 'false');
document.body.classList.add('modal-open');
renderMessages();
}
function closeMessages() {
$('messageModal').hidden = true;
$('messageModal').setAttribute('aria-hidden', 'true');
document.body.classList.remove('modal-open');
}
function setLoading(loading) {
state.loading = Boolean(loading);
render();
@ -805,6 +1014,9 @@
'click',
navigateToWithdrawExchange
);
$('messageButton').addEventListener('click', openMessages);
$('messageBackdrop').addEventListener('click', closeMessages);
$('messageCloseButton').addEventListener('click', closeMessages);
$('inviteAgentButton').addEventListener('click', openInviteModal);
$('inviteBackdrop').addEventListener('click', closeInviteModal);
$('inviteCloseButton').addEventListener('click', closeInviteModal);
@ -834,6 +1046,7 @@
renderBalance();
renderTeamList();
renderInviteModal();
renderMessages();
}
document.addEventListener('DOMContentLoaded', function () {
@ -844,7 +1057,7 @@
(error && error.message) ||
t('bd_center.load_failed', 'Load failed. Try again later.')
);
});
}).finally(loadRoleInvitations);
if (window.HyAppBridge) {
window.HyAppBridge.ready({
page: 'bd-center',
@ -855,4 +1068,8 @@
window.addEventListener('hyapp:i18n-ready', function () {
render();
});
window.addEventListener('hyapp:role-invitation-processed', function () {
loadRealData().catch(function () {});
});
})();

View File

@ -404,6 +404,7 @@ input:focus-visible {
}
.menu-row {
position: relative;
display: grid;
grid-template-columns: 38px minmax(0, 1fr) 24px;
gap: 12px;
@ -413,6 +414,17 @@ input:focus-visible {
text-align: left;
}
.menu-row .message-unread-dot {
position: absolute;
top: 20px;
right: 24px;
width: 9px;
height: 9px;
border: 2px solid #fff;
border-radius: 50%;
background: #ff3b30;
}
.menu-row:last-child {
border-bottom: 0;
}
@ -467,6 +479,24 @@ input:focus-visible {
text-align: right;
}
.message-unread-dot {
position: absolute;
top: 7px;
right: 7px;
width: 9px;
height: 9px;
border: 2px solid #fff;
border-radius: 50%;
background: #ff3b30;
}
.menu-row .message-unread-dot {
position: relative;
top: auto;
right: auto;
flex: 0 0 9px;
}
.sheet-modal,
.message-modal,
.invite-modal {
@ -539,6 +569,137 @@ input:focus-visible {
line-height: 1;
}
.message-dialog {
position: relative;
display: flex;
flex-direction: column;
width: min(394px, 100%);
max-height: 78vh;
max-height: 78dvh;
overflow: hidden;
border-radius: 14px;
background: #fff;
box-shadow: 0 18px 44px rgba(23, 31, 42, 0.2);
}
.message-list {
display: grid;
gap: 10px;
min-height: 0;
overflow-y: auto;
padding: 14px 18px max(18px, env(safe-area-inset-bottom));
-webkit-overflow-scrolling: touch;
}
.sheet-empty {
padding: 24px 18px max(24px, env(safe-area-inset-bottom));
color: var(--muted);
text-align: center;
font-size: 14px;
font-weight: 850;
}
.message-card {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
gap: 10px;
align-items: center;
padding: 12px;
border: 1px solid var(--line);
border-radius: 8px;
background: #fbfcfc;
}
.message-user {
display: flex;
align-items: center;
min-width: 0;
}
.small-avatar,
.message-avatar {
position: relative;
display: flex;
align-items: center;
justify-content: center;
width: 46px;
height: 46px;
flex: 0 0 46px;
overflow: hidden;
border-radius: 50%;
background: var(--primary);
color: var(--primary-deep);
font-size: 18px;
font-weight: 950;
}
.small-avatar img,
.message-avatar img {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: cover;
}
.message-copy {
min-width: 0;
margin-left: 12px;
}
.message-name {
overflow: hidden;
color: var(--text);
font-size: 15px;
font-weight: 950;
line-height: 1.2;
text-overflow: ellipsis;
white-space: nowrap;
}
.message-id {
margin-top: 5px;
overflow: hidden;
color: var(--muted);
font-size: 12px;
font-weight: 800;
line-height: 1.2;
text-overflow: ellipsis;
white-space: nowrap;
}
.message-actions {
display: flex;
gap: 6px;
}
.message-action {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 54px;
min-height: 34px;
padding: 0 10px;
border-radius: 8px;
font-size: 12px;
font-weight: 950;
white-space: nowrap;
}
.message-action:disabled {
opacity: 0.58;
}
.message-action.agree {
background: var(--button);
color: #fff;
}
.message-action.refuse {
background: #f1edf8;
color: var(--text);
}
.home-indicator {
position: absolute;
left: 50%;

View File

@ -13,7 +13,10 @@
</head>
<body>
<div class="host-center" aria-label="Host Center">
<div
class="host-center"
aria-label="Host Center"
>
<div class="hero-bg" aria-hidden="true"></div>
<nav class="title-bar">
@ -123,6 +126,33 @@
</section>
<section class="card menu-card" aria-label="Host tools">
<button
class="menu-row"
id="messageButton"
type="button"
data-action="messages"
data-label="Messages"
>
<span class="menu-icon" aria-hidden="true">
<svg viewBox="0 0 24 24">
<path
d="M4 7a3 3 0 0 1 3-3h10a3 3 0 0 1 3 3v6a3 3 0 0 1-3 3h-5l-5 4v-4a3 3 0 0 1-3-3Z"
/>
<path d="M8 8h8M8 12h5" />
</svg>
</span>
<span
class="menu-label"
data-i18n="host_center.messages"
>Messages</span
>
<span
class="message-unread-dot"
id="messageUnreadDot"
hidden
></span>
<span class="chevron" aria-hidden="true"></span>
</button>
<button
class="menu-row"
type="button"
@ -194,6 +224,44 @@
</section>
</div>
<div
class="message-modal"
id="messageModal"
hidden
aria-hidden="true"
>
<button
class="modal-backdrop"
id="messageBackdrop"
type="button"
aria-label="Close"
data-i18n-aria="host_center.close"
></button>
<section
class="message-dialog"
role="dialog"
aria-modal="true"
aria-labelledby="messageTitle"
>
<div class="sheet-head">
<h2 id="messageTitle" data-i18n="host_center.messages">
Messages
</h2>
<button
class="sheet-close"
id="messageCloseButton"
type="button"
aria-label="Close"
data-i18n-aria="host_center.close"
>
&times;
</button>
</div>
<div class="message-list" id="messageList"></div>
<div class="sheet-empty" id="messageEmpty" hidden></div>
</section>
</div>
<div class="home-indicator" aria-hidden="true"></div>
</div>

View File

@ -46,6 +46,8 @@
found: false,
policy: null,
},
messages: [],
processingMessages: {},
};
}
@ -208,6 +210,146 @@
}
}
function commandID(prefix, id) {
return [
prefix,
id || '0',
Date.now(),
Math.random().toString(16).slice(2),
].join('-');
}
function normalizeInvitationMessage(item) {
var invitation = (item && item.invitation) || item || {};
var inviter = (item && item.inviter) || {};
var id = String(invitation.invitation_id || invitation.invitationId || '');
var type = firstValue(invitation, [
'invitation_type',
'invitationType',
]);
var agencyName = firstValue(invitation, [
'agency_name',
'agencyName',
]);
var inviterName =
firstValue(inviter, ['username', 'name', 'display_user_id']) ||
firstValue(invitation, ['inviter_user_id', 'inviterUserId']) ||
t('host_center.inviter', 'Inviter');
return {
id: id,
type: type,
name: inviterName,
account:
firstValue(inviter, ['display_user_id', 'displayUserID']) ||
firstValue(inviter, ['user_id', 'userId']) ||
firstValue(invitation, ['inviter_user_id', 'inviterUserId']),
avatar: firstValue(inviter, ['avatar']),
title: invitationMessageTitle(type, inviterName, agencyName),
};
}
function invitationMessageTitle(type, inviterName, agencyName) {
if (type === 'host') {
return t(
'host_center.host_invitation',
'{name} invited you to join {agency}'
)
.replace('{name}', inviterName)
.replace('{agency}', agencyName || t('host_center.agency', 'Agency'));
}
if (type === 'agency') {
return t(
'host_center.agency_invitation',
'{name} invited you to create agency {agency}'
)
.replace('{name}', inviterName)
.replace('{agency}', agencyName || t('host_center.agency', 'Agency'));
}
if (type === 'bd') {
return t(
'host_center.bd_invitation',
'{name} invited you to become BD'
).replace('{name}', inviterName);
}
return t(
'host_center.role_invitation',
'{name} sent you an invitation'
).replace('{name}', inviterName);
}
function renderUnread() {
var dot = $('messageUnreadDot');
if (dot) dot.hidden = state.messages.length <= 0;
}
function createMessageAvatar(message) {
var avatar = document.createElement('div');
avatar.className = 'message-avatar';
if (!message.avatar) {
avatar.textContent = initial(message.name || 'M') || 'M';
return avatar;
}
var img = document.createElement('img');
img.src = message.avatar;
img.alt = '';
img.addEventListener('error', function () {
avatar.textContent = initial(message.name || 'M') || 'M';
});
avatar.appendChild(img);
return avatar;
}
function renderMessages() {
var list = $('messageList');
var empty = $('messageEmpty');
if (!list || !empty) return;
list.textContent = '';
empty.hidden = state.messages.length > 0;
empty.textContent = t('host_center.no_messages', 'No messages');
state.messages.forEach(function (message) {
var card = document.createElement('article');
var user = document.createElement('div');
var copy = document.createElement('div');
var title = document.createElement('div');
var meta = 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';
title.className = 'message-name';
meta.className = 'message-id';
actions.className = 'message-actions';
agree.className = 'message-action agree';
refuse.className = 'message-action refuse';
agree.type = 'button';
refuse.type = 'button';
agree.disabled = Boolean(state.processingMessages[message.id]);
refuse.disabled = Boolean(state.processingMessages[message.id]);
title.textContent = message.title;
meta.textContent = message.account ? 'ID: ' + message.account : '';
agree.textContent = t('host_center.agree', 'Agree');
refuse.textContent = t('host_center.refuse', 'Refuse');
agree.addEventListener('click', function () {
processInvitationMessage(message, 'accept');
});
refuse.addEventListener('click', function () {
processInvitationMessage(message, 'reject');
});
user.appendChild(createMessageAvatar(message));
copy.appendChild(title);
copy.appendChild(meta);
user.appendChild(copy);
actions.appendChild(agree);
actions.appendChild(refuse);
card.appendChild(user);
card.appendChild(actions);
list.appendChild(card);
});
renderUnread();
}
function policyAmount(minor) {
return '$' + money(toNumber(minor) / 100);
}
@ -510,6 +652,7 @@
renderIncome();
renderLevel();
renderPolicy();
renderMessages();
}
function applyProfile(payload) {
@ -716,6 +859,107 @@
});
}
function loadRoleInvitations() {
if (
!window.HyAppAPI ||
!window.HyAppAPI.roleInvitations ||
!window.HyAppAPI.roleInvitations.list ||
!hasAccessToken()
) {
state.messages = [];
renderMessages();
return Promise.resolve(false);
}
return window.HyAppAPI.roleInvitations
.list('pending', 50)
.then(function (payload) {
var items =
(payload && (payload.items || payload.invitations)) || [];
state.messages = items
.map(normalizeInvitationMessage)
.filter(function (item) {
return !!item.id;
});
renderMessages();
return true;
})
.catch(function (error) {
if (window.console && window.console.warn) {
window.console.warn('[host-center] messages failed', error);
}
state.messages = [];
renderMessages();
return false;
});
}
function processInvitationMessage(message, action) {
if (
!message ||
!message.id ||
!window.HyAppAPI ||
!window.HyAppAPI.roleInvitations ||
!window.HyAppAPI.roleInvitations.process
) {
return;
}
state.processingMessages[message.id] = true;
renderMessages();
window.HyAppAPI.roleInvitations
.process(message.id, {
command_id: commandID('role-invite-' + action, message.id),
action: action,
reason: 'h5_message_center',
})
.then(function () {
state.messages = state.messages.filter(function (item) {
return item.id !== message.id;
});
toast(
t(
action === 'accept'
? 'host_center.invitation_accepted'
: 'host_center.invitation_rejected',
action === 'accept'
? 'Invitation accepted.'
: 'Invitation rejected.'
)
);
renderMessages();
return loadRealData();
})
.catch(function (error) {
toast(
(error && error.message) ||
t(
'host_center.process_failed',
'Process failed. Try again later.'
)
);
})
.finally(function () {
delete state.processingMessages[message.id];
renderMessages();
});
}
function openMessages() {
var modal = $('messageModal');
if (!modal) return;
renderMessages();
modal.hidden = false;
modal.setAttribute('aria-hidden', 'false');
document.body.classList.add('modal-open');
}
function closeMessages() {
var modal = $('messageModal');
if (!modal) return;
modal.hidden = true;
modal.setAttribute('aria-hidden', 'true');
document.body.classList.remove('modal-open');
}
function requestPolicy() {
if (!window.HyAppAPI || !window.HyAppAPI.hostCenter) {
return Promise.resolve(null);
@ -808,11 +1052,21 @@
document.querySelectorAll('[data-action="policy"]').forEach(function (button) {
button.addEventListener('click', openPolicy);
});
document
.querySelectorAll('[data-action="messages"]')
.forEach(function (button) {
button.addEventListener('click', openMessages);
});
document.querySelectorAll('[data-close-policy]').forEach(function (button) {
button.addEventListener('click', closePolicy);
});
$('messageBackdrop').addEventListener('click', closeMessages);
$('messageCloseButton').addEventListener('click', closeMessages);
document.addEventListener('keydown', function (event) {
if (event.key === 'Escape') closePolicy();
if (event.key === 'Escape') {
closePolicy();
closeMessages();
}
});
}
@ -824,6 +1078,7 @@
render();
bindEvents();
loadRealData().then(function (loaded) {
loadRoleInvitations();
if (window.HyAppBridge) {
window.HyAppBridge.ready({
page: 'host-center',
@ -842,4 +1097,8 @@
window.addEventListener('hyapp:i18n-ready', function () {
render();
});
window.addEventListener('hyapp:role-invitation-processed', function () {
loadRealData();
});
})();

View File

@ -90,6 +90,25 @@
<span>Agency</span>
</button>
</div>
<button
class="message-button"
id="messageButton"
type="button"
aria-label="Open messages"
data-i18n-aria="host_center.open_messages"
>
<svg viewBox="0 0 28 28" aria-hidden="true">
<path
d="M5 8.5A3.5 3.5 0 0 1 8.5 5h11A3.5 3.5 0 0 1 23 8.5v7A3.5 3.5 0 0 1 19.5 19H12l-5 4v-4.5A3.5 3.5 0 0 1 5 15.3Z"
/>
<path d="M9 10h10M9 14h6" />
</svg>
<span
class="message-unread-dot"
id="messageUnreadDot"
hidden
></span>
</button>
</section>
<section
@ -204,6 +223,44 @@
</div>
</section>
</div>
<div
class="message-modal"
id="messageModal"
hidden
aria-hidden="true"
>
<button
class="modal-backdrop"
id="messageBackdrop"
type="button"
aria-label="Close"
data-i18n-aria="host_center.close"
></button>
<section
class="message-dialog"
role="dialog"
aria-modal="true"
aria-labelledby="messageTitle"
>
<div class="sheet-head">
<h2 id="messageTitle" data-i18n="host_center.messages">
Messages
</h2>
<button
class="sheet-close"
id="messageCloseButton"
type="button"
aria-label="Close"
data-i18n-aria="host_center.close"
>
&times;
</button>
</div>
<div class="message-list" id="messageList"></div>
<div class="sheet-empty" id="messageEmpty" hidden></div>
</section>
</div>
</div>
<script src="../../common/api.js"></script>
<script src="../../common/toast.js"></script>

View File

@ -1,6 +1,8 @@
(function () {
var selectedAgency = null;
var agencies = [];
var messages = [];
var processingMessages = {};
var isSearching = false;
var isApplying = false;
@ -163,6 +165,251 @@
avatar.appendChild(span);
}
function commandID(prefix, id) {
return [
prefix,
id || '0',
Date.now(),
Math.random().toString(16).slice(2),
].join('-');
}
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 normalizeInvitationMessage(item) {
var invitation = (item && item.invitation) || item || {};
var inviter = (item && item.inviter) || {};
var id = String(invitation.invitation_id || invitation.invitationId || '');
var type = firstValue(invitation, [
'invitation_type',
'invitationType',
]);
var agencyName = firstValue(invitation, [
'agency_name',
'agencyName',
]);
var inviterName =
firstValue(inviter, ['username', 'name', 'display_user_id']) ||
firstValue(invitation, ['inviter_user_id', 'inviterUserId']) ||
t('host_center.inviter', 'Inviter');
var account =
firstValue(inviter, ['display_user_id', 'displayUserID']) ||
firstValue(inviter, ['user_id', 'userId']) ||
firstValue(invitation, ['inviter_user_id', 'inviterUserId']);
return {
id: id,
type: type,
name: inviterName,
account: account,
avatar: firstValue(inviter, ['avatar']),
agencyName: agencyName,
title: invitationMessageTitle(type, inviterName, agencyName),
};
}
function invitationMessageTitle(type, inviterName, agencyName) {
if (type === 'host') {
return t(
'host_center.host_invitation',
'{name} invited you to join {agency}'
)
.replace('{name}', inviterName)
.replace('{agency}', agencyName || t('host_center.agency', 'Agency'));
}
if (type === 'agency') {
return t(
'host_center.agency_invitation',
'{name} invited you to create agency {agency}'
)
.replace('{name}', inviterName)
.replace('{agency}', agencyName || t('host_center.agency', 'Agency'));
}
if (type === 'bd') {
return t(
'host_center.bd_invitation',
'{name} invited you to become BD'
).replace('{name}', inviterName);
}
return t(
'host_center.role_invitation',
'{name} sent you an invitation'
).replace('{name}', inviterName);
}
function renderUnread() {
var dot = $('messageUnreadDot');
if (dot) dot.hidden = messages.length <= 0;
}
function createMessageAvatar(message) {
var avatar = document.createElement('div');
avatar.className = 'message-avatar';
if (!message.avatar) {
avatar.textContent =
String(message.name || 'M').trim().charAt(0).toUpperCase() ||
'M';
return avatar;
}
var img = document.createElement('img');
img.src = message.avatar;
img.alt = '';
img.addEventListener('error', function () {
avatar.textContent =
String(message.name || 'M').trim().charAt(0).toUpperCase() ||
'M';
});
avatar.appendChild(img);
return avatar;
}
function renderMessages() {
var list = $('messageList');
var empty = $('messageEmpty');
if (!list || !empty) return;
list.textContent = '';
empty.hidden = messages.length > 0;
empty.textContent = t('host_center.no_messages', 'No messages');
messages.forEach(function (message) {
var card = document.createElement('article');
var user = document.createElement('div');
var copy = document.createElement('div');
var title = document.createElement('div');
var meta = 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';
title.className = 'message-name';
meta.className = 'message-id';
actions.className = 'message-actions';
agree.className = 'message-action agree';
refuse.className = 'message-action refuse';
agree.type = 'button';
refuse.type = 'button';
agree.disabled = Boolean(processingMessages[message.id]);
refuse.disabled = Boolean(processingMessages[message.id]);
title.textContent = message.title;
meta.textContent = message.account ? 'ID: ' + message.account : '';
agree.textContent = t('host_center.agree', 'Agree');
refuse.textContent = t('host_center.refuse', 'Refuse');
agree.addEventListener('click', function () {
processInvitationMessage(message, 'accept');
});
refuse.addEventListener('click', function () {
processInvitationMessage(message, 'reject');
});
user.appendChild(createMessageAvatar(message));
copy.appendChild(title);
copy.appendChild(meta);
user.appendChild(copy);
actions.appendChild(agree);
actions.appendChild(refuse);
card.appendChild(user);
card.appendChild(actions);
list.appendChild(card);
});
renderUnread();
}
function loadRoleInvitations() {
if (
!window.HyAppAPI ||
!window.HyAppAPI.roleInvitations ||
!window.HyAppAPI.roleInvitations.list
) {
return Promise.resolve(false);
}
return window.HyAppAPI.roleInvitations
.list('pending', 50)
.then(function (payload) {
var items = (payload && (payload.items || payload.invitations)) || [];
messages = items.map(normalizeInvitationMessage).filter(function (item) {
return !!item.id;
});
renderMessages();
return true;
})
.catch(function () {
messages = [];
renderMessages();
return false;
});
}
function processInvitationMessage(message, action) {
if (
!message ||
!message.id ||
!window.HyAppAPI ||
!window.HyAppAPI.roleInvitations ||
!window.HyAppAPI.roleInvitations.process
) {
return;
}
processingMessages[message.id] = true;
renderMessages();
window.HyAppAPI.roleInvitations
.process(message.id, {
command_id: commandID('role-invite-' + action, message.id),
action: action,
reason: 'h5_message_center',
})
.then(function () {
messages = messages.filter(function (item) {
return item.id !== message.id;
});
renderMessages();
setStatus(
action === 'accept'
? 'host_center.invitation_accepted'
: 'host_center.invitation_rejected',
'success'
);
})
.catch(function (error) {
setStatusMessage(
(error && error.message) ||
t(
'host_center.process_failed',
'Process failed. Try again later.'
),
'error'
);
})
.finally(function () {
delete processingMessages[message.id];
renderMessages();
});
}
function openMessages() {
var modal = $('messageModal');
if (!modal) return;
renderMessages();
modal.hidden = false;
modal.setAttribute('aria-hidden', 'false');
document.body.classList.add('daily-modal-open');
}
function closeMessages() {
var modal = $('messageModal');
if (!modal) return;
modal.hidden = true;
modal.setAttribute('aria-hidden', 'true');
document.body.classList.remove('daily-modal-open');
}
function createAgencyAvatar(agency) {
var avatar = document.createElement('div');
var name = agencyName(agency) || t('host_center.agency', 'Agency');
@ -366,6 +613,13 @@
if (cancel) cancel.addEventListener('click', closeJoinConfirm);
var backdrop = $('joinConfirmBackdrop');
if (backdrop) backdrop.addEventListener('click', closeJoinConfirm);
var messageButton = $('messageButton');
if (messageButton) messageButton.addEventListener('click', openMessages);
var messageClose = $('messageCloseButton');
if (messageClose) messageClose.addEventListener('click', closeMessages);
var messageBackdrop = $('messageBackdrop');
if (messageBackdrop)
messageBackdrop.addEventListener('click', closeMessages);
var backButton = $('backButton');
if (backButton) {
backButton.addEventListener('click', function () {
@ -373,12 +627,14 @@
});
}
searchAgency();
loadRoleInvitations();
}
window.addEventListener('hyapp:i18n-ready', function () {
var searching = isSearching;
setSearching(searching);
if (!searching) renderAgencyList(agencies);
renderMessages();
if (selectedAgency) updateConfirmMessage();
setConfirmApplying(isApplying);
});

View File

@ -385,6 +385,44 @@ a {
margin-left: 20px;
}
.message-button {
position: relative;
display: flex;
align-items: center;
justify-content: center;
width: 42px;
height: 42px;
flex: 0 0 42px;
margin-left: auto;
border-radius: 50%;
background: var(--hy-theme-primary-soft, #f4ebff);
color: var(--hy-theme-primary-deep, #7d57c7);
}
.message-button svg {
width: 25px;
height: 25px;
}
.message-button path {
fill: none;
stroke: currentColor;
stroke-linecap: round;
stroke-linejoin: round;
stroke-width: 2.2;
}
.message-unread-dot {
position: absolute;
top: 7px;
right: 7px;
width: 9px;
height: 9px;
border: 2px solid #fff;
border-radius: 50%;
background: #ff3b30;
}
.name {
color: var(--hy-theme-text, #282333);
font-size: 20px;
@ -1469,6 +1507,185 @@ a {
opacity: 0.58;
}
.message-modal {
position: fixed;
z-index: 24;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
padding: 18px;
}
.modal-backdrop {
position: absolute;
inset: 0;
background: rgba(15, 21, 28, 0.38);
}
.message-dialog {
position: relative;
display: flex;
flex-direction: column;
width: min(394px, 100%);
max-height: 78vh;
max-height: 78dvh;
overflow: hidden;
border-radius: 14px;
background: #fff;
box-shadow: 0 18px 44px rgba(23, 31, 42, 0.2);
}
.sheet-head {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
min-height: 58px;
padding: 16px 18px 12px;
border-bottom: 1px solid var(--hy-theme-line, #eee7f8);
}
.sheet-head h2 {
margin: 0;
color: var(--hy-theme-text, #282333);
font-size: 18px;
font-weight: 950;
line-height: 1.2;
}
.sheet-close {
display: flex;
align-items: center;
justify-content: center;
width: 34px;
height: 34px;
border-radius: 50%;
background: var(--hy-theme-primary-soft, #f4ebff);
color: var(--hy-theme-primary-deep, #7d57c7);
font-size: 25px;
font-weight: 500;
line-height: 1;
}
.message-list {
display: grid;
gap: 10px;
min-height: 0;
overflow-y: auto;
padding: 14px 18px max(18px, env(safe-area-inset-bottom));
-webkit-overflow-scrolling: touch;
}
.sheet-empty {
padding: 24px 18px max(24px, env(safe-area-inset-bottom));
color: var(--hy-theme-muted, #8d879a);
text-align: center;
font-size: 14px;
font-weight: 850;
}
.message-card {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
gap: 10px;
align-items: center;
padding: 12px;
border: 1px solid var(--hy-theme-line, #eee7f8);
border-radius: 8px;
background: #fbfcfc;
}
.message-user {
display: flex;
align-items: center;
min-width: 0;
}
.small-avatar,
.message-avatar {
position: relative;
display: flex;
align-items: center;
justify-content: center;
width: 46px;
height: 46px;
flex: 0 0 46px;
overflow: hidden;
border-radius: 50%;
background: var(--hy-theme-primary, #dbc8ff);
color: var(--hy-theme-primary-deep, #7d57c7);
font-size: 18px;
font-weight: 950;
}
.small-avatar img,
.message-avatar img {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: cover;
}
.message-copy {
min-width: 0;
margin-left: 12px;
}
.message-name {
overflow: hidden;
color: var(--hy-theme-text, #282333);
font-size: 15px;
font-weight: 950;
line-height: 1.2;
text-overflow: ellipsis;
white-space: nowrap;
}
.message-id {
margin-top: 5px;
overflow: hidden;
color: var(--hy-theme-muted, #8d879a);
font-size: 12px;
font-weight: 800;
line-height: 1.2;
text-overflow: ellipsis;
white-space: nowrap;
}
.message-actions {
display: flex;
gap: 6px;
}
.message-action {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 54px;
min-height: 34px;
padding: 0 10px;
border-radius: 8px;
font-size: 12px;
font-weight: 950;
white-space: nowrap;
}
.message-action:disabled {
opacity: 0.58;
}
.message-action.agree {
background: var(--hy-theme-button, #7d57c7);
color: #fff;
}
.message-action.refuse {
background: #f1edf8;
color: var(--hy-theme-text, #282333);
}
.daily-modal-open {
overflow: hidden;
}