diff --git a/common/api.js b/common/api.js index 826057c..2781d6c 100644 --- a/common/api.js +++ b/common/api.js @@ -218,7 +218,38 @@ var default_api = 'https://api.global-interaction.com/'; }, }; - var hostAPI = { + var userAPI = { + me: function () { + return request('/api/v1/users/me', { method: 'GET' }); + }, + overview: function () { + return request('/api/v1/users/me/overview', { method: 'GET' }); + }, + hostIdentity: function () { + return request('/api/v1/users/me/host-identity', { + method: 'GET', + }); + }, + roleSummary: function () { + return request('/api/v1/users/me/role-summary', { + method: 'GET', + }); + }, + }; + + var walletAPI = { + balances: function (assetTypes) { + var value = Array.isArray(assetTypes) + ? assetTypes.join(',') + : assetTypes; + return request('/api/v1/wallet/me/balances', { + method: 'GET', + query: { asset_type: value }, + }); + }, + }; + + var hostAPI = { searchAgencies: function (shortId, pageSize) { return request('/api/v1/host/agencies/search', { method: 'GET', @@ -230,25 +261,69 @@ var default_api = 'https://api.global-interaction.com/'; method: 'POST', body: payload || {}, }); - }, - }; + }, + }; - var levelAPI = { - overview: function () { - return request("/api/v1/levels/me/overview", { method: "GET" }); - }, - track: function (track) { - return request("/api/v1/levels/tracks/" + encodeURIComponent(track || ""), { - method: "GET", - }); - }, - rewards: function (query) { - return request("/api/v1/levels/rewards", { - method: "GET", - query: query || {}, - }); - }, - }; + var agencyCenterAPI = { + overview: function () { + return request('/api/v1/agency-center/overview', { + method: 'GET', + }); + }, + hosts: function () { + return request('/api/v1/agency-center/hosts', { + method: 'GET', + }); + }, + applications: function (status) { + return request('/api/v1/agency-center/applications', { + method: 'GET', + query: { status: status || 'pending' }, + }); + }, + reviewApplication: function (applicationId, payload) { + return request( + '/api/v1/agency-center/applications/' + + encodeURIComponent(applicationId || '') + + '/review', + { + method: 'POST', + body: payload || {}, + } + ); + }, + removeHost: function (hostUserId, payload) { + return request( + '/api/v1/agency-center/hosts/' + + encodeURIComponent(hostUserId || '') + + '/remove', + { + method: 'POST', + body: payload || {}, + } + ); + }, + }; + + var levelAPI = { + overview: function () { + return request('/api/v1/levels/me/overview', { method: 'GET' }); + }, + track: function (track) { + return request( + '/api/v1/levels/tracks/' + encodeURIComponent(track || ''), + { + method: 'GET', + } + ); + }, + rewards: function (query) { + return request('/api/v1/levels/rewards', { + method: 'GET', + query: query || {}, + }); + }, + }; window.HyAppAPI = { baseURL: resolveBaseURL, @@ -272,10 +347,13 @@ var default_api = 'https://api.global-interaction.com/'; }, delete: function (path, query) { return request(path, { method: 'DELETE', query: query }); - }, - vip: vipAPI, - host: hostAPI, - level: levelAPI, - }; + }, + vip: vipAPI, + user: userAPI, + wallet: walletAPI, + host: hostAPI, + agencyCenter: agencyCenterAPI, + level: levelAPI, + }; clearLocalDevCache(); })(); diff --git a/common/i18n.js b/common/i18n.js index b6d88f0..0e3f9c8 100644 --- a/common/i18n.js +++ b/common/i18n.js @@ -1,7 +1,7 @@ (function () { var STORAGE_KEY = 'hyapp_h5_lang'; var DEFAULT_LANG = 'en'; - var SUPPORTED = ['en', 'ar', 'tr', 'es']; + var SUPPORTED = ['en', 'ar', 'tr', 'es', 'zh', 'id']; var scriptURL = document.currentScript && document.currentScript.src ? document.currentScript.src @@ -23,6 +23,8 @@ if (lang.indexOf('ar') === 0) return 'ar'; if (lang.indexOf('tr') === 0) return 'tr'; if (lang.indexOf('es') === 0) return 'es'; + if (lang.indexOf('zh') === 0) return 'zh'; + if (lang.indexOf('id') === 0) return 'id'; return SUPPORTED.indexOf(lang) >= 0 ? lang : ''; } @@ -165,8 +167,14 @@ supported: SUPPORTED.slice(), }; - document.addEventListener('DOMContentLoaded', function () { + function init() { initLanguageMenu(); load(resolveLang()); - }); + } + + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', init); + } else { + init(); + } })(); diff --git a/common/locales/ar.json b/common/locales/ar.json index 84377dd..b89225b 100644 --- a/common/locales/ar.json +++ b/common/locales/ar.json @@ -18,6 +18,7 @@ "host_center.loading_agencies": "جار تحميل الوكالات...", "host_center.no_agency": "لم يتم العثور على وكالة في بلدك.", "host_center.search_failed": "فشل البحث. حاول لاحقا.", + "host_center.load_failed": "فشل التحميل. حاول لاحقا.", "host_center.apply_failed": "فشل إرسال الطلب. حاول لاحقا.", "host_center.apply_success": "تم إرسال الطلب.", "host_center.applying": "جار الإرسال...", @@ -26,5 +27,161 @@ "host_center.join": "انضم", "host_center.cancel": "إلغاء", "host_center.join_confirm_title": "انضم إلى وكالة", - "host_center.join_confirm_message": "هل أنت متأكد أنك تريد الانضمام إلى {agency}؟" + "host_center.join_confirm_message": "هل أنت متأكد أنك تريد الانضمام إلى {agency}؟", + "host_center.verified_host": "مضيف موثق", + "host_center.agency_short_id": "رقم الوكالة: {id}", + "host_center.my_agency": "وكالتي", + "host_center.leave": "مغادرة", + "host_center.available_salary": "راتبي المتاح", + "host_center.salary_details": "تفاصيل الراتب", + "host_center.salary_month_note": "تسوية {month} · {currency}", + "host_center.todays_task": "مهمة اليوم", + "host_center.anchor_type": "نوع المضيف", + "host_center.minutes": "الدقائق", + "host_center.gift_task": "مهمة الهدايا", + "host_center.in_progress": "قيد التنفيذ", + "host_center.level_progress": "تقدم المستوى", + "host_center.current_level": "المستوى الحالي", + "host_center.next_level_need": "المطلوب للمستوى التالي", + "host_center.level_value": "المستوى {level}", + "host_center.platform_policy": "سياسة المنصة", + "host_center.exchange_coins": "تبديل العملات", + "host_center.withdraw_exchange": "السحب/التبديل", + "host_center.transfer": "تحويل", + "host_center.cash_withdraw": "سحب نقدي", + "host_center.bank_accounts": "الحسابات البنكية", + "host_center.leave_agency": "مغادرة الوكالة", + "host_center.leave_confirm_message": "هل أنت متأكد أنك تريد مغادرة وكالتك؟", + "host_center.confirm": "تأكيد", + "host_center.close": "إغلاق", + "host_center.leave_success_mock": "تم إرسال طلب مغادرة الوكالة.", + "host_center.mock_navigation": "انتقال تجريبي: {label}", + "host_center.live_salary": "راتب البث", + "host_center.gift_reward": "مكافأة الهدايا", + "host_center.bonus": "مكافأة", + "host_center.month_june": "يونيو", + "host_center.currency_coins": "عملات", + "withdraw_exchange.page_label": "السحب والتبديل", + "withdraw_exchange.back": "رجوع", + "withdraw_exchange.title": "السحب/التبديل", + "withdraw_exchange.change_language": "تغيير اللغة", + "withdraw_exchange.mode_tabs": "السحب أو التبديل أو التحويل", + "withdraw_exchange.salary": "الراتب", + "withdraw_exchange.salary_history": "سجل الراتب", + "withdraw_exchange.withdraw": "سحب", + "withdraw_exchange.exchange": "تبديل", + "withdraw_exchange.transfer": "تحويل", + "withdraw_exchange.withdraw_amount": "مبلغ السحب", + "withdraw_exchange.exchange_amount": "مبلغ التبديل", + "withdraw_exchange.transfer_to": "تحويل إلى", + "withdraw_exchange.transfer_amount": "مبلغ التحويل", + "withdraw_exchange.search": "بحث", + "withdraw_exchange.searching": "جار البحث...", + "withdraw_exchange.minimum": "الحد الأدنى 50 USD", + "withdraw_exchange.all": "الكل", + "withdraw_exchange.exchange_rate": "سعر التبديل", + "withdraw_exchange.exchange_rate_value": "1$ = {amount} عملة", + "withdraw_exchange.payment_method": "عنوان USDT TRC20", + "withdraw_exchange.payment_method_subtitle": "يتم إرسال السحوبات إلى عنوان USDT TRC20 الخاص بك.", + "withdraw_exchange.no_payment_info": "لا يوجد عنوان USDT", + "withdraw_exchange.no_payment_info_copy": "أدخل عنوان USDT TRC20 قبل السحب.", + "withdraw_exchange.trc20_address": "عنوان TRC20", + "withdraw_exchange.save_address": "حفظ العنوان", + "withdraw_exchange.saving": "جار الحفظ...", + "withdraw_exchange.usdt_only": "USDT فقط", + "withdraw_exchange.withdraw_now": "اسحب الآن", + "withdraw_exchange.exchange_now": "بدّل الآن", + "withdraw_exchange.transfer_now": "حوّل الآن", + "withdraw_exchange.submitting": "جار الإرسال...", + "withdraw_exchange.payee": "المستلم", + "withdraw_exchange.uid_prefix": "UID:", + "withdraw_exchange.close": "إغلاق", + "withdraw_exchange.loading": "جار التحميل...", + "withdraw_exchange.no_salary_history": "لا يوجد سجل راتب", + "withdraw_exchange.balance": "الرصيد", + "withdraw_exchange.history_host_salary": "راتب المضيف", + "withdraw_exchange.history_exchange_to_golds": "تبديل إلى عملات", + "withdraw_exchange.history_gift_reward": "مكافأة الهدايا", + "withdraw_exchange.mock_user_name": "المستخدم {account}", + "withdraw_exchange.missing_payment_info": "يرجى إضافة عنوان USDT TRC20", + "withdraw_exchange.invalid_address": "يرجى إدخال عنوان USDT TRC20 صالح", + "withdraw_exchange.invalid_amount": "يرجى إدخال مبلغ صالح", + "withdraw_exchange.amount_too_low": "الحد الأدنى لمبلغ السحب هو 50 USD", + "withdraw_exchange.amount_exceeds_balance": "المبلغ يتجاوز الراتب", + "withdraw_exchange.payee_not_found": "لم يتم العثور على المستخدم", + "withdraw_exchange.missing_payee": "يرجى البحث عن مستخدم واختياره", + "withdraw_exchange.address_saved": "تم حفظ العنوان", + "withdraw_exchange.withdraw_success": "تم إرسال طلب السحب", + "withdraw_exchange.exchange_success": "تم التبديل بنجاح", + "withdraw_exchange.transfer_success": "تم التحويل بنجاح", + "bd_center.back": "رجوع", + "bd_center.title": "مركز BD", + "bd_center.change_language": "تغيير اللغة", + "bd_center.role": "BD", + "bd_center.salary": "الراتب", + "bd_center.withdraw_exchange": "Withdraw/Exchange", + "bd_center.invite_agent": "دعوة وكيل", + "bd_center.agency_list": "قائمة الوكالات", + "bd_center.agency_statistics": "إحصائيات الوكالات", + "bd_center.month": "الشهر", + "bd_center.agency_number": "عدد الوكالات", + "bd_center.team_salary": "راتب الفريق", + "bd_center.team_recharge": "شحن الفريق", + "bd_center.recharge": "الشحن", + "bd_center.host": "مضيف", + "bd_center.no_data": "لا توجد بيانات", + "bd_center.enter_user_id": "أدخل معرف المستخدم", + "bd_center.search": "بحث", + "bd_center.no_users_found": "لم يتم العثور على مستخدمين", + "bd_center.success": "نجاح", + "bd_center.pending": "قيد الانتظار", + "bd_center.cancel": "إلغاء", + "bd_center.invite": "دعوة", + "bd_center.application_cancelled": "تم إلغاء الطلب", + "bd_center.invitation_submitted": "تم إرسال الدعوة", + "bd_center.close": "إغلاق", + "bd_center.mock_navigation": "انتقال تجريبي: {label}", + "bd_center.mock_bill_loaded": "تم تحميل فاتورة تجريبية.", + "agency_center.title": "مركز الوكالة", + "agency_center.back": "رجوع", + "agency_center.change_language": "تغيير اللغة", + "agency_center.open_messages": "فتح الرسائل", + "agency_center.work_time": "وقت العمل (دقيقة)", + "agency_center.work_time_short": "العمل", + "agency_center.target": "الهدف", + "agency_center.open_daily_data": "فتح البيانات اليومية", + "agency_center.salary": "الراتب", + "agency_center.withdraw_exchange": "سحب/استبدال", + "agency_center.open_withdraw_exchange": "فتح صفحة السحب والاستبدال", + "agency_center.host_list": "قائمة المضيفين", + "agency_center.salary_bills": "فواتير الراتب", + "agency_center.agency_policy": "سياسة الوكالة", + "agency_center.invite_host": "كيفية دعوة مضيف", + "agency_center.close": "إغلاق", + "agency_center.daily_data": "البيانات اليومية", + "agency_center.gift_points": "نقاط الهدايا", + "agency_center.online_minutes": "دقائق الاتصال", + "agency_center.enter_host_id": "أدخل معرف المضيف", + "agency_center.search": "بحث", + "agency_center.no_hosts": "لا يوجد مضيفون", + "agency_center.remove": "إزالة", + "agency_center.tips": "تنبيه", + "agency_center.cancel": "إلغاء", + "agency_center.confirm": "تأكيد", + "agency_center.remove_confirm_message": "هل تريد إزالة {name} من وكالتك؟", + "agency_center.host_removed": "تمت إزالة المضيف.", + "agency_center.host_salary": "راتب المضيف", + "agency_center.agency_salary": "راتب الوكالة", + "agency_center.total": "المجموع", + "agency_center.messages": "الرسائل", + "agency_center.no_messages": "لا توجد رسائل", + "agency_center.agree": "موافقة", + "agency_center.refuse": "رفض", + "agency_center.approved_application": "تمت الموافقة على طلب {name}.", + "agency_center.rejected_application": "تم رفض طلب {name}.", + "agency_center.mock_navigation": "انتقال تجريبي: {label}", + "agency_center.invite_step_1": "ادع المستخدمين لتنزيل التطبيق.", + "agency_center.invite_step_2": "يجب على المستخدمين المدعوين تسجيل الدخول إلى التطبيق.", + "agency_center.invite_step_3": "Me > Host Center > Apply to join the team.", + "agency_center.invite_step_4": "أدخل معرف الفريق ثم اضغط إرسال." } diff --git a/common/locales/en.json b/common/locales/en.json index a3a6e80..6866cd3 100644 --- a/common/locales/en.json +++ b/common/locales/en.json @@ -18,6 +18,7 @@ "host_center.loading_agencies": "Loading agencies...", "host_center.no_agency": "No agency found in your country.", "host_center.search_failed": "Search failed. Try again later.", + "host_center.load_failed": "Load failed. Try again later.", "host_center.apply_failed": "Application failed. Try again later.", "host_center.apply_success": "Application submitted.", "host_center.applying": "Submitting...", @@ -26,5 +27,161 @@ "host_center.join": "Join", "host_center.cancel": "Cancel", "host_center.join_confirm_title": "Join Agency", - "host_center.join_confirm_message": "Are you sure you want to join {agency}?" + "host_center.join_confirm_message": "Are you sure you want to join {agency}?", + "host_center.verified_host": "Verified Host", + "host_center.agency_short_id": "Agency ID: {id}", + "host_center.my_agency": "My Agency", + "host_center.leave": "Leave", + "host_center.available_salary": "My available salary", + "host_center.salary_details": "Salary details", + "host_center.salary_month_note": "{month} settlement · {currency}", + "host_center.todays_task": "Today's task", + "host_center.anchor_type": "Anchor type", + "host_center.minutes": "Minutes", + "host_center.gift_task": "Gift Task", + "host_center.in_progress": "In progress", + "host_center.level_progress": "Level progress", + "host_center.current_level": "Current level", + "host_center.next_level_need": "Needed for next level", + "host_center.level_value": "Lv. {level}", + "host_center.platform_policy": "Platform policy", + "host_center.exchange_coins": "Exchange coins", + "host_center.withdraw_exchange": "Withdraw/Exchange", + "host_center.transfer": "Transfer", + "host_center.cash_withdraw": "Cash withdraw", + "host_center.bank_accounts": "Bank accounts", + "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.close": "Close", + "host_center.leave_success_mock": "Agency leave submitted.", + "host_center.mock_navigation": "Mock navigation: {label}", + "host_center.live_salary": "Live salary", + "host_center.gift_reward": "Gift reward", + "host_center.bonus": "Bonus", + "host_center.month_june": "June", + "host_center.currency_coins": "Coins", + "withdraw_exchange.page_label": "Withdraw and exchange", + "withdraw_exchange.back": "Back", + "withdraw_exchange.title": "Withdraw/Exchange", + "withdraw_exchange.change_language": "Change language", + "withdraw_exchange.mode_tabs": "Withdraw, exchange, or transfer", + "withdraw_exchange.salary": "salary", + "withdraw_exchange.salary_history": "Salary history", + "withdraw_exchange.withdraw": "Withdraw", + "withdraw_exchange.exchange": "Exchange", + "withdraw_exchange.transfer": "Transfer", + "withdraw_exchange.withdraw_amount": "Withdraw amount", + "withdraw_exchange.exchange_amount": "Exchange amount", + "withdraw_exchange.transfer_to": "Transfer to", + "withdraw_exchange.transfer_amount": "Transfer amount", + "withdraw_exchange.search": "Search", + "withdraw_exchange.searching": "Searching...", + "withdraw_exchange.minimum": "Minimum 50 USD", + "withdraw_exchange.all": "All", + "withdraw_exchange.exchange_rate": "Exchange rate", + "withdraw_exchange.exchange_rate_value": "1$ = {amount} golds", + "withdraw_exchange.payment_method": "USDT TRC20 address", + "withdraw_exchange.payment_method_subtitle": "Withdrawals are sent to your TRC20 USDT address.", + "withdraw_exchange.no_payment_info": "No USDT address", + "withdraw_exchange.no_payment_info_copy": "Fill in a TRC20 USDT address before withdrawing.", + "withdraw_exchange.trc20_address": "TRC20 address", + "withdraw_exchange.save_address": "Save address", + "withdraw_exchange.saving": "Saving...", + "withdraw_exchange.usdt_only": "USDT only", + "withdraw_exchange.withdraw_now": "Withdraw now", + "withdraw_exchange.exchange_now": "Exchange now", + "withdraw_exchange.transfer_now": "Transfer now", + "withdraw_exchange.submitting": "Submitting...", + "withdraw_exchange.payee": "Payee", + "withdraw_exchange.uid_prefix": "UID:", + "withdraw_exchange.close": "Close", + "withdraw_exchange.loading": "Loading...", + "withdraw_exchange.no_salary_history": "No salary history", + "withdraw_exchange.balance": "Balance", + "withdraw_exchange.history_host_salary": "Host salary", + "withdraw_exchange.history_exchange_to_golds": "Exchange to golds", + "withdraw_exchange.history_gift_reward": "Gift reward", + "withdraw_exchange.mock_user_name": "User {account}", + "withdraw_exchange.missing_payment_info": "Please add a TRC20 USDT address", + "withdraw_exchange.invalid_address": "Please enter a valid TRC20 USDT address", + "withdraw_exchange.invalid_amount": "Please enter a valid amount", + "withdraw_exchange.amount_too_low": "Minimum withdrawal amount is 50 USD", + "withdraw_exchange.amount_exceeds_balance": "Amount exceeds salary", + "withdraw_exchange.payee_not_found": "User not found", + "withdraw_exchange.missing_payee": "Please search and select a user", + "withdraw_exchange.address_saved": "Address saved", + "withdraw_exchange.withdraw_success": "Withdrawal submitted", + "withdraw_exchange.exchange_success": "Exchange success", + "withdraw_exchange.transfer_success": "Transfer success", + "bd_center.back": "Back", + "bd_center.title": "BD Center", + "bd_center.change_language": "Change language", + "bd_center.role": "BD", + "bd_center.salary": "Salary", + "bd_center.withdraw_exchange": "Withdraw/Exchange", + "bd_center.invite_agent": "Invite Agent", + "bd_center.agency_list": "Agency List", + "bd_center.agency_statistics": "Agency Statistics", + "bd_center.month": "Month", + "bd_center.agency_number": "Agency number", + "bd_center.team_salary": "Team salary", + "bd_center.team_recharge": "Team recharge", + "bd_center.recharge": "Recharge", + "bd_center.host": "Host", + "bd_center.no_data": "No data", + "bd_center.enter_user_id": "Enter User ID", + "bd_center.search": "Search", + "bd_center.no_users_found": "No users found", + "bd_center.success": "Success", + "bd_center.pending": "Pending", + "bd_center.cancel": "Cancel", + "bd_center.invite": "Invite", + "bd_center.application_cancelled": "Application cancelled", + "bd_center.invitation_submitted": "Invitation submitted", + "bd_center.close": "Close", + "bd_center.mock_navigation": "Mock navigation: {label}", + "bd_center.mock_bill_loaded": "Mock bill loaded.", + "agency_center.title": "Agency Center", + "agency_center.back": "Back", + "agency_center.change_language": "Change language", + "agency_center.open_messages": "Open messages", + "agency_center.work_time": "Work Time (min)", + "agency_center.work_time_short": "Work", + "agency_center.target": "Target", + "agency_center.open_daily_data": "Open daily data", + "agency_center.salary": "Salary", + "agency_center.withdraw_exchange": "Withdraw/Exchange", + "agency_center.open_withdraw_exchange": "Open withdraw and exchange page", + "agency_center.host_list": "Host List", + "agency_center.salary_bills": "Salary Bills", + "agency_center.agency_policy": "Agency Policy", + "agency_center.invite_host": "How to invite host", + "agency_center.close": "Close", + "agency_center.daily_data": "Daily data", + "agency_center.gift_points": "Gift points", + "agency_center.online_minutes": "Online minutes", + "agency_center.enter_host_id": "Enter host ID", + "agency_center.search": "Search", + "agency_center.no_hosts": "No hosts", + "agency_center.remove": "Remove", + "agency_center.tips": "Tips", + "agency_center.cancel": "Cancel", + "agency_center.confirm": "Confirm", + "agency_center.remove_confirm_message": "Confirm remove {name} from your agency?", + "agency_center.host_removed": "Host removed.", + "agency_center.host_salary": "Host salary", + "agency_center.agency_salary": "Agency salary", + "agency_center.total": "Total", + "agency_center.messages": "Messages", + "agency_center.no_messages": "No messages", + "agency_center.agree": "Agree", + "agency_center.refuse": "Refuse", + "agency_center.approved_application": "Approved {name}'s application.", + "agency_center.rejected_application": "Rejected {name}'s application.", + "agency_center.mock_navigation": "Mock navigation: {label}", + "agency_center.invite_step_1": "Invite users to download APP.", + "agency_center.invite_step_2": "Invited users need to log in to the APP.", + "agency_center.invite_step_3": "Me > Host Center > Apply to join the team.", + "agency_center.invite_step_4": "Enter the team ID, click send to join." } diff --git a/common/locales/es.json b/common/locales/es.json index 98ce8b7..646a92e 100644 --- a/common/locales/es.json +++ b/common/locales/es.json @@ -18,6 +18,7 @@ "host_center.loading_agencies": "Cargando agencias...", "host_center.no_agency": "No se encontró ninguna agencia en tu país.", "host_center.search_failed": "La búsqueda falló. Inténtalo más tarde.", + "host_center.load_failed": "La carga falló. Inténtalo más tarde.", "host_center.apply_failed": "La solicitud falló. Inténtalo más tarde.", "host_center.apply_success": "Solicitud enviada.", "host_center.applying": "Enviando...", @@ -26,5 +27,161 @@ "host_center.join": "Unirse", "host_center.cancel": "Cancelar", "host_center.join_confirm_title": "Unirse a una agencia", - "host_center.join_confirm_message": "¿Seguro que quieres unirte a {agency}?" + "host_center.join_confirm_message": "¿Seguro que quieres unirte a {agency}?", + "host_center.verified_host": "Host verificado", + "host_center.agency_short_id": "ID de agencia: {id}", + "host_center.my_agency": "Mi agencia", + "host_center.leave": "Salir", + "host_center.available_salary": "Mi salario disponible", + "host_center.salary_details": "Detalles del salario", + "host_center.salary_month_note": "Liquidación de {month} · {currency}", + "host_center.todays_task": "Tarea de hoy", + "host_center.anchor_type": "Tipo de host", + "host_center.minutes": "Minutos", + "host_center.gift_task": "Tarea de regalos", + "host_center.in_progress": "En progreso", + "host_center.level_progress": "Progreso de nivel", + "host_center.current_level": "Nivel actual", + "host_center.next_level_need": "Necesario para el siguiente nivel", + "host_center.level_value": "Nv. {level}", + "host_center.platform_policy": "Política de plataforma", + "host_center.exchange_coins": "Cambiar monedas", + "host_center.withdraw_exchange": "Retirar/Intercambiar", + "host_center.transfer": "Transferir", + "host_center.cash_withdraw": "Retiro de efectivo", + "host_center.bank_accounts": "Cuentas bancarias", + "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.close": "Cerrar", + "host_center.leave_success_mock": "Solicitud de salida enviada.", + "host_center.mock_navigation": "Navegación mock: {label}", + "host_center.live_salary": "Salario en vivo", + "host_center.gift_reward": "Recompensa de regalos", + "host_center.bonus": "Bono", + "host_center.month_june": "Junio", + "host_center.currency_coins": "Monedas", + "withdraw_exchange.page_label": "Retiro e intercambio", + "withdraw_exchange.back": "Volver", + "withdraw_exchange.title": "Retirar/Intercambiar", + "withdraw_exchange.change_language": "Cambiar idioma", + "withdraw_exchange.mode_tabs": "Retirar, intercambiar o transferir", + "withdraw_exchange.salary": "salario", + "withdraw_exchange.salary_history": "Historial salarial", + "withdraw_exchange.withdraw": "Retirar", + "withdraw_exchange.exchange": "Intercambiar", + "withdraw_exchange.transfer": "Transferir", + "withdraw_exchange.withdraw_amount": "Monto a retirar", + "withdraw_exchange.exchange_amount": "Monto a intercambiar", + "withdraw_exchange.transfer_to": "Transferir a", + "withdraw_exchange.transfer_amount": "Monto a transferir", + "withdraw_exchange.search": "Buscar", + "withdraw_exchange.searching": "Buscando...", + "withdraw_exchange.minimum": "Mínimo 50 USD", + "withdraw_exchange.all": "Todo", + "withdraw_exchange.exchange_rate": "Tipo de cambio", + "withdraw_exchange.exchange_rate_value": "1$ = {amount} monedas", + "withdraw_exchange.payment_method": "Dirección USDT TRC20", + "withdraw_exchange.payment_method_subtitle": "Los retiros se envían a tu dirección USDT TRC20.", + "withdraw_exchange.no_payment_info": "Sin dirección USDT", + "withdraw_exchange.no_payment_info_copy": "Agrega una dirección USDT TRC20 antes de retirar.", + "withdraw_exchange.trc20_address": "Dirección TRC20", + "withdraw_exchange.save_address": "Guardar dirección", + "withdraw_exchange.saving": "Guardando...", + "withdraw_exchange.usdt_only": "Solo USDT", + "withdraw_exchange.withdraw_now": "Retirar ahora", + "withdraw_exchange.exchange_now": "Intercambiar ahora", + "withdraw_exchange.transfer_now": "Transferir ahora", + "withdraw_exchange.submitting": "Enviando...", + "withdraw_exchange.payee": "Destinatario", + "withdraw_exchange.uid_prefix": "UID:", + "withdraw_exchange.close": "Cerrar", + "withdraw_exchange.loading": "Cargando...", + "withdraw_exchange.no_salary_history": "No hay historial salarial", + "withdraw_exchange.balance": "Saldo", + "withdraw_exchange.history_host_salary": "Salario de host", + "withdraw_exchange.history_exchange_to_golds": "Intercambio a monedas", + "withdraw_exchange.history_gift_reward": "Recompensa de regalos", + "withdraw_exchange.mock_user_name": "Usuario {account}", + "withdraw_exchange.missing_payment_info": "Agrega una dirección USDT TRC20", + "withdraw_exchange.invalid_address": "Ingresa una dirección USDT TRC20 válida", + "withdraw_exchange.invalid_amount": "Ingresa un monto válido", + "withdraw_exchange.amount_too_low": "El monto mínimo de retiro es 50 USD", + "withdraw_exchange.amount_exceeds_balance": "El monto supera el salario", + "withdraw_exchange.payee_not_found": "Usuario no encontrado", + "withdraw_exchange.missing_payee": "Busca y selecciona un usuario", + "withdraw_exchange.address_saved": "Dirección guardada", + "withdraw_exchange.withdraw_success": "Retiro enviado", + "withdraw_exchange.exchange_success": "Intercambio exitoso", + "withdraw_exchange.transfer_success": "Transferencia exitosa", + "bd_center.back": "Volver", + "bd_center.title": "Centro BD", + "bd_center.change_language": "Cambiar idioma", + "bd_center.role": "BD", + "bd_center.salary": "Salario", + "bd_center.withdraw_exchange": "Withdraw/Exchange", + "bd_center.invite_agent": "Invitar agente", + "bd_center.agency_list": "Lista de agencias", + "bd_center.agency_statistics": "Estadísticas de agencias", + "bd_center.month": "Mes", + "bd_center.agency_number": "Número de agencias", + "bd_center.team_salary": "Salario del equipo", + "bd_center.team_recharge": "Recarga del equipo", + "bd_center.recharge": "Recarga", + "bd_center.host": "Host", + "bd_center.no_data": "Sin datos", + "bd_center.enter_user_id": "Ingresa el ID de usuario", + "bd_center.search": "Buscar", + "bd_center.no_users_found": "No se encontraron usuarios", + "bd_center.success": "Éxito", + "bd_center.pending": "Pendiente", + "bd_center.cancel": "Cancelar", + "bd_center.invite": "Invitar", + "bd_center.application_cancelled": "Solicitud cancelada", + "bd_center.invitation_submitted": "Invitación enviada", + "bd_center.close": "Cerrar", + "bd_center.mock_navigation": "Navegación mock: {label}", + "bd_center.mock_bill_loaded": "Factura mock cargada.", + "agency_center.title": "Centro de agencia", + "agency_center.back": "Volver", + "agency_center.change_language": "Cambiar idioma", + "agency_center.open_messages": "Abrir mensajes", + "agency_center.work_time": "Tiempo de trabajo (min)", + "agency_center.work_time_short": "Trabajo", + "agency_center.target": "Objetivo", + "agency_center.open_daily_data": "Abrir datos diarios", + "agency_center.salary": "Salario", + "agency_center.withdraw_exchange": "Retirar/Cambiar", + "agency_center.open_withdraw_exchange": "Abrir retiro y cambio", + "agency_center.host_list": "Lista de hosts", + "agency_center.salary_bills": "Facturas de salario", + "agency_center.agency_policy": "Política de agencia", + "agency_center.invite_host": "Cómo invitar host", + "agency_center.close": "Cerrar", + "agency_center.daily_data": "Datos diarios", + "agency_center.gift_points": "Puntos de regalo", + "agency_center.online_minutes": "Minutos online", + "agency_center.enter_host_id": "Ingresa ID de host", + "agency_center.search": "Buscar", + "agency_center.no_hosts": "No hay hosts", + "agency_center.remove": "Eliminar", + "agency_center.tips": "Aviso", + "agency_center.cancel": "Cancelar", + "agency_center.confirm": "Confirmar", + "agency_center.remove_confirm_message": "¿Confirmas eliminar a {name} de tu agencia?", + "agency_center.host_removed": "Host eliminado.", + "agency_center.host_salary": "Salario de host", + "agency_center.agency_salary": "Salario de agencia", + "agency_center.total": "Total", + "agency_center.messages": "Mensajes", + "agency_center.no_messages": "Sin mensajes", + "agency_center.agree": "Aceptar", + "agency_center.refuse": "Rechazar", + "agency_center.approved_application": "Solicitud de {name} aprobada.", + "agency_center.rejected_application": "Solicitud de {name} rechazada.", + "agency_center.mock_navigation": "Navegación mock: {label}", + "agency_center.invite_step_1": "Invita usuarios a descargar la APP.", + "agency_center.invite_step_2": "Los usuarios invitados deben iniciar sesión en la APP.", + "agency_center.invite_step_3": "Me > Host Center > Solicitar unirse al equipo.", + "agency_center.invite_step_4": "Ingresa el ID del equipo y toca enviar." } diff --git a/common/locales/id.json b/common/locales/id.json index a76b998..aa662d3 100644 --- a/common/locales/id.json +++ b/common/locales/id.json @@ -18,6 +18,7 @@ "host_center.loading_agencies": "Memuat agency...", "host_center.no_agency": "Agency tidak ditemukan di negara Anda.", "host_center.search_failed": "Pencarian gagal. Coba lagi nanti.", + "host_center.load_failed": "Gagal memuat. Coba lagi nanti.", "host_center.apply_failed": "Pengajuan gagal. Coba lagi nanti.", "host_center.apply_success": "Pengajuan terkirim.", "host_center.applying": "Mengirim...", @@ -26,5 +27,161 @@ "host_center.join": "Gabung", "host_center.cancel": "Batal", "host_center.join_confirm_title": "Gabung Agency", - "host_center.join_confirm_message": "Apakah Anda yakin ingin bergabung dengan {agency}?" + "host_center.join_confirm_message": "Apakah Anda yakin ingin bergabung dengan {agency}?", + "host_center.verified_host": "Host Terverifikasi", + "host_center.agency_short_id": "ID Agency: {id}", + "host_center.my_agency": "Agency Saya", + "host_center.leave": "Keluar", + "host_center.available_salary": "Gaji tersedia saya", + "host_center.salary_details": "Detail gaji", + "host_center.salary_month_note": "Penyelesaian {month} · {currency}", + "host_center.todays_task": "Tugas hari ini", + "host_center.anchor_type": "Tipe host", + "host_center.minutes": "Menit", + "host_center.gift_task": "Tugas hadiah", + "host_center.in_progress": "Berlangsung", + "host_center.level_progress": "Progress level", + "host_center.current_level": "Level saat ini", + "host_center.next_level_need": "Dibutuhkan ke level berikutnya", + "host_center.level_value": "Lv. {level}", + "host_center.platform_policy": "Kebijakan platform", + "host_center.exchange_coins": "Tukar coin", + "host_center.withdraw_exchange": "Tarik/Tukar", + "host_center.transfer": "Transfer", + "host_center.cash_withdraw": "Tarik tunai", + "host_center.bank_accounts": "Akun bank", + "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.close": "Tutup", + "host_center.leave_success_mock": "Pengajuan keluar agency terkirim.", + "host_center.mock_navigation": "Navigasi mock: {label}", + "host_center.live_salary": "Gaji live", + "host_center.gift_reward": "Reward hadiah", + "host_center.bonus": "Bonus", + "host_center.month_june": "Juni", + "host_center.currency_coins": "Koin", + "withdraw_exchange.page_label": "Tarik dan tukar", + "withdraw_exchange.back": "Kembali", + "withdraw_exchange.title": "Tarik/Tukar", + "withdraw_exchange.change_language": "Ganti bahasa", + "withdraw_exchange.mode_tabs": "Tarik, tukar, atau transfer", + "withdraw_exchange.salary": "gaji", + "withdraw_exchange.salary_history": "Riwayat gaji", + "withdraw_exchange.withdraw": "Tarik", + "withdraw_exchange.exchange": "Tukar", + "withdraw_exchange.transfer": "Transfer", + "withdraw_exchange.withdraw_amount": "Jumlah penarikan", + "withdraw_exchange.exchange_amount": "Jumlah penukaran", + "withdraw_exchange.transfer_to": "Transfer ke", + "withdraw_exchange.transfer_amount": "Jumlah transfer", + "withdraw_exchange.search": "Cari", + "withdraw_exchange.searching": "Mencari...", + "withdraw_exchange.minimum": "Minimum 50 USD", + "withdraw_exchange.all": "Semua", + "withdraw_exchange.exchange_rate": "Kurs tukar", + "withdraw_exchange.exchange_rate_value": "1$ = {amount} koin", + "withdraw_exchange.payment_method": "Alamat USDT TRC20", + "withdraw_exchange.payment_method_subtitle": "Penarikan dikirim ke alamat USDT TRC20 Anda.", + "withdraw_exchange.no_payment_info": "Belum ada alamat USDT", + "withdraw_exchange.no_payment_info_copy": "Isi alamat USDT TRC20 sebelum menarik.", + "withdraw_exchange.trc20_address": "Alamat TRC20", + "withdraw_exchange.save_address": "Simpan alamat", + "withdraw_exchange.saving": "Menyimpan...", + "withdraw_exchange.usdt_only": "Hanya USDT", + "withdraw_exchange.withdraw_now": "Tarik sekarang", + "withdraw_exchange.exchange_now": "Tukar sekarang", + "withdraw_exchange.transfer_now": "Transfer sekarang", + "withdraw_exchange.submitting": "Mengirim...", + "withdraw_exchange.payee": "Penerima", + "withdraw_exchange.uid_prefix": "UID:", + "withdraw_exchange.close": "Tutup", + "withdraw_exchange.loading": "Memuat...", + "withdraw_exchange.no_salary_history": "Belum ada riwayat gaji", + "withdraw_exchange.balance": "Saldo", + "withdraw_exchange.history_host_salary": "Gaji host", + "withdraw_exchange.history_exchange_to_golds": "Tukar ke koin", + "withdraw_exchange.history_gift_reward": "Reward hadiah", + "withdraw_exchange.mock_user_name": "Pengguna {account}", + "withdraw_exchange.missing_payment_info": "Tambahkan alamat USDT TRC20", + "withdraw_exchange.invalid_address": "Masukkan alamat USDT TRC20 yang valid", + "withdraw_exchange.invalid_amount": "Masukkan jumlah yang valid", + "withdraw_exchange.amount_too_low": "Jumlah penarikan minimum 50 USD", + "withdraw_exchange.amount_exceeds_balance": "Jumlah melebihi gaji", + "withdraw_exchange.payee_not_found": "Pengguna tidak ditemukan", + "withdraw_exchange.missing_payee": "Cari dan pilih pengguna terlebih dahulu", + "withdraw_exchange.address_saved": "Alamat tersimpan", + "withdraw_exchange.withdraw_success": "Pengajuan penarikan terkirim", + "withdraw_exchange.exchange_success": "Penukaran berhasil", + "withdraw_exchange.transfer_success": "Transfer berhasil", + "bd_center.back": "Kembali", + "bd_center.title": "Pusat BD", + "bd_center.change_language": "Ganti bahasa", + "bd_center.role": "BD", + "bd_center.salary": "Gaji", + "bd_center.withdraw_exchange": "Withdraw/Exchange", + "bd_center.invite_agent": "Invite Agent", + "bd_center.agency_list": "Daftar agency", + "bd_center.agency_statistics": "Statistik agency", + "bd_center.month": "Bulan", + "bd_center.agency_number": "Jumlah agency", + "bd_center.team_salary": "Gaji tim", + "bd_center.team_recharge": "Recharge tim", + "bd_center.recharge": "Recharge", + "bd_center.host": "Host", + "bd_center.no_data": "Tidak ada data", + "bd_center.enter_user_id": "Masukkan ID Pengguna", + "bd_center.search": "Cari", + "bd_center.no_users_found": "Pengguna tidak ditemukan", + "bd_center.success": "Berhasil", + "bd_center.pending": "Menunggu", + "bd_center.cancel": "Batal", + "bd_center.invite": "Undang", + "bd_center.application_cancelled": "Pengajuan dibatalkan", + "bd_center.invitation_submitted": "Undangan terkirim", + "bd_center.close": "Tutup", + "bd_center.mock_navigation": "Navigasi mock: {label}", + "bd_center.mock_bill_loaded": "Tagihan mock dimuat.", + "agency_center.title": "Pusat Agency", + "agency_center.back": "Kembali", + "agency_center.change_language": "Ganti bahasa", + "agency_center.open_messages": "Buka pesan", + "agency_center.work_time": "Waktu Kerja (mnt)", + "agency_center.work_time_short": "Kerja", + "agency_center.target": "Target", + "agency_center.open_daily_data": "Buka data harian", + "agency_center.salary": "Gaji", + "agency_center.withdraw_exchange": "Tarik/Tukar", + "agency_center.open_withdraw_exchange": "Buka halaman tarik dan tukar", + "agency_center.host_list": "Daftar Host", + "agency_center.salary_bills": "Tagihan gaji", + "agency_center.agency_policy": "Kebijakan agency", + "agency_center.invite_host": "Cara mengundang host", + "agency_center.close": "Tutup", + "agency_center.daily_data": "Data harian", + "agency_center.gift_points": "Poin hadiah", + "agency_center.online_minutes": "Menit online", + "agency_center.enter_host_id": "Masukkan ID host", + "agency_center.search": "Cari", + "agency_center.no_hosts": "Tidak ada host", + "agency_center.remove": "Hapus", + "agency_center.tips": "Tips", + "agency_center.cancel": "Batal", + "agency_center.confirm": "Konfirmasi", + "agency_center.remove_confirm_message": "Konfirmasi hapus {name} dari agency Anda?", + "agency_center.host_removed": "Host dihapus.", + "agency_center.host_salary": "Gaji host", + "agency_center.agency_salary": "Gaji agency", + "agency_center.total": "Total", + "agency_center.messages": "Pesan", + "agency_center.no_messages": "Tidak ada pesan", + "agency_center.agree": "Setuju", + "agency_center.refuse": "Tolak", + "agency_center.approved_application": "Pengajuan {name} disetujui.", + "agency_center.rejected_application": "Pengajuan {name} ditolak.", + "agency_center.mock_navigation": "Navigasi mock: {label}", + "agency_center.invite_step_1": "Undang pengguna untuk mengunduh APP.", + "agency_center.invite_step_2": "Pengguna yang diundang harus login ke APP.", + "agency_center.invite_step_3": "Me > Host Center > Ajukan bergabung ke tim.", + "agency_center.invite_step_4": "Masukkan ID tim lalu ketuk kirim." } diff --git a/common/locales/tr.json b/common/locales/tr.json index c672af2..276f1b1 100644 --- a/common/locales/tr.json +++ b/common/locales/tr.json @@ -1,5 +1,5 @@ { - "host_center.title": "Host Center", + "host_center.title": "Host Merkezi", "host_center.back": "Geri", "host_center.change_language": "Dili değiştir", "host_center.profile_name": "Namenamename", @@ -18,6 +18,7 @@ "host_center.loading_agencies": "Ajanslar yükleniyor...", "host_center.no_agency": "Ülkenizde ajans bulunamadı.", "host_center.search_failed": "Arama başarısız. Daha sonra deneyin.", + "host_center.load_failed": "Yükleme başarısız. Daha sonra deneyin.", "host_center.apply_failed": "Başvuru başarısız. Daha sonra deneyin.", "host_center.apply_success": "Başvuru gönderildi.", "host_center.applying": "Gönderiliyor...", @@ -26,5 +27,161 @@ "host_center.join": "Katıl", "host_center.cancel": "İptal", "host_center.join_confirm_title": "Ajansa Katıl", - "host_center.join_confirm_message": "{agency} için katılmak istediğinizden emin misiniz?" + "host_center.join_confirm_message": "{agency} için katılmak istediğinizden emin misiniz?", + "host_center.verified_host": "Doğrulanmış Host", + "host_center.agency_short_id": "Ajans ID: {id}", + "host_center.my_agency": "Ajansım", + "host_center.leave": "Ayrıl", + "host_center.available_salary": "Kullanılabilir maaşım", + "host_center.salary_details": "Maaş detayları", + "host_center.salary_month_note": "{month} ödemesi · {currency}", + "host_center.todays_task": "Bugünün görevi", + "host_center.anchor_type": "Host türü", + "host_center.minutes": "Dakika", + "host_center.gift_task": "Hediye görevi", + "host_center.in_progress": "Devam ediyor", + "host_center.level_progress": "Seviye ilerlemesi", + "host_center.current_level": "Mevcut seviye", + "host_center.next_level_need": "Sonraki seviye için gereken", + "host_center.level_value": "Sv. {level}", + "host_center.platform_policy": "Platform kuralları", + "host_center.exchange_coins": "Coin değiştir", + "host_center.withdraw_exchange": "Çekim/Değişim", + "host_center.transfer": "Transfer", + "host_center.cash_withdraw": "Nakit çekim", + "host_center.bank_accounts": "Banka hesapları", + "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.close": "Kapat", + "host_center.leave_success_mock": "Ajanstan ayrılma isteği gönderildi.", + "host_center.mock_navigation": "Mock yönlendirme: {label}", + "host_center.live_salary": "Canlı maaşı", + "host_center.gift_reward": "Hediye ödülü", + "host_center.bonus": "Bonus", + "host_center.month_june": "Haziran", + "host_center.currency_coins": "Coin", + "withdraw_exchange.page_label": "Çekim ve değişim", + "withdraw_exchange.back": "Geri", + "withdraw_exchange.title": "Çekim/Değişim", + "withdraw_exchange.change_language": "Dili değiştir", + "withdraw_exchange.mode_tabs": "Çekim, değişim veya transfer", + "withdraw_exchange.salary": "Maaş", + "withdraw_exchange.salary_history": "Maaş geçmişi", + "withdraw_exchange.withdraw": "Çekim", + "withdraw_exchange.exchange": "Değişim", + "withdraw_exchange.transfer": "Transfer", + "withdraw_exchange.withdraw_amount": "Çekim tutarı", + "withdraw_exchange.exchange_amount": "Değişim tutarı", + "withdraw_exchange.transfer_to": "Transfer alıcısı", + "withdraw_exchange.transfer_amount": "Transfer tutarı", + "withdraw_exchange.search": "Ara", + "withdraw_exchange.searching": "Aranıyor...", + "withdraw_exchange.minimum": "Minimum 50 USD", + "withdraw_exchange.all": "Tümü", + "withdraw_exchange.exchange_rate": "Değişim kuru", + "withdraw_exchange.exchange_rate_value": "1$ = {amount} altın", + "withdraw_exchange.payment_method": "USDT TRC20 adresi", + "withdraw_exchange.payment_method_subtitle": "Çekimler TRC20 USDT adresinize gönderilir.", + "withdraw_exchange.no_payment_info": "USDT adresi yok", + "withdraw_exchange.no_payment_info_copy": "Çekimden önce bir TRC20 USDT adresi girin.", + "withdraw_exchange.trc20_address": "TRC20 adresi", + "withdraw_exchange.save_address": "Adresi kaydet", + "withdraw_exchange.saving": "Kaydediliyor...", + "withdraw_exchange.usdt_only": "Sadece USDT", + "withdraw_exchange.withdraw_now": "Şimdi çek", + "withdraw_exchange.exchange_now": "Şimdi değiştir", + "withdraw_exchange.transfer_now": "Şimdi transfer et", + "withdraw_exchange.submitting": "Gönderiliyor...", + "withdraw_exchange.payee": "Alıcı", + "withdraw_exchange.uid_prefix": "UID:", + "withdraw_exchange.close": "Kapat", + "withdraw_exchange.loading": "Yükleniyor...", + "withdraw_exchange.no_salary_history": "Maaş geçmişi yok", + "withdraw_exchange.balance": "Bakiye", + "withdraw_exchange.history_host_salary": "Host maaşı", + "withdraw_exchange.history_exchange_to_golds": "Altına değişim", + "withdraw_exchange.history_gift_reward": "Hediye ödülü", + "withdraw_exchange.mock_user_name": "Kullanıcı {account}", + "withdraw_exchange.missing_payment_info": "Lütfen bir TRC20 USDT adresi ekleyin", + "withdraw_exchange.invalid_address": "Lütfen geçerli bir TRC20 USDT adresi girin", + "withdraw_exchange.invalid_amount": "Lütfen geçerli bir tutar girin", + "withdraw_exchange.amount_too_low": "Minimum çekim tutarı 50 USD", + "withdraw_exchange.amount_exceeds_balance": "Tutar maaş bakiyesini aşıyor", + "withdraw_exchange.payee_not_found": "Kullanıcı bulunamadı", + "withdraw_exchange.missing_payee": "Lütfen bir kullanıcı arayın ve seçin", + "withdraw_exchange.address_saved": "Adres kaydedildi", + "withdraw_exchange.withdraw_success": "Çekim talebi gönderildi", + "withdraw_exchange.exchange_success": "Değişim başarılı", + "withdraw_exchange.transfer_success": "Transfer başarılı", + "bd_center.back": "Geri", + "bd_center.title": "BD Merkezi", + "bd_center.change_language": "Dili değiştir", + "bd_center.role": "BD", + "bd_center.salary": "Maaş", + "bd_center.withdraw_exchange": "Withdraw/Exchange", + "bd_center.invite_agent": "Ajans Davet Et", + "bd_center.agency_list": "Ajans listesi", + "bd_center.agency_statistics": "Ajans istatistikleri", + "bd_center.month": "Ay", + "bd_center.agency_number": "Ajans sayısı", + "bd_center.team_salary": "Takım maaşı", + "bd_center.team_recharge": "Takım yüklemesi", + "bd_center.recharge": "Yükleme", + "bd_center.host": "Host", + "bd_center.no_data": "Veri yok", + "bd_center.enter_user_id": "Kullanıcı ID gir", + "bd_center.search": "Ara", + "bd_center.no_users_found": "Kullanıcı bulunamadı", + "bd_center.success": "Başarılı", + "bd_center.pending": "Beklemede", + "bd_center.cancel": "İptal", + "bd_center.invite": "Davet et", + "bd_center.application_cancelled": "Başvuru iptal edildi", + "bd_center.invitation_submitted": "Davet gönderildi", + "bd_center.close": "Kapat", + "bd_center.mock_navigation": "Mock yönlendirme: {label}", + "bd_center.mock_bill_loaded": "Mock fatura yüklendi.", + "agency_center.title": "Ajans Merkezi", + "agency_center.back": "Geri", + "agency_center.change_language": "Dili değiştir", + "agency_center.open_messages": "Mesajları aç", + "agency_center.work_time": "Çalışma süresi (dk)", + "agency_center.work_time_short": "Çalışma", + "agency_center.target": "Hedef", + "agency_center.open_daily_data": "Günlük veriyi aç", + "agency_center.salary": "Maaş", + "agency_center.withdraw_exchange": "Çek/Değiştir", + "agency_center.open_withdraw_exchange": "Çekme ve değişim sayfasını aç", + "agency_center.host_list": "Host Listesi", + "agency_center.salary_bills": "Maaş faturaları", + "agency_center.agency_policy": "Ajans politikası", + "agency_center.invite_host": "Host nasıl davet edilir", + "agency_center.close": "Kapat", + "agency_center.daily_data": "Günlük veri", + "agency_center.gift_points": "Hediye puanı", + "agency_center.online_minutes": "Online dakika", + "agency_center.enter_host_id": "Host ID girin", + "agency_center.search": "Ara", + "agency_center.no_hosts": "Host yok", + "agency_center.remove": "Kaldır", + "agency_center.tips": "İpuçları", + "agency_center.cancel": "İptal", + "agency_center.confirm": "Onayla", + "agency_center.remove_confirm_message": "{name} ajansınızdan kaldırılsın mı?", + "agency_center.host_removed": "Host kaldırıldı.", + "agency_center.host_salary": "Host maaşı", + "agency_center.agency_salary": "Ajans maaşı", + "agency_center.total": "Toplam", + "agency_center.messages": "Mesajlar", + "agency_center.no_messages": "Mesaj yok", + "agency_center.agree": "Onayla", + "agency_center.refuse": "Reddet", + "agency_center.approved_application": "{name} başvurusu onaylandı.", + "agency_center.rejected_application": "{name} başvurusu reddedildi.", + "agency_center.mock_navigation": "Mock yönlendirme: {label}", + "agency_center.invite_step_1": "Kullanıcıları APP indirmeye davet et.", + "agency_center.invite_step_2": "Davet edilen kullanıcıların APP'e giriş yapması gerekir.", + "agency_center.invite_step_3": "Ben > Host Center > Ekibe katılmak için başvur.", + "agency_center.invite_step_4": "Takım ID'sini girin ve göndere dokunun." } diff --git a/common/locales/zh.json b/common/locales/zh.json index 5c35ec7..832d004 100644 --- a/common/locales/zh.json +++ b/common/locales/zh.json @@ -18,6 +18,7 @@ "host_center.loading_agencies": "公会加载中...", "host_center.no_agency": "未找到同国家公会。", "host_center.search_failed": "搜索失败,请稍后重试。", + "host_center.load_failed": "加载失败,请稍后重试。", "host_center.apply_failed": "申请失败,请稍后重试。", "host_center.apply_success": "申请已提交。", "host_center.applying": "提交中...", @@ -26,5 +27,161 @@ "host_center.join": "加入", "host_center.cancel": "取消", "host_center.join_confirm_title": "加入公会", - "host_center.join_confirm_message": "确定要加入 {agency} 吗?" + "host_center.join_confirm_message": "确定要加入 {agency} 吗?", + "host_center.verified_host": "已认证主播", + "host_center.agency_short_id": "公会 ID: {id}", + "host_center.my_agency": "我的公会", + "host_center.leave": "退出", + "host_center.available_salary": "我的可用薪资", + "host_center.salary_details": "薪资明细", + "host_center.salary_month_note": "{month} 结算 · {currency}", + "host_center.todays_task": "今日任务", + "host_center.anchor_type": "主播类型", + "host_center.minutes": "时长", + "host_center.gift_task": "礼物任务", + "host_center.in_progress": "进行中", + "host_center.level_progress": "等级进度", + "host_center.current_level": "当前等级", + "host_center.next_level_need": "距离下一级需要", + "host_center.level_value": "Lv. {level}", + "host_center.platform_policy": "平台政策", + "host_center.exchange_coins": "兑换金币", + "host_center.withdraw_exchange": "提现/兑换", + "host_center.transfer": "转账", + "host_center.cash_withdraw": "提现", + "host_center.bank_accounts": "银行卡", + "host_center.leave_agency": "退出公会", + "host_center.leave_confirm_message": "确定要退出当前公会吗?", + "host_center.confirm": "确认", + "host_center.close": "关闭", + "host_center.leave_success_mock": "退出公会申请已提交。", + "host_center.mock_navigation": "Mock 跳转:{label}", + "host_center.live_salary": "直播薪资", + "host_center.gift_reward": "礼物奖励", + "host_center.bonus": "奖金", + "host_center.month_june": "6 月", + "host_center.currency_coins": "金币", + "withdraw_exchange.page_label": "提现和兑换", + "withdraw_exchange.back": "返回", + "withdraw_exchange.title": "提现/兑换", + "withdraw_exchange.change_language": "切换语言", + "withdraw_exchange.mode_tabs": "提现、兑换或转账", + "withdraw_exchange.salary": "薪资", + "withdraw_exchange.salary_history": "薪资历史", + "withdraw_exchange.withdraw": "提现", + "withdraw_exchange.exchange": "兑换", + "withdraw_exchange.transfer": "转账", + "withdraw_exchange.withdraw_amount": "提现金额", + "withdraw_exchange.exchange_amount": "兑换金额", + "withdraw_exchange.transfer_to": "转账给", + "withdraw_exchange.transfer_amount": "转账金额", + "withdraw_exchange.search": "搜索", + "withdraw_exchange.searching": "搜索中...", + "withdraw_exchange.minimum": "最低 50 USD", + "withdraw_exchange.all": "全部", + "withdraw_exchange.exchange_rate": "兑换比例", + "withdraw_exchange.exchange_rate_value": "1$ = {amount} 金币", + "withdraw_exchange.payment_method": "USDT TRC20 address", + "withdraw_exchange.payment_method_subtitle": "提现会发送到你的 TRC20 USDT 地址。", + "withdraw_exchange.no_payment_info": "暂无 USDT 地址", + "withdraw_exchange.no_payment_info_copy": "提现前请先填写 TRC20 USDT 地址。", + "withdraw_exchange.trc20_address": "TRC20 地址", + "withdraw_exchange.save_address": "保存地址", + "withdraw_exchange.saving": "保存中...", + "withdraw_exchange.usdt_only": "仅支持 USDT", + "withdraw_exchange.withdraw_now": "立即提现", + "withdraw_exchange.exchange_now": "立即兑换", + "withdraw_exchange.transfer_now": "立即转账", + "withdraw_exchange.submitting": "提交中...", + "withdraw_exchange.payee": "收款人", + "withdraw_exchange.uid_prefix": "UID:", + "withdraw_exchange.close": "关闭", + "withdraw_exchange.loading": "加载中...", + "withdraw_exchange.no_salary_history": "暂无薪资历史", + "withdraw_exchange.balance": "余额", + "withdraw_exchange.history_host_salary": "主播薪资", + "withdraw_exchange.history_exchange_to_golds": "兑换金币", + "withdraw_exchange.history_gift_reward": "礼物奖励", + "withdraw_exchange.mock_user_name": "用户 {account}", + "withdraw_exchange.missing_payment_info": "请先添加 TRC20 USDT 地址", + "withdraw_exchange.invalid_address": "请输入有效的 TRC20 USDT 地址", + "withdraw_exchange.invalid_amount": "请输入有效金额", + "withdraw_exchange.amount_too_low": "最低提现金额为 50 USD", + "withdraw_exchange.amount_exceeds_balance": "金额超过薪资余额", + "withdraw_exchange.payee_not_found": "未找到用户", + "withdraw_exchange.missing_payee": "请先搜索并选择用户", + "withdraw_exchange.address_saved": "地址已保存", + "withdraw_exchange.withdraw_success": "提现申请已提交", + "withdraw_exchange.exchange_success": "兑换成功", + "withdraw_exchange.transfer_success": "转账成功", + "bd_center.back": "返回", + "bd_center.title": "BD Center", + "bd_center.change_language": "切换语言", + "bd_center.role": "BD", + "bd_center.salary": "薪资", + "bd_center.withdraw_exchange": "Withdraw/Exchange", + "bd_center.invite_agent": "邀请代理", + "bd_center.agency_list": "Agency List", + "bd_center.agency_statistics": "代理统计", + "bd_center.month": "月份", + "bd_center.agency_number": "代理数量", + "bd_center.team_salary": "团队薪资", + "bd_center.team_recharge": "团队充值", + "bd_center.recharge": "充值", + "bd_center.host": "主播", + "bd_center.no_data": "暂无数据", + "bd_center.enter_user_id": "输入用户 ID", + "bd_center.search": "搜索", + "bd_center.no_users_found": "未找到用户", + "bd_center.success": "成功", + "bd_center.pending": "待处理", + "bd_center.cancel": "取消", + "bd_center.invite": "邀请", + "bd_center.application_cancelled": "申请已取消", + "bd_center.invitation_submitted": "邀请已提交", + "bd_center.close": "关闭", + "bd_center.mock_navigation": "Mock 跳转:{label}", + "bd_center.mock_bill_loaded": "Mock 账单已加载。", + "agency_center.title": "Agency Center", + "agency_center.back": "返回", + "agency_center.change_language": "切换语言", + "agency_center.open_messages": "打开消息", + "agency_center.work_time": "Work Time (min)", + "agency_center.work_time_short": "Work", + "agency_center.target": "Target", + "agency_center.open_daily_data": "打开每日数据", + "agency_center.salary": "Salary", + "agency_center.withdraw_exchange": "Withdraw/Exchange", + "agency_center.open_withdraw_exchange": "打开提现兑换页面", + "agency_center.host_list": "Host List", + "agency_center.salary_bills": "Salary Bills", + "agency_center.agency_policy": "Agency Policy", + "agency_center.invite_host": "How to invite host", + "agency_center.close": "关闭", + "agency_center.daily_data": "Daily data", + "agency_center.gift_points": "Gift points", + "agency_center.online_minutes": "Online minutes", + "agency_center.enter_host_id": "Enter host ID", + "agency_center.search": "Search", + "agency_center.no_hosts": "No hosts", + "agency_center.remove": "Remove", + "agency_center.tips": "Tips", + "agency_center.cancel": "Cancel", + "agency_center.confirm": "Confirm", + "agency_center.remove_confirm_message": "Confirm remove {name} from your agency?", + "agency_center.host_removed": "Host removed.", + "agency_center.host_salary": "Host salary", + "agency_center.agency_salary": "Agency salary", + "agency_center.total": "Total", + "agency_center.messages": "Messages", + "agency_center.no_messages": "No messages", + "agency_center.agree": "Agree", + "agency_center.refuse": "Refuse", + "agency_center.approved_application": "Approved {name}'s application.", + "agency_center.rejected_application": "Rejected {name}'s application.", + "agency_center.mock_navigation": "Mock navigation: {label}", + "agency_center.invite_step_1": "Invite users to download APP.", + "agency_center.invite_step_2": "Invited users need to log in to the APP.", + "agency_center.invite_step_3": "Me > Host Center > Apply to join the team.", + "agency_center.invite_step_4": "Enter the team ID, click send to join." } diff --git a/common/theme.css b/common/theme.css index 9277e44..ec1001d 100644 --- a/common/theme.css +++ b/common/theme.css @@ -14,7 +14,8 @@ --hy-theme-danger: #d95d72; --hy-theme-shadow: 0 10px 24px rgba(132, 90, 212, 0.075); --hy-theme-button: #7d57c7; - --hy-theme-button-disabled: #c5a6f6; + --hy-theme-button-disabled: #eadffc; + --hy-theme-button-disabled-text: #9a8faa; --hy-theme-button-shadow: 0 8px 18px rgba(125, 87, 199, 0.18); --hy-theme-button-disabled-shadow: none; --hy-theme-hero: linear-gradient( diff --git a/gonghui/agency-center/index.html b/gonghui/agency-center/index.html new file mode 100644 index 0000000..b3ff151 --- /dev/null +++ b/gonghui/agency-center/index.html @@ -0,0 +1,440 @@ + + + + + + Agency Center + + + + + + +
+ + + + +
+
+
+ + +
+
+
Yumi Star Agency
+
UID: 163003
+
BD: Mila
+
+ +
+ +
+
+
+ Salary + +
+ +
+ +
+ + +
+ + + + + + + + + + + + +
+ + + + + + + + + diff --git a/gonghui/agency-center/script.js b/gonghui/agency-center/script.js new file mode 100644 index 0000000..e8b90d0 --- /dev/null +++ b/gonghui/agency-center/script.js @@ -0,0 +1,727 @@ +(function () { + var AGENCY_SALARY_USD = 'AGENCY_SALARY_USD'; + var HOST_SALARY_USD = 'HOST_SALARY_USD'; + + var mock = { + profile: { + name: 'Yumi Star Agency', + uid: '163003', + avatar: avatarData('A', '#dbc8ff', '#7d57c7'), + bd: 'Mila BD (880001)', + }, + metrics: { + salary: 12880.75, + }, + hosts: [ + { + id: '163000', + name: 'quick_1780052629537', + avatar: avatarData('Q', '#dbc8ff', '#7d57c7'), + workTime: 86, + gift: 2450, + salary: 3050.25, + }, + { + id: '163011', + name: 'Lina_voice', + avatar: avatarData('L', '#f4ebff', '#7d57c7'), + workTime: 124, + gift: 3760, + salary: 4280.5, + }, + { + id: '163024', + name: 'Nora_live', + avatar: avatarData('N', '#efe4ff', '#7d57c7'), + workTime: 98, + gift: 2990, + salary: 2298, + }, + ], + bills: [ + { + month: '2026-06', + hostSalary: 8420.2, + agencySalary: 3260.55, + total: 11680.75, + status: 'In progress', + }, + { + month: '2026-05', + hostSalary: 13240, + agencySalary: 5140.8, + total: 18380.8, + status: 'Completed', + }, + ], + messages: [ + { + id: 'apply-1001', + applicationId: '1001', + name: 'Mona_host', + account: '163088', + avatar: avatarData('M', '#dbc8ff', '#7d57c7'), + }, + { + id: 'apply-1002', + applicationId: '1002', + name: 'Sara_room', + account: '163099', + avatar: avatarData('S', '#f4ebff', '#7d57c7'), + }, + ], + }; + + var state = { + hosts: mock.hosts.slice(), + messages: mock.messages.slice(), + hostSearch: '', + pendingRemoveHost: null, + profile: mock.profile, + salary: mock.metrics.salary, + loading: false, + isMock: shouldUseMock(), + }; + + function $(id) { + return document.getElementById(id); + } + + function shouldUseMock() { + var params = new URLSearchParams(window.location.search); + return params.get('mock') === '1' || params.get('mock') === 'true'; + } + + function avatarData(text, background, foreground) { + var letter = encodeURIComponent(String(text || 'A').charAt(0)); + var svg = + '' + + '' + + '' + + letter + + '' + + ''; + 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 (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: 2, + }); + } + + 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 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 setImage(image, fallback, src, name) { + if (!image || !fallback) return; + fallback.textContent = initial(name) || 'A'; + if (!src) { + image.hidden = true; + 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 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 hasRealAPI() { + return ( + !state.isMock && + window.HyAppAPI && + window.HyAppAPI.agencyCenter + ); + } + + function displayName(user, fallback) { + if (!user) return fallback || '-'; + return ( + user.username || + user.display_user_id || + user.user_id || + fallback || + '-' + ); + } + + function normalizeOverview(payload) { + var agency = payload && payload.agency ? payload.agency : {}; + var bd = payload && payload.bd ? payload.bd : null; + state.profile = { + name: agency.name || mock.profile.name, + uid: agency.agency_id || mock.profile.uid, + avatar: agency.avatar || '', + bd: bd + ? displayName(bd, '') + + (bd.display_user_id ? ' (' + bd.display_user_id + ')' : '') + : '', + }; + state.salary = salaryDisplayAmount( + payload ? payload.salary : null, + 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 applyAgencyCenterPayload(overview, hosts, applications) { + normalizeOverview(overview || {}); + state.hosts = ((hosts && hosts.items) || []).map(normalizeHost); + state.messages = ((applications && applications.items) || []).map( + normalizeMessage + ); + } + + function loadAgencyCenter() { + if (!hasRealAPI()) return Promise.resolve(); + if (window.HyAppParams && window.HyAppParams.parse) { + window.HyAppParams.parse(); + } + state.loading = true; + return Promise.all([ + window.HyAppAPI.agencyCenter.overview(), + window.HyAppAPI.agencyCenter.hosts(), + window.HyAppAPI.agencyCenter.applications('pending'), + ]) + .then(function (results) { + applyAgencyCenterPayload(results[0], results[1], results[2]); + render(); + }) + .catch(function () { + toast( + t( + 'agency_center.load_failed', + 'Load failed. Try again later.' + ) + ); + }) + .finally(function () { + state.loading = false; + }); + } + + function renderProfile() { + var profile = state.profile || mock.profile; + $('agencyName').textContent = profile.name; + $('agencyUid').textContent = 'UID: ' + profile.uid; + $('bdName').textContent = profile.bd ? 'BD: ' + profile.bd : ''; + setImage( + $('agencyAvatar'), + $('agencyAvatarFallback'), + profile.avatar, + profile.name + ); + } + + function renderSalary() { + $('currentSalary').textContent = formatMoney(state.salary); + } + + function renderHostCount() { + $('hostCount').textContent = 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 renderHostList() { + var list = $('hostList'); + var empty = $('hostListEmpty'); + var hosts = filteredHosts(); + list.textContent = ''; + 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; + if (!host) return; + if (hasRealAPI()) { + window.HyAppAPI.agencyCenter + .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.' + ) + ); + }); + return; + } + state.hosts = state.hosts.filter(function (item) { + return item.id !== host.id; + }); + state.pendingRemoveHost = null; + closeSheet('removeConfirmModal'); + renderHostCount(); + renderHostList(); + toast(t('agency_center.host_removed', 'Host removed.')); + } + + function createBillCell(label, value) { + var cell = document.createElement('div'); + var title = document.createElement('span'); + var strong = document.createElement('strong'); + cell.className = 'bill-cell'; + title.textContent = label; + strong.textContent = value; + cell.appendChild(title); + cell.appendChild(strong); + return cell; + } + + function renderBillList() { + var list = $('billList'); + list.textContent = ''; + mock.bills.forEach(function (bill) { + var row = document.createElement('div'); + var month = document.createElement('div'); + var values = document.createElement('div'); + row.className = 'bill-row'; + month.className = 'bill-month'; + values.className = 'bill-values'; + month.textContent = bill.month + ' · ' + bill.status; + values.appendChild( + createBillCell( + t('agency_center.host_salary', 'Host salary'), + formatMoney(bill.hostSalary) + ) + ); + values.appendChild( + createBillCell( + t('agency_center.agency_salary', 'Agency salary'), + formatMoney(bill.agencySalary) + ) + ); + values.appendChild( + createBillCell( + t('agency_center.total', 'Total'), + formatMoney(bill.total) + ) + ); + row.appendChild(month); + row.appendChild(values); + list.appendChild(row); + }); + } + + 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) { + if (hasRealAPI()) { + var decision = action === 'agree' ? 'approve' : 'reject'; + window.HyAppAPI.agencyCenter + .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.' + ) + ); + }); + return; + } + state.messages = state.messages.filter(function (item) { + return item.id !== message.id; + }); + renderUnread(); + renderMessages(); + 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)); + } + + 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 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); + if (!params.has('mode')) params.set('mode', 'transfer'); + window.location.href = + '../withdraw-exchange/index.html?' + params.toString(); + } + + 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('.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 === 'team-bill') { + renderBillList(); + openSheet('billSheet'); + return; + } + if (action === 'invite') { + openSheet('inviteSheet'); + return; + } + toast( + t( + 'agency_center.mock_navigation', + 'Mock navigation: {label}' + ).replace( + '{label}', + t('agency_center.agency_policy', 'Agency Policy') + ) + ); + }); + }); + document.addEventListener('keydown', function (event) { + if (event.key === 'Escape') closeAllSheets(); + }); + } + + function render() { + renderProfile(); + renderSalary(); + renderHostCount(); + renderUnread(); + renderHostList(); + renderBillList(); + renderMessages(); + } + + function initPage() { + render(); + bindEvents(); + loadAgencyCenter(); + if (window.HyAppBridge) { + window.HyAppBridge.ready({ + page: 'agency-center', + mock: state.isMock, + }); + } + } + + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', initPage); + } else { + initPage(); + } + + window.addEventListener('hyapp:i18n-ready', function () { + render(); + }); +})(); diff --git a/gonghui/agency-center/style.css b/gonghui/agency-center/style.css new file mode 100644 index 0000000..ddf0b97 --- /dev/null +++ b/gonghui/agency-center/style.css @@ -0,0 +1,932 @@ +:root { + --page-bg: var(--hy-theme-bg, #fbf8ff); + --card-bg: var(--hy-theme-surface, rgba(255, 255, 255, 0.96)); + --text: var(--hy-theme-text, #282333); + --muted: var(--hy-theme-muted, #8d879a); + --line: var(--hy-theme-line, #f0e8fb); + --primary: var(--hy-theme-primary, #dbc8ff); + --primary-soft: var(--hy-theme-primary-soft, #f4ebff); + --primary-deep: var(--hy-theme-primary-deep, #7d57c7); + --button: var(--hy-theme-button, #7d57c7); + --danger: var(--hy-theme-danger, #d95d72); + --shadow: var(--hy-theme-shadow, 0 10px 24px rgba(132, 90, 212, 0.075)); +} + +* { + box-sizing: border-box; +} + +html, +body { + width: 100%; + min-height: 100%; + margin: 0; + -webkit-font-smoothing: antialiased; + -webkit-text-size-adjust: 100%; + -webkit-tap-highlight-color: transparent; +} + +body { + display: flex; + justify-content: center; + background: #111; + color: var(--text); + font-family: + Inter, + -apple-system, + BlinkMacSystemFont, + 'Segoe UI', + Roboto, + Helvetica, + Arial, + sans-serif; +} + +button, +input { + font: inherit; +} + +button { + border: 0; + padding: 0; + background: transparent; + color: inherit; +} + +button:focus, +input:focus { + outline: none; +} + +button:focus-visible, +input:focus-visible { + outline: 2px solid rgba(125, 87, 199, 0.32); + outline-offset: 2px; +} + +[hidden] { + display: none !important; +} + +.agency-center { + position: relative; + width: 100%; + max-width: 430px; + min-height: 100vh; + min-height: 100dvh; + overflow: hidden; + background: + linear-gradient( + 145deg, + rgba(255, 255, 255, 0.82), + rgba(250, 246, 255, 0) 42% + ), + var(--page-bg); +} + +.hero-bg { + position: absolute; + inset: 0 0 auto; + height: 215px; + background: var( + --hy-theme-hero, + linear-gradient( + 151deg, + #f0e6ff 0%, + #fffbff 58%, + rgba(251, 248, 255, 0.88) 100% + ) + ); + clip-path: polygon(0 0, 100% 0, 100% 76%, 70% 47%, 40% 58%, 0 78%); +} + +.title-bar, +.content, +.home-indicator { + position: relative; + z-index: 1; +} + +.title-bar { + display: grid; + grid-template-columns: 52px 1fr 52px; + align-items: center; + z-index: 3; + height: 60px; + padding: 0 14px; + direction: ltr; +} + +.title-bar h1 { + margin: 0; + color: var(--text); + font-size: 22px; + font-weight: 900; + line-height: 1; + text-align: center; +} + +.back-button { + display: flex; + align-items: center; + justify-content: flex-start; + width: 44px; + height: 44px; +} + +.back-button svg { + width: 28px; + height: 28px; +} + +.back-button path { + fill: none; + stroke: var(--text); + stroke-linecap: round; + stroke-linejoin: round; + stroke-width: 3; +} + +.language-switcher { + position: relative; + justify-self: end; +} + +.language-button { + display: flex; + align-items: center; + justify-content: center; + width: 42px; + height: 30px; + border: 1px solid rgba(35, 40, 46, 0.12); + border-radius: 15px; + background: rgba(255, 255, 255, 0.68); + color: var(--text); + font-size: 13px; + font-weight: 900; + box-shadow: 0 4px 12px rgba(43, 118, 107, 0.08); +} + +.language-menu { + position: absolute; + z-index: 20; + top: calc(100% + 7px); + right: 0; + display: grid; + gap: 2px; + min-width: 72px; + padding: 5px; + border: 1px solid rgba(35, 40, 46, 0.1); + border-radius: 8px; + background: rgba(255, 255, 255, 0.96); + box-shadow: 0 10px 26px rgba(36, 46, 60, 0.14); +} + +.language-menu button { + min-height: 34px; + border-radius: 6px; + color: var(--text); + font-size: 12px; + font-weight: 900; +} + +.language-menu button.is-active { + background: var(--primary-soft); + color: var(--primary-deep); +} + +.content { + display: flex; + flex-direction: column; + gap: 15px; + padding: 8px 14px 90px; +} + +.card { + width: 100%; + border-radius: 8px; + background: var(--card-bg); + box-shadow: var(--shadow); +} + +.profile-card { + display: flex; + align-items: center; + min-height: 103px; + padding: 16px 18px 16px 24px; +} + +.avatar-shell { + position: relative; + width: 64px; + height: 64px; + flex: 0 0 64px; +} + +.avatar-image, +.avatar-fallback { + width: 64px; + height: 64px; + border-radius: 50%; +} + +.avatar-image { + display: block; + object-fit: cover; +} + +.avatar-fallback { + display: flex; + align-items: center; + justify-content: center; + background: var(--primary); + color: var(--primary-deep); + font-size: 24px; + font-weight: 950; +} + +.profile-copy { + min-width: 0; + margin-left: 20px; +} + +.name { + overflow: hidden; + color: var(--text); + font-size: 20px; + font-weight: 900; + line-height: 1.1; + text-overflow: ellipsis; + white-space: nowrap; +} + +.meta, +.agency-line { + overflow: hidden; + color: var(--muted); + font-size: 13px; + font-weight: 750; + line-height: 1.2; + text-overflow: ellipsis; + white-space: nowrap; +} + +.meta { + margin-top: 6px; +} + +.agency-line { + margin-top: 7px; +} + +.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(--primary-soft); + color: var(--primary-deep); +} + +.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; +} + +.salary-card { + display: flex; + flex-direction: column; + justify-content: center; + min-height: 113px; + padding: 18px 24px; +} + +.salary-head { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; +} + +.salary-title { + display: flex; + align-items: center; + min-width: 0; + color: var(--text); + font-size: 17px; + font-weight: 900; +} + +.salary-title svg { + width: 17px; + height: 17px; + margin-left: 7px; +} + +.salary-title circle, +.salary-title path { + fill: none; + stroke: currentColor; + stroke-linecap: round; + stroke-width: 2; +} + +.salary-link { + flex: 0 0 auto; + color: var(--primary-deep); + font-size: 13px; + font-weight: 900; + white-space: nowrap; +} + +.salary-value { + display: flex; + align-items: center; + max-width: 100%; + margin-top: 14px; + color: #23272d; + font-size: 34px; + font-weight: 950; + line-height: 1.05; +} + +.salary-currency { + flex: 0 0 auto; + margin-right: 6px; + color: #f2ad2c; + font-size: 28px; + font-weight: 950; + line-height: 1; +} + +.chevron { + display: inline-flex; + align-items: center; + justify-content: center; + margin-left: 8px; + color: var(--muted); + font-size: 24px; + font-weight: 500; + line-height: 0.8; +} + +.menu-card { + display: grid; + padding: 0 16px; +} + +.menu-row { + display: grid; + grid-template-columns: 38px minmax(0, 1fr) auto 24px; + gap: 12px; + align-items: center; + min-height: 64px; + border-bottom: 1px solid var(--line); + text-align: left; +} + +.menu-row:last-child { + border-bottom: 0; +} + +.menu-icon { + display: flex; + align-items: center; + justify-content: center; + width: 34px; + height: 34px; + border-radius: 50%; + background: var(--primary-soft); + color: var(--primary-deep); +} + +.menu-icon svg { + width: 20px; + height: 20px; +} + +.menu-icon path { + fill: none; + stroke: currentColor; + stroke-linecap: round; + stroke-linejoin: round; + stroke-width: 2; +} + +.menu-label { + min-width: 0; + overflow: hidden; + color: #464951; + font-size: 16px; + font-weight: 850; + line-height: 1.2; + text-overflow: ellipsis; + white-space: nowrap; +} + +.menu-count { + color: var(--muted); + font-size: 13px; + font-weight: 900; + white-space: nowrap; +} + +.sheet-modal, +.message-modal, +.confirm-modal { + position: fixed; + z-index: 24; + inset: 0; + display: flex; + justify-content: center; +} + +.sheet-modal { + align-items: flex-end; + padding: 0 0 env(safe-area-inset-bottom); +} + +.message-modal, +.confirm-modal { + align-items: center; + padding: 18px; +} + +.confirm-modal { + z-index: 30; +} + +.modal-backdrop { + position: absolute; + inset: 0; + background: rgba(15, 21, 28, 0.38); +} + +.bottom-sheet { + position: relative; + display: flex; + flex-direction: column; + width: min(430px, 100%); + max-height: 80vh; + max-height: 80dvh; + overflow: hidden; + border-radius: 16px 16px 0 0; + background: #fff; + box-shadow: 0 -14px 34px rgba(23, 31, 42, 0.16); +} + +.message-dialog, +.confirm-dialog { + position: relative; + overflow: hidden; + background: #fff; + box-shadow: 0 18px 44px rgba(23, 31, 42, 0.2); +} + +.message-dialog { + display: flex; + flex-direction: column; + width: min(394px, 100%); + max-height: 78vh; + max-height: 78dvh; + border-radius: 14px; +} + +.confirm-dialog { + display: grid; + gap: 14px; + width: min(342px, 100%); + padding: 20px 18px 18px; + border-radius: 14px; +} + +.confirm-dialog h2, +.confirm-dialog p { + margin: 0; + text-align: center; +} + +.confirm-dialog h2 { + color: var(--text); + font-size: 18px; + font-weight: 950; + line-height: 1.2; +} + +.confirm-dialog p { + color: var(--muted); + font-size: 14px; + font-weight: 800; + line-height: 1.35; +} + +.confirm-actions { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 10px; + margin-top: 4px; +} + +.confirm-cancel, +.confirm-submit { + display: inline-flex; + align-items: center; + justify-content: center; + min-height: 42px; + border-radius: 8px; + font-size: 14px; + font-weight: 900; +} + +.confirm-cancel { + border: 1px solid var(--line); + background: #fff; + color: var(--text); +} + +.confirm-submit { + background: var(--button); + color: #fff; + box-shadow: var( + --hy-theme-button-shadow, + 0 8px 18px rgba(125, 87, 199, 0.18) + ); +} + +.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(--line); +} + +.sheet-head h2 { + margin: 0; + color: var(--text); + 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(--primary-soft); + color: var(--primary-deep); + font-size: 25px; + font-weight: 500; + line-height: 1; +} + +.host-list, +.bill-list, +.message-list, +.invite-steps { + display: grid; + gap: 10px; + min-height: 0; + overflow-y: auto; + padding: 14px 18px max(18px, env(safe-area-inset-bottom)); + -webkit-overflow-scrolling: touch; +} + +.host-row, +.bill-row, +.message-card, +.invite-step { + border: 1px solid var(--line); + border-radius: 8px; + background: #fbfcfc; +} + +.bill-row { + display: grid; + gap: 10px; + padding: 12px; +} + +.bill-month { + color: var(--text); + font-size: 15px; + font-weight: 950; + line-height: 1.2; +} + +.bill-values { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 10px; +} + +.bill-cell span { + display: block; + overflow: hidden; + color: var(--muted); + font-size: 12px; + font-weight: 800; + line-height: 1.2; + text-overflow: ellipsis; + white-space: nowrap; +} + +.bill-cell strong { + display: block; + margin-top: 4px; + overflow-wrap: anywhere; + color: #292d33; + font-size: 16px; + font-weight: 950; + line-height: 1.2; +} + +.host-search { + display: grid; + grid-template-columns: minmax(0, 1fr) 82px; + gap: 10px; + padding: 14px 18px 0; +} + +.host-search input { + min-width: 0; + height: 42px; + border: 1px solid var(--line); + border-radius: 8px; + background: #fff; + color: var(--text); + padding: 0 12px; + font-size: 14px; + font-weight: 800; +} + +.host-search input::placeholder { + color: #b7b3bf; +} + +.host-search button, +.remove-host-button, +.message-action { + display: inline-flex; + align-items: center; + justify-content: center; + min-height: 34px; + border-radius: 8px; + font-size: 12px; + font-weight: 950; + white-space: nowrap; +} + +.host-search button { + min-height: 42px; + background: var(--button); + color: #fff; + box-shadow: var( + --hy-theme-button-shadow, + 0 8px 18px rgba(125, 87, 199, 0.18) + ); +} + +.host-row, +.message-card { + display: grid; + grid-template-columns: minmax(0, 1fr) auto; + gap: 12px; + align-items: center; + padding: 12px; +} + +.host-user, +.message-user { + display: flex; + align-items: center; + min-width: 0; +} + +.small-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 { + position: absolute; + inset: 0; + width: 100%; + height: 100%; + object-fit: cover; +} + +.host-copy, +.message-copy { + min-width: 0; + margin-left: 12px; +} + +.host-name, +.message-name { + overflow: hidden; + color: var(--text); + font-size: 15px; + font-weight: 950; + line-height: 1.2; + text-overflow: ellipsis; + white-space: nowrap; +} + +.host-meta, +.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; +} + +.remove-host-button { + min-width: 58px; + padding: 0 10px; + background: #fff; + border: 1px solid rgba(217, 93, 114, 0.28); + color: var(--danger); +} + +.message-actions { + display: flex; + gap: 6px; +} + +.message-action { + min-width: 54px; + padding: 0 10px; +} + +.message-action.agree { + background: var(--button); + color: #fff; +} + +.message-action.refuse { + background: #f1edf8; + color: var(--text); +} + +.invite-step { + display: grid; + grid-template-columns: 30px minmax(0, 1fr); + gap: 12px; + align-items: start; + padding: 13px 12px; + color: #3d4148; + font-size: 14px; + font-weight: 800; + line-height: 1.42; +} + +.invite-step span { + display: inline-flex; + align-items: center; + justify-content: center; + width: 30px; + height: 30px; + border-radius: 50%; + background: var(--primary-soft); + color: var(--primary-deep); + font-size: 14px; + font-weight: 950; + line-height: 1; +} + +.invite-step p { + margin: 0; +} + +.sheet-empty { + display: flex; + align-items: center; + justify-content: center; + min-height: 112px; + margin: 14px 18px max(18px, env(safe-area-inset-bottom)); + border: 1px dashed var(--line); + border-radius: 8px; + color: var(--muted); + font-size: 14px; + font-weight: 850; + text-align: center; +} + +.modal-open { + overflow: hidden; +} + +.home-indicator { + position: absolute; + left: 50%; + bottom: 8px; + width: 154px; + height: 5px; + border-radius: 999px; + background: #050506; + transform: translateX(-50%); +} + +[dir='rtl'] .content, +[dir='rtl'] .bottom-sheet, +[dir='rtl'] .message-dialog, +[dir='rtl'] .confirm-dialog { + direction: rtl; +} + +[dir='rtl'] .profile-copy { + margin-right: 20px; + margin-left: 0; + text-align: right; +} + +[dir='rtl'] .message-button { + margin-right: auto; + margin-left: 0; +} + +[dir='rtl'] .menu-row { + text-align: right; +} + +[dir='rtl'] .chevron { + transform: rotate(180deg); +} + +[dir='rtl'] .host-copy, +[dir='rtl'] .message-copy { + margin-right: 12px; + margin-left: 0; + text-align: right; +} + +@media (max-width: 360px) { + .content { + padding-right: 12px; + padding-left: 12px; + } + + .profile-card, + .salary-card { + padding-right: 18px; + padding-left: 18px; + } + + .profile-copy { + margin-left: 14px; + } + + .bill-values { + grid-template-columns: 1fr; + } + + .salary-value { + font-size: 29px; + } +} diff --git a/gonghui/bd-center/index.html b/gonghui/bd-center/index.html new file mode 100644 index 0000000..c114290 --- /dev/null +++ b/gonghui/bd-center/index.html @@ -0,0 +1,290 @@ + + + + + + BD Center + + + + + + +
+ + + + +
+
+
+ + +
+
+
+ BD +
+
-
+
UID: -
+
+
+ +
+
+

Salary

+ +
+
+ + 0.00 +
+
+ + + +
+
+

+ Agency Statistics +

+
+
+ +
+
+
+
+ +
+
+

Agency List

+
+
+
+
+ + + + + + +
+ + + + + + + diff --git a/gonghui/bd-center/script.js b/gonghui/bd-center/script.js new file mode 100644 index 0000000..0494ebf --- /dev/null +++ b/gonghui/bd-center/script.js @@ -0,0 +1,592 @@ +(function () { + var FIRST_BILL_MONTH = '2026-06'; + var mock = { + profile: { + name: 'BD_Jasmine', + uid: 'BD-163008', + avatar: avatarData('B', '#dbc8ff', '#7d57c7'), + }, + balance: { + available: 48620.8, + }, + billMonth: currentMonth(), + agencyBill: { + billTitle: '2026.06', + agencyNumber: 12, + totalSalary: 128450.35, + totalRecharge: 356900.0, + memberBillList: [ + { + name: 'Yumi Star Agency', + account: '163003', + avatar: avatarData('Y', '#dbc8ff', '#7d57c7'), + teamSalaryAmount: 38420.55, + teamRechargeAmount: 126880, + teamMemberCount: 28, + }, + { + name: 'Moon Live Agency', + account: '163086', + avatar: avatarData('M', '#f4ebff', '#7d57c7'), + teamSalaryAmount: 29106.2, + teamRechargeAmount: 98540, + teamMemberCount: 19, + }, + { + name: 'Nova Host Guild', + account: '163221', + avatar: avatarData('N', '#dbc8ff', '#7d57c7'), + teamSalaryAmount: 22450, + teamRechargeAmount: 73150, + teamMemberCount: 16, + }, + ], + }, + inviteRecords: [ + { + id: 'inv-001', + status: 'pending', + profile: { + id: '3187001', + name: 'Agent_Lina', + account: '168801', + avatar: avatarData('L', '#dbc8ff', '#7d57c7'), + }, + }, + { + id: 'inv-002', + status: 'success', + profile: { + id: '3187002', + name: 'Agent_Omar', + account: '168802', + avatar: avatarData('O', '#f4ebff', '#7d57c7'), + }, + }, + ], + searchPool: [ + { + id: '3187099', + name: 'Agent_River', + account: '168899', + avatar: avatarData('R', '#dbc8ff', '#7d57c7'), + }, + { + id: '3187100', + name: 'Agent_Sara', + account: '168900', + avatar: avatarData('S', '#f4ebff', '#7d57c7'), + }, + ], + }; + + var state = { + billMonth: normalizeBillMonth(mock.billMonth), + inviteQuery: '', + inviteMode: 'records', + inviteStatus: '', + inviteStatusType: '', + searched: [], + }; + + function $(id) { + return document.getElementById(id); + } + + function t(key, fallback) { + return window.HyAppI18n && window.HyAppI18n.t + ? window.HyAppI18n.t(key, fallback) + : fallback || key; + } + + function avatarData(text, background, foreground) { + var letter = encodeURIComponent(String(text || 'B').charAt(0)); + var svg = + '' + + '' + + '' + + letter + + '' + + ''; + return 'data:image/svg+xml;charset=UTF-8,' + encodeURIComponent(svg); + } + + function currentMonth() { + var now = new Date(); + return ( + String(now.getFullYear()) + + '-' + + String(now.getMonth() + 1).padStart(2, '0') + ); + } + + function monthDate(value) { + var parts = String(value || currentMonth()).split('-'); + var year = Number(parts[0]) || new Date().getFullYear(); + var month = Number(parts[1]) || new Date().getMonth() + 1; + return new Date(year, month - 1, 1); + } + + function monthValue(date) { + return ( + String(date.getFullYear()) + + '-' + + String(date.getMonth() + 1).padStart(2, '0') + ); + } + + function monthTime(value) { + return monthDate(value).getTime(); + } + + function normalizeBillMonth(value) { + if (monthTime(value) < monthTime(FIRST_BILL_MONTH)) { + return FIRST_BILL_MONTH; + } + if (monthTime(value) > monthTime(currentMonth())) { + return currentMonth(); + } + return monthValue(monthDate(value)); + } + + function monthLabel(value) { + var date = monthDate(value); + return ( + String(date.getFullYear()) + + '年' + + String(date.getMonth() + 1).padStart(2, '0') + + '月' + ); + } + + function monthOptions() { + var options = []; + var cursor = monthDate(currentMonth()); + var first = monthDate(FIRST_BILL_MONTH); + while (cursor.getTime() >= first.getTime()) { + options.push(new Date(cursor.getFullYear(), cursor.getMonth(), 1)); + cursor = new Date(cursor.getFullYear(), cursor.getMonth() - 1, 1); + } + return options; + } + + function money(value) { + var number = Number(value || 0); + return number.toLocaleString('en-US', { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + }); + } + + function count(value) { + return Number(value || 0).toLocaleString('en-US', { + maximumFractionDigits: 0, + }); + } + + function initial(text) { + return String(text || '') + .trim() + .charAt(0) + .toUpperCase(); + } + + function toast(message) { + if (window.HyAppToast) { + window.HyAppToast.show(message); + return; + } + window.alert(message); + } + + function replaceChildren(node, children) { + node.textContent = ''; + children.forEach(function (child) { + node.appendChild(child); + }); + } + + function renderImageAvatar(container, src, name, fallbackClass) { + container.textContent = ''; + if (!src) { + var fallback = document.createElement('span'); + fallback.className = fallbackClass || 'member-fallback'; + fallback.textContent = initial(name) || 'B'; + container.appendChild(fallback); + return; + } + var image = document.createElement('img'); + image.src = src; + image.alt = ''; + image.addEventListener('error', function () { + container.textContent = ''; + var fallback = document.createElement('span'); + fallback.className = fallbackClass || 'member-fallback'; + fallback.textContent = initial(name) || 'B'; + container.appendChild(fallback); + }); + container.appendChild(image); + } + + function renderProfile() { + var image = $('profileAvatar'); + var fallback = $('profileAvatarFallback'); + $('profileName').textContent = mock.profile.name; + $('profileUID').textContent = 'UID: ' + mock.profile.uid; + fallback.textContent = initial(mock.profile.name) || 'B'; + image.onload = function () { + image.hidden = false; + fallback.hidden = true; + }; + image.onerror = function () { + image.hidden = true; + fallback.hidden = false; + }; + image.src = mock.profile.avatar; + } + + function renderBalance() { + $('availableBalance').textContent = money(mock.balance.available); + } + + function summaryCell(label, value) { + var cell = document.createElement('div'); + var labelNode = document.createElement('span'); + var valueNode = document.createElement('strong'); + labelNode.textContent = label; + valueNode.textContent = value; + cell.appendChild(labelNode); + cell.appendChild(valueNode); + return cell; + } + + function memberRow(item) { + var row = document.createElement('article'); + var avatar = document.createElement('div'); + var main = document.createElement('div'); + var name = document.createElement('div'); + var meta = document.createElement('div'); + var side = document.createElement('div'); + row.className = 'member-row'; + avatar.className = 'member-avatar'; + main.className = 'member-main'; + name.className = 'member-name'; + meta.className = 'member-meta'; + side.className = 'member-side'; + renderImageAvatar(avatar, item.avatar, item.name); + name.textContent = item.name; + meta.textContent = 'UID: ' + item.account; + [ + t('bd_center.team_salary', 'Team salary') + + ': $' + + money(item.teamSalaryAmount), + t('bd_center.recharge', 'Recharge') + + ': $' + + money(item.teamRechargeAmount), + t('bd_center.host', 'Host') + ': ' + count(item.teamMemberCount), + ].forEach(function (line) { + var node = document.createElement('div'); + node.textContent = line; + side.appendChild(node); + }); + main.appendChild(name); + main.appendChild(meta); + row.appendChild(avatar); + row.appendChild(main); + row.appendChild(side); + return row; + } + + function renderTeamList() { + var bill = mock.agencyBill; + $('billMonthText').textContent = monthLabel(state.billMonth); + $('billRange').textContent = state.billMonth.replace('-', '.'); + + replaceChildren($('teamListSummary'), [ + summaryCell( + t('bd_center.agency_number', 'Agency number'), + count(bill.agencyNumber) + ), + summaryCell( + t('bd_center.team_salary', 'Team salary'), + '$' + money(bill.totalSalary) + ), + ]); + + var rows = bill.memberBillList.map(memberRow); + if (!rows.length) { + var empty = document.createElement('div'); + empty.className = 'empty-state'; + empty.textContent = t('bd_center.no_data', 'No data'); + rows = [empty]; + } + replaceChildren($('teamListContent'), rows); + } + + function monthOption(date) { + var value = monthValue(date); + var option = document.createElement('button'); + option.className = 'month-option'; + option.type = 'button'; + option.setAttribute('role', 'option'); + option.setAttribute('data-month', value); + option.setAttribute('aria-selected', String(value === state.billMonth)); + option.textContent = monthLabel(value); + if (value === state.billMonth) option.classList.add('is-selected'); + return option; + } + + function renderMonthSheet() { + replaceChildren( + $('monthOptionList'), + monthOptions().map(function (date) { + return monthOption(date); + }) + ); + } + + function openMonthSheet() { + renderMonthSheet(); + $('monthSheet').hidden = false; + $('monthSheet').setAttribute('aria-hidden', 'false'); + document.body.classList.add('modal-open'); + window.setTimeout(function () { + var selected = $('monthOptionList').querySelector('.is-selected'); + if (selected && selected.scrollIntoView) { + selected.scrollIntoView({ block: 'center' }); + } + }, 0); + } + + function closeMonthSheet() { + $('monthSheet').hidden = true; + $('monthSheet').setAttribute('aria-hidden', 'true'); + document.body.classList.remove('modal-open'); + } + + function selectMonth(value) { + var nextMonth = normalizeBillMonth(value); + if (!nextMonth || nextMonth === state.billMonth) { + closeMonthSheet(); + return; + } + state.billMonth = nextMonth; + closeMonthSheet(); + renderTeamList(); + toast(t('bd_center.mock_bill_loaded', 'Mock bill loaded.')); + } + + function inviteProfile(item) { + return item.profile || item; + } + + function statusLabel(status) { + if (status === 'success') return t('bd_center.success', 'Success'); + if (status === 'pending') return t('bd_center.pending', 'Pending'); + return ''; + } + + function inviteCard(item) { + var profile = inviteProfile(item); + var card = document.createElement('article'); + var avatar = document.createElement('div'); + var main = document.createElement('div'); + var name = document.createElement('div'); + var meta = document.createElement('div'); + var side = document.createElement('div'); + card.className = 'invite-user-card'; + avatar.className = 'invite-user-avatar'; + main.className = 'invite-user-main'; + name.className = 'invite-user-name'; + meta.className = 'invite-user-meta'; + side.className = 'invite-user-side'; + renderImageAvatar( + avatar, + profile.avatar, + profile.name, + 'invite-avatar-fallback' + ); + name.textContent = profile.name; + meta.textContent = 'UID: ' + profile.account; + main.appendChild(name); + main.appendChild(meta); + + if (item.status === 'pending' || item.status === 'success') { + var badge = document.createElement('span'); + badge.className = 'invite-badge ' + item.status; + badge.textContent = statusLabel(item.status); + side.appendChild(badge); + if (item.status === 'pending') { + var cancel = document.createElement('button'); + cancel.className = 'invite-cancel'; + cancel.type = 'button'; + cancel.textContent = t('bd_center.cancel', 'Cancel'); + cancel.addEventListener('click', function () { + mock.inviteRecords = mock.inviteRecords.filter( + function (record) { + return record.id !== item.id; + } + ); + toast( + t( + 'bd_center.application_cancelled', + 'Application cancelled' + ) + ); + renderInviteModal(); + }); + side.appendChild(cancel); + } + } else { + var invite = document.createElement('button'); + invite.className = 'invite-action'; + invite.type = 'button'; + invite.textContent = t('bd_center.invite', 'Invite'); + invite.addEventListener('click', function () { + mock.inviteRecords.unshift({ + id: 'inv-' + Date.now(), + status: 'pending', + profile: profile, + }); + state.inviteQuery = ''; + state.inviteMode = 'records'; + state.searched = []; + $('inviteSearchInput').value = ''; + toast( + t('bd_center.invitation_submitted', 'Invitation submitted') + ); + renderInviteModal(); + }); + side.appendChild(invite); + } + + card.appendChild(avatar); + card.appendChild(main); + card.appendChild(side); + return card; + } + + function setInviteStatus(text, type) { + var node = $('inviteStatus'); + node.textContent = text || ''; + node.hidden = !text; + node.classList.toggle('is-error', type === 'error'); + node.classList.toggle('is-success', type === 'success'); + } + + function renderInviteModal() { + var rows = + state.inviteMode === 'search' + ? state.searched.map(inviteCard) + : mock.inviteRecords.map(inviteCard); + setInviteStatus(state.inviteStatus, state.inviteStatusType); + replaceChildren($('inviteList'), rows); + $('inviteEmpty').hidden = + rows.length > 0 || Boolean(state.inviteStatus); + $('inviteSearchButton').disabled = !state.inviteQuery.trim(); + } + + function openInviteModal() { + state.inviteQuery = ''; + state.inviteMode = 'records'; + state.searched = []; + state.inviteStatus = ''; + $('inviteSearchInput').value = ''; + $('inviteModal').hidden = false; + $('inviteModal').setAttribute('aria-hidden', 'false'); + document.body.classList.add('modal-open'); + renderInviteModal(); + window.setTimeout(function () { + $('inviteSearchInput').focus(); + }, 80); + } + + function closeInviteModal() { + $('inviteModal').hidden = true; + $('inviteModal').setAttribute('aria-hidden', 'true'); + document.body.classList.remove('modal-open'); + } + + function searchInvite(event) { + event.preventDefault(); + var query = state.inviteQuery.trim().toLowerCase(); + state.inviteMode = 'search'; + state.inviteStatus = ''; + state.inviteStatusType = ''; + state.searched = mock.searchPool.filter(function (profile) { + return ( + profile.name.toLowerCase().indexOf(query) >= 0 || + profile.account.indexOf(query) >= 0 || + profile.id.indexOf(query) >= 0 + ); + }); + if (!state.searched.length) { + state.inviteStatus = t( + 'bd_center.no_users_found', + 'No users found' + ); + } + renderInviteModal(); + } + + function bindEvents() { + $('backButton').addEventListener('click', function () { + if (window.HyAppBridge) window.HyAppBridge.back(); + }); + $('withdrawExchangeButton').addEventListener('click', function () { + toast( + t( + 'bd_center.mock_navigation', + 'Mock navigation: {label}' + ).replace( + '{label}', + t('bd_center.withdraw_exchange', 'Withdraw/Exchange') + ) + ); + }); + $('inviteAgentButton').addEventListener('click', openInviteModal); + $('inviteBackdrop').addEventListener('click', closeInviteModal); + $('inviteCloseButton').addEventListener('click', closeInviteModal); + $('inviteSearchInput').addEventListener('input', function (event) { + state.inviteQuery = event.target.value; + if (!state.inviteQuery.trim()) { + state.inviteMode = 'records'; + state.searched = []; + state.inviteStatus = ''; + } + renderInviteModal(); + }); + $('inviteSearchForm').addEventListener('submit', searchInvite); + $('billMonthButton').addEventListener('click', openMonthSheet); + $('monthSheetBackdrop').addEventListener('click', closeMonthSheet); + $('monthSheetCloseButton').addEventListener('click', closeMonthSheet); + $('monthOptionList').addEventListener('click', function (event) { + var option = event.target.closest('[data-month]'); + if (!option) return; + selectMonth(option.getAttribute('data-month')); + }); + } + + function render() { + renderProfile(); + renderBalance(); + renderTeamList(); + renderInviteModal(); + } + + document.addEventListener('DOMContentLoaded', function () { + render(); + bindEvents(); + if (window.HyAppBridge) { + window.HyAppBridge.ready({ page: 'bd-center', mock: true }); + } + }); + + window.addEventListener('hyapp:i18n-ready', function () { + render(); + }); +})(); diff --git a/gonghui/bd-center/style.css b/gonghui/bd-center/style.css new file mode 100644 index 0000000..997e084 --- /dev/null +++ b/gonghui/bd-center/style.css @@ -0,0 +1,535 @@ +.role-pill { + display: inline-flex; + align-items: center; + min-height: 24px; + padding: 0 10px; + border-radius: 999px; + background: var(--hy-theme-primary-soft, #f4ebff); + color: var(--primary-deep); + font-size: 12px; + font-weight: 900; +} + +.bd-center .name { + margin-top: 7px; +} + +.salary-card, +.team-stats-card, +.team-users-card { + padding: 16px; +} + +.salary-head, +.team-list-head { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; +} + +.salary-head h2, +.team-list-head h2 { + margin: 0; + color: var(--text); + font-size: 18px; + font-weight: 950; + line-height: 1.2; +} + +.salary-value { + display: flex; + align-items: center; + gap: 10px; + margin-top: 18px; + color: #23272d; + font-size: 34px; + font-weight: 950; + line-height: 1; +} + +.coin-icon { + display: inline-flex; + align-items: center; + justify-content: center; + width: 28px; + height: 28px; + flex: 0 0 28px; + border-radius: 50%; + background: linear-gradient(145deg, #ffe179 0%, #ffb62d 52%, #f49b20 100%); + color: #fff; + font-size: 19px; + font-weight: 950; + box-shadow: + inset 0 1px 2px rgba(255, 255, 255, 0.7), + 0 1px 2px rgba(195, 117, 12, 0.24); +} + +.salary-value strong { + min-width: 0; + overflow-wrap: anywhere; +} + +.team-stats-card, +.team-users-card { + display: grid; + gap: 12px; +} + +.team-list-period { + display: grid; + grid-template-columns: minmax(0, 1fr) auto; + align-items: center; + gap: 10px; +} + +.month-filter { + display: grid; + min-width: 0; + gap: 6px; +} + +.month-filter span { + color: var(--muted); + font-size: 12px; + font-weight: 850; + line-height: 1.2; +} + +.month-trigger { + display: grid; + grid-template-columns: minmax(0, 1fr) 22px; + align-items: center; + gap: 10px; + width: 100%; + min-width: 0; + height: 38px; + padding: 0 10px; + border: 1px solid var(--line); + border-radius: 8px; + background: #fbfcfc; + color: var(--text); + font-size: 13px; + font-weight: 900; + text-align: left; +} + +.month-trigger span { + min-width: 0; + overflow: hidden; + color: var(--text); + font-size: 13px; + font-weight: 900; + line-height: 1.2; + text-overflow: ellipsis; + white-space: nowrap; +} + +.month-trigger svg { + width: 20px; + height: 20px; +} + +.month-trigger path { + fill: none; + stroke: var(--text); + stroke-linecap: round; + stroke-linejoin: round; + stroke-width: 1.8; +} + +.bill-range { + color: var(--muted); + font-size: 12px; + font-weight: 850; + line-height: 1.25; + text-align: right; +} + +.team-list-summary { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 8px; +} + +.team-list-summary > div { + min-width: 0; + padding: 10px; + border-radius: 8px; + background: var(--hy-theme-primary-soft, #f4ebff); +} + +.team-list-summary span { + display: block; + overflow: hidden; + color: var(--muted); + font-size: 11px; + font-weight: 850; + line-height: 1.2; + text-overflow: ellipsis; + white-space: nowrap; +} + +.team-list-summary strong { + display: block; + margin-top: 5px; + overflow-wrap: anywhere; + color: var(--text); + font-size: 15px; + font-weight: 950; + line-height: 1.15; +} + +.team-list-content { + display: grid; + gap: 10px; + max-height: 360px; + overflow-y: auto; + -webkit-overflow-scrolling: touch; +} + +.member-row, +.invite-user-card { + display: grid; + grid-template-columns: 44px minmax(0, 1fr) auto; + gap: 10px; + align-items: center; + padding: 12px; + border: 1px solid var(--line); + border-radius: 8px; + background: #fbfcfc; +} + +.member-avatar, +.invite-user-avatar { + display: flex; + align-items: center; + justify-content: center; + width: 44px; + height: 44px; + overflow: hidden; + border-radius: 50%; + background: var(--primary); +} + +.member-avatar img, +.invite-user-avatar img { + display: block; + width: 100%; + height: 100%; + object-fit: cover; +} + +.member-fallback, +.invite-avatar-fallback { + color: var(--primary-deep); + font-size: 18px; + font-weight: 950; +} + +.member-main, +.invite-user-main { + min-width: 0; +} + +.member-name, +.invite-user-name { + overflow: hidden; + color: var(--text); + font-size: 15px; + font-weight: 900; + line-height: 1.2; + text-overflow: ellipsis; + white-space: nowrap; +} + +.member-meta, +.invite-user-meta { + margin-top: 4px; + overflow: hidden; + color: var(--muted); + font-size: 12px; + font-weight: 800; + line-height: 1.2; + text-overflow: ellipsis; + white-space: nowrap; +} + +.member-side { + display: grid; + gap: 3px; + color: #555b64; + font-size: 12px; + font-weight: 850; + line-height: 1.2; + text-align: right; +} + +.empty-state, +.invite-empty { + display: flex; + align-items: center; + justify-content: center; + min-height: 80px; + border: 1px dashed var(--line); + border-radius: 8px; + color: var(--muted); + font-size: 14px; + font-weight: 850; + text-align: center; +} + +.invite-dialog { + position: relative; + display: flex; + flex-direction: column; + width: min(394px, 100%); + max-height: 80vh; + max-height: 80dvh; + overflow: hidden; + border-radius: 14px; + background: #fff; + box-shadow: 0 18px 44px rgba(23, 31, 42, 0.2); +} + +.month-sheet { + max-height: 62vh; + max-height: 62dvh; +} + +.month-option-list { + display: grid; + gap: 8px; + min-height: 0; + overflow-y: auto; + padding: 12px 18px max(18px, env(safe-area-inset-bottom)); + -webkit-overflow-scrolling: touch; +} + +.month-option { + display: flex; + align-items: center; + justify-content: space-between; + min-height: 44px; + padding: 0 14px; + border: 1px solid var(--line); + border-radius: 8px; + background: #fbfcfc; + color: var(--text); + font-size: 15px; + font-weight: 900; + text-align: left; +} + +.month-option.is-selected { + border-color: transparent; + background: var(--button); + color: #fff; + box-shadow: var( + --hy-theme-button-shadow, + 0 8px 18px rgba(125, 87, 199, 0.18) + ); +} + +.invite-head { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + min-height: 58px; + padding: 16px 18px 12px; + border-bottom: 1px solid var(--line); +} + +.invite-head h2 { + min-width: 0; + margin: 0; + overflow: hidden; + color: var(--text); + font-size: 18px; + font-weight: 950; + line-height: 1.2; + text-overflow: ellipsis; + white-space: nowrap; +} + +.invite-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(--primary-deep); + font-size: 25px; + font-weight: 500; + line-height: 1; +} + +.invite-body { + display: flex; + min-height: 0; + flex: 1 1 auto; + flex-direction: column; + gap: 12px; + overflow-y: auto; + padding: 14px 18px max(18px, env(safe-area-inset-bottom)); + -webkit-overflow-scrolling: touch; +} + +.invite-search-form { + margin: 0; +} + +.invite-field { + display: grid; + gap: 8px; +} + +.invite-field > span { + color: #555b64; + font-size: 13px; + font-weight: 900; + line-height: 1.2; +} + +.invite-search-control { + display: grid; + grid-template-columns: minmax(0, 1fr) auto; + gap: 8px; +} + +.invite-search-control input { + width: 100%; + min-width: 0; + height: 42px; + padding: 0 12px; + border: 1px solid var(--line); + border-radius: 8px; + background: #fbfcfc; + color: var(--text); + font-size: 14px; + font-weight: 800; +} + +.invite-search-control button, +.invite-action, +.invite-cancel { + min-height: 34px; + border-radius: 8px; + font-size: 12px; + font-weight: 950; +} + +.invite-search-control button { + min-width: 76px; + height: 42px; + padding: 0 12px; + background: var(--button); + color: #fff; + box-shadow: var( + --hy-theme-button-shadow, + 0 8px 18px rgba(125, 87, 199, 0.18) + ); +} + +.invite-search-control button:disabled { + background: var(--button-disabled); + box-shadow: var(--hy-theme-button-disabled-shadow, none); +} + +.invite-status { + padding: 10px 12px; + border-radius: 8px; + background: var(--hy-theme-primary-soft, #f4ebff); + color: var(--primary-deep); + font-size: 12px; + font-weight: 850; + line-height: 1.35; +} + +.invite-status.is-error { + background: #fff0f0; + color: #c43f3f; +} + +.invite-status.is-success { + background: #ebfbf2; + color: #128946; +} + +.invite-list { + display: grid; + gap: 10px; +} + +.invite-user-side { + display: grid; + justify-items: end; + gap: 6px; +} + +.invite-action { + min-width: 68px; + padding: 0 12px; + background: var(--button); + color: #fff; +} + +.invite-cancel { + min-width: 68px; + padding: 0 12px; + border: 1px solid rgba(217, 93, 114, 0.24); + background: #fff2f2; + color: var(--danger); +} + +.invite-badge { + min-width: 72px; + padding: 5px 8px; + border-radius: 999px; + font-size: 11px; + font-weight: 950; + line-height: 1; + text-align: center; +} + +.invite-badge.pending { + background: #fff4dc; + color: #bd7a10; +} + +.invite-badge.success { + background: #e9fbf1; + color: #15914f; +} + +@media (max-width: 360px) { + .salary-card, + .team-stats-card, + .team-users-card { + padding-right: 18px; + padding-left: 18px; + } + + .salary-value { + font-size: 29px; + } + + .team-list-summary { + grid-template-columns: 1fr; + } + + .member-row, + .invite-user-card { + grid-template-columns: 44px minmax(0, 1fr); + } + + .member-side, + .invite-user-side { + grid-column: 2; + justify-items: start; + text-align: left; + } +} diff --git a/gonghui/common/center.css b/gonghui/common/center.css new file mode 100644 index 0000000..ada8f8b --- /dev/null +++ b/gonghui/common/center.css @@ -0,0 +1,484 @@ +:root { + --page-bg: var(--hy-theme-bg, #f7f3ff); + --card-bg: var(--hy-theme-surface, rgba(255, 255, 255, 0.96)); + --text: var(--hy-theme-text, #282333); + --muted: var(--hy-theme-muted, #8d879a); + --line: var(--hy-theme-line, #eee7f8); + --primary: var(--hy-theme-primary, #dbc8ff); + --primary-soft: var(--hy-theme-primary-soft, #f4ebff); + --primary-strong: var(--hy-theme-primary-strong, #c5a6f6); + --primary-deep: var(--hy-theme-primary-deep, #7d57c7); + --button: var(--hy-theme-button, #7d57c7); + --button-disabled: var(--hy-theme-button-disabled, #c5a6f6); + --shadow: var(--hy-theme-shadow, 0 10px 26px rgba(109, 69, 189, 0.1)); + --danger: var(--hy-theme-danger, #d95d72); + --success: var(--hy-theme-success, #31c6a8); +} + +* { + box-sizing: border-box; +} + +html, +body { + width: 100%; + min-height: 100%; + margin: 0; + -webkit-font-smoothing: antialiased; + -webkit-text-size-adjust: 100%; + -webkit-tap-highlight-color: transparent; +} + +body { + display: flex; + justify-content: center; + background: #111; + color: var(--text); + font-family: + Inter, + -apple-system, + BlinkMacSystemFont, + 'Segoe UI', + Roboto, + Helvetica, + Arial, + sans-serif; +} + +button, +input { + font: inherit; +} + +button { + border: 0; + padding: 0; + background: transparent; + color: inherit; +} + +button:focus, +input:focus { + outline: none; +} + +button:focus-visible, +input:focus-visible { + outline: 2px solid rgba(125, 87, 199, 0.32); + outline-offset: 2px; +} + +[hidden] { + display: none !important; +} + +.host-center, +.bd-center, +.agency-center { + position: relative; + width: 100%; + max-width: 430px; + min-height: 100vh; + min-height: 100dvh; + overflow: hidden; + background: + linear-gradient( + 145deg, + rgba(255, 255, 255, 0.82), + rgba(250, 246, 255, 0) 42% + ), + var(--page-bg); +} + +.hero-bg { + position: absolute; + inset: 0 0 auto; + height: 215px; + background: var( + --hy-theme-hero, + linear-gradient( + 151deg, + #f0e6ff 0%, + #fffbff 58%, + rgba(250, 246, 255, 0.82) 100% + ) + ); + clip-path: polygon(0 0, 100% 0, 100% 76%, 70% 47%, 40% 58%, 0 78%); +} + +.title-bar, +.content, +.home-indicator { + position: relative; + z-index: 1; +} + +.title-bar { + display: grid; + grid-template-columns: 52px 1fr 52px; + align-items: center; + z-index: 3; + height: 60px; + padding: 0 14px; + direction: ltr; +} + +.title-bar h1 { + margin: 0; + color: var(--text); + font-size: 22px; + font-weight: 900; + line-height: 1; + text-align: center; +} + +.back-button { + display: flex; + align-items: center; + justify-content: flex-start; + width: 44px; + height: 44px; +} + +.back-button svg { + width: 28px; + height: 28px; +} + +.back-button path { + fill: none; + stroke: var(--text); + stroke-linecap: round; + stroke-linejoin: round; + stroke-width: 3; +} + +.language-switcher { + position: relative; + justify-self: end; +} + +.language-button { + display: flex; + align-items: center; + justify-content: center; + width: 42px; + height: 30px; + border: 1px solid rgba(35, 40, 46, 0.12); + border-radius: 15px; + background: rgba(255, 255, 255, 0.68); + color: var(--text); + font-size: 13px; + font-weight: 900; + box-shadow: 0 4px 12px rgba(43, 118, 107, 0.08); +} + +.language-menu { + position: absolute; + z-index: 20; + top: calc(100% + 7px); + right: 0; + display: grid; + gap: 2px; + min-width: 72px; + padding: 5px; + border: 1px solid rgba(35, 40, 46, 0.1); + border-radius: 8px; + background: rgba(255, 255, 255, 0.96); + box-shadow: 0 10px 26px rgba(36, 46, 60, 0.14); +} + +.language-menu button { + min-height: 34px; + border-radius: 6px; + color: var(--text); + font-size: 12px; + font-weight: 900; +} + +.language-menu button.is-active { + background: var(--primary-soft); + color: var(--primary-deep); +} + +.content { + display: flex; + flex-direction: column; + gap: 15px; + padding: 8px 14px 90px; +} + +.card { + width: 100%; + border-radius: 8px; + background: var(--card-bg); + box-shadow: var(--shadow); +} + +.profile-card { + display: flex; + align-items: center; + min-height: 103px; + padding: 16px 24px; +} + +.avatar-shell { + position: relative; + width: 64px; + height: 64px; + flex: 0 0 64px; +} + +.avatar-image, +.avatar-fallback { + width: 64px; + height: 64px; + border-radius: 50%; +} + +.avatar-image { + display: block; + object-fit: cover; +} + +.avatar-fallback { + display: flex; + align-items: center; + justify-content: center; + background: var(--primary); + color: var(--primary-deep); + font-size: 24px; + font-weight: 950; +} + +.profile-copy { + min-width: 0; + margin-left: 20px; +} + +.name { + overflow: hidden; + color: var(--text); + font-size: 20px; + font-weight: 900; + line-height: 1.1; + text-overflow: ellipsis; + white-space: nowrap; +} + +.meta { + margin-top: 6px; + overflow: hidden; + color: var(--muted); + font-size: 13px; + font-weight: 750; + line-height: 1.2; + text-overflow: ellipsis; + white-space: nowrap; +} + +.text-link, +.salary-link { + display: inline-flex; + align-items: center; + justify-content: center; + flex: 0 0 auto; + min-height: 34px; + color: var(--primary-deep); + font-size: 13px; + font-weight: 900; + white-space: nowrap; +} + +.menu-card { + display: grid; + padding: 0 16px; +} + +.menu-row { + display: grid; + grid-template-columns: 38px minmax(0, 1fr) 24px; + gap: 12px; + align-items: center; + min-height: 64px; + border-bottom: 1px solid var(--line); + text-align: left; +} + +.menu-row:last-child { + border-bottom: 0; +} + +.menu-icon { + display: flex; + align-items: center; + justify-content: center; + width: 34px; + height: 34px; + border-radius: 50%; + background: var(--primary-soft); + color: var(--primary-deep); +} + +.menu-icon svg { + width: 20px; + height: 20px; +} + +.menu-icon path { + fill: none; + stroke: currentColor; + stroke-linecap: round; + stroke-linejoin: round; + stroke-width: 2; +} + +.menu-label { + min-width: 0; + overflow: hidden; + color: #464951; + font-size: 16px; + font-weight: 850; + line-height: 1.2; + text-overflow: ellipsis; + white-space: nowrap; +} + +.menu-count { + color: var(--muted); + font-size: 13px; + font-weight: 900; + white-space: nowrap; +} + +.chevron { + color: var(--muted); + font-size: 24px; + font-weight: 500; + line-height: 1; + text-align: right; +} + +.sheet-modal, +.message-modal, +.invite-modal { + position: fixed; + z-index: 24; + inset: 0; + display: flex; + justify-content: center; +} + +.sheet-modal { + align-items: flex-end; + padding: 0 0 env(safe-area-inset-bottom); +} + +.message-modal, +.invite-modal { + align-items: center; + padding: 18px; +} + +.modal-backdrop { + position: absolute; + inset: 0; + background: rgba(15, 21, 28, 0.38); +} + +.bottom-sheet { + position: relative; + display: flex; + flex-direction: column; + width: min(430px, 100%); + max-height: 80vh; + max-height: 80dvh; + overflow: hidden; + border-radius: 16px 16px 0 0; + background: #fff; + box-shadow: 0 -14px 34px rgba(23, 31, 42, 0.16); +} + +.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(--line); +} + +.sheet-head h2 { + margin: 0; + color: var(--text); + 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(--primary-soft); + color: var(--primary-deep); + font-size: 25px; + font-weight: 500; + line-height: 1; +} + +.home-indicator { + position: absolute; + left: 50%; + bottom: 8px; + width: 154px; + height: 5px; + border-radius: 999px; + background: #050506; + transform: translateX(-50%); +} + +.modal-open { + overflow: hidden; +} + +[dir='rtl'] .content, +[dir='rtl'] .bottom-sheet, +[dir='rtl'] .message-dialog, +[dir='rtl'] .invite-dialog { + direction: rtl; +} + +[dir='rtl'] .profile-copy { + margin-right: 20px; + margin-left: 0; + text-align: right; +} + +[dir='rtl'] .menu-row { + text-align: right; +} + +[dir='rtl'] .chevron { + transform: rotate(180deg); +} + +@media (max-width: 360px) { + .content { + padding-right: 12px; + padding-left: 12px; + } + + .profile-card { + padding-right: 18px; + padding-left: 18px; + } + + .profile-copy { + margin-left: 14px; + } +} diff --git a/gonghui/host-center/index.html b/gonghui/host-center/index.html new file mode 100644 index 0000000..0347ca5 --- /dev/null +++ b/gonghui/host-center/index.html @@ -0,0 +1,160 @@ + + + + + + Host Center + + + + + + +
+ + + + +
+
+
+ + +
+
+
Yumi_Host
+
UID: 1688008
+
+
+
+ +
+
+

+ My available salary +

+ +
+
+ + +
+
+
+ +
+
+

+ Level progress +

+ +
+
+
+ Current level + +
+
+ Needed for next level + +
+
+ +
+ + +
+ + +
+ + + + + + + + + diff --git a/gonghui/host-center/script.js b/gonghui/host-center/script.js new file mode 100644 index 0000000..a708eca --- /dev/null +++ b/gonghui/host-center/script.js @@ -0,0 +1,471 @@ +(function () { + var HOST_SALARY_USD = 'HOST_SALARY_USD'; + var HOST_LEVEL_TRACK = 'charm'; + + var mock = { + profile: { + name: 'quick_1780052629537', + uid: '163000', + avatar: avatarData('Y', '#dbc8ff', '#7d57c7'), + }, + agency: { + shortId: '163003', + }, + salary: { + available: 30650.75, + monthKey: 'host_center.month_june', + month: 'June', + currencyKey: 'host_center.currency_usd', + currency: 'USD', + useCurrentMonth: false, + }, + level: { + current: 3, + currentRequired: 0, + currentValue: 2450, + nextValue: 4000, + }, + }; + + var state = cloneHostState(mock); + + function $(id) { + return document.getElementById(id); + } + + function cloneHostState(value) { + return { + profile: Object.assign({}, value.profile), + agency: Object.assign({}, value.agency), + salary: Object.assign({}, value.salary), + level: Object.assign({}, value.level), + }; + } + + function avatarData(text, background, foreground) { + var value = + String(text || 'Y') + .trim() + .charAt(0) || 'Y'; + var letter = value.replace(/[<>&"']/g, ''); + var svg = + '' + + '' + + '' + + letter + + '' + + ''; + 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 money(value) { + var number = Number(value || 0); + return number.toLocaleString('en-US', { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + }); + } + + function initial(text) { + return String(text || '') + .trim() + .charAt(0) + .toUpperCase(); + } + + function queryValue(name) { + return new URLSearchParams(window.location.search).get(name); + } + + function isMockMode() { + return queryValue('mock') === '1'; + } + + function hasAccessToken() { + return ( + window.HyAppAPI && + window.HyAppAPI.getAccessToken && + !!window.HyAppAPI.getAccessToken() + ); + } + + function unwrapData(payload) { + if (!payload || typeof payload !== 'object') return payload; + return Object.prototype.hasOwnProperty.call(payload, 'data') + ? payload.data + : payload; + } + + 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 toNumber(value) { + var number = Number(value); + return Number.isFinite(number) ? number : 0; + } + + function safeRequest(factory) { + return factory().catch(function (error) { + if (window.console && window.console.warn) { + window.console.warn('[host-center] api failed', error); + } + return null; + }); + } + + 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 currentMonthName() { + try { + return new Date().toLocaleString(currentLocale(), { + month: 'long', + }); + } catch (_) { + return 'June'; + } + } + + function salaryMonthLabel(salary) { + if (salary.monthKey) return t(salary.monthKey, salary.month); + if (salary.useCurrentMonth) return currentMonthName(); + return salary.month || currentMonthName(); + } + + function salaryCurrencyLabel(salary) { + if (salary.currencyKey) return t(salary.currencyKey, salary.currency); + return salary.currency || t('host_center.currency_usd', 'USD'); + } + + function renderProfile() { + var image = $('profileAvatar'); + var fallback = $('profileAvatarFallback'); + var badge = $('profileBadge'); + var profile = state.profile; + var agency = state.agency; + + $('profileName').textContent = profile.name || 'User'; + $('profileUID').textContent = 'UID: ' + (profile.uid || '-'); + fallback.textContent = initial(profile.name || profile.uid) || 'Y'; + + if (agency.shortId) { + badge.hidden = false; + badge.textContent = t( + 'host_center.agency_short_id', + 'Agency ID: {id}' + ).replace('{id}', agency.shortId); + } else { + badge.hidden = true; + badge.textContent = ''; + } + + if (!profile.avatar) { + 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 = profile.avatar; + } + + function renderIncome() { + var salary = state.salary; + $('availableSalary').textContent = money(salary.available); + $('incomeFoot').textContent = t( + 'host_center.salary_month_note', + '{month} settlement · {currency}' + ) + .replace('{month}', salaryMonthLabel(salary)) + .replace('{currency}', salaryCurrencyLabel(salary)); + } + + function renderLevel() { + var level = state.level; + var currentRequired = toNumber(level.currentRequired); + var currentValue = toNumber(level.currentValue); + var nextValue = toNumber(level.nextValue); + var need = Math.max(0, nextValue - currentValue); + var denominator = Math.max(1, nextValue - currentRequired); + var currentInLevel = Math.max(0, currentValue - currentRequired); + var percent = + nextValue > currentRequired + ? Math.min( + 100, + Math.round((currentInLevel / denominator) * 100) + ) + : 100; + + $('currentLevel').textContent = t( + 'host_center.level_value', + 'Lv. {level}' + ).replace('{level}', String(level.current || 0)); + $('nextLevelNeed').textContent = money(need); + $('levelProgress').style.width = percent + '%'; + $('levelStatus').textContent = t( + 'host_center.in_progress', + 'In progress' + ); + } + + function render() { + renderProfile(); + renderIncome(); + renderLevel(); + } + + function applyProfile(payload) { + var profile = unwrapData(payload); + if (!profile) return; + + var name = firstValue(profile, [ + 'username', + 'nickname', + 'name', + 'display_name', + ]); + var uid = firstValue(profile, [ + 'display_user_id', + 'default_display_user_id', + 'uid', + 'user_id', + ]); + var avatar = firstValue(profile, ['avatar', 'avatar_url', 'avatarUrl']); + + state.profile = { + name: name || state.profile.name, + uid: uid || state.profile.uid, + avatar: + avatar || + avatarData( + initial(name || uid || state.profile.name), + '#dbc8ff', + '#7d57c7' + ), + }; + } + + function applyRoleSummary(payload) { + var summary = unwrapData(payload); + if (!summary) return; + + var agencyId = firstValue(summary, [ + 'agency_id', + 'agencyId', + 'host_agency_id', + 'hostAgencyId', + ]); + state.agency = { + shortId: agencyId ? String(agencyId) : '', + }; + } + + function displayAmountForAsset(assetType, amount) { + if (assetType === HOST_SALARY_USD) return toNumber(amount) / 100; + return toNumber(amount); + } + + function findBalance(payload, assetType) { + var data = unwrapData(payload); + var balances = + data && Array.isArray(data.balances) ? data.balances : []; + for (var i = 0; i < balances.length; i += 1) { + if ( + balances[i].asset_type === assetType || + balances[i].assetType === assetType + ) { + return balances[i]; + } + } + return null; + } + + function applyWallet(payload) { + var balance = findBalance(payload, HOST_SALARY_USD); + if (!balance) return; + + var amount = firstValue(balance, [ + 'available_amount', + 'availableAmount', + ]); + state.salary = Object.assign({}, state.salary, { + available: displayAmountForAsset(HOST_SALARY_USD, amount), + monthKey: '', + month: '', + currencyKey: 'host_center.currency_usd', + currency: 'USD', + useCurrentMonth: true, + }); + } + + function pickLevelTrack(payload) { + var data = unwrapData(payload); + var tracks = data && Array.isArray(data.tracks) ? data.tracks : []; + if (!tracks.length) return null; + + for (var i = 0; i < tracks.length; i += 1) { + if (tracks[i].track === HOST_LEVEL_TRACK) return tracks[i]; + } + return tracks[0]; + } + + function applyLevel(payload) { + var track = pickLevelTrack(payload); + if (!track) return; + + state.level = { + current: toNumber( + firstValue(track, ['level', 'current_level', 'currentLevel']) + ), + currentRequired: toNumber( + firstValue(track, [ + 'current_level_required_value', + 'currentLevelRequiredValue', + ]) + ), + currentValue: toNumber( + firstValue(track, ['total_value', 'totalValue']) + ), + nextValue: toNumber( + firstValue(track, [ + 'next_level_required_value', + 'nextLevelRequiredValue', + 'total_value', + 'totalValue', + ]) + ), + }; + } + + function toast(message) { + if (!message) return; + if (window.HyAppToast && window.HyAppToast.show) { + window.HyAppToast.show(message); + } + } + + function loadRealData() { + if (isMockMode() || !window.HyAppAPI) return Promise.resolve(false); + if (window.HyAppParams && window.HyAppParams.parse) { + window.HyAppParams.parse(); + } + if (!hasAccessToken()) return Promise.resolve(false); + + return Promise.all([ + safeRequest(function () { + return window.HyAppAPI.user.me(); + }), + safeRequest(function () { + return window.HyAppAPI.user.roleSummary(); + }), + safeRequest(function () { + return window.HyAppAPI.wallet.balances([HOST_SALARY_USD]); + }), + safeRequest(function () { + return window.HyAppAPI.level.overview(); + }), + ]).then(function (results) { + applyProfile(results[0]); + applyRoleSummary(results[1]); + applyWallet(results[2]); + applyLevel(results[3]); + render(); + + var hasAnyData = results.some(function (item) { + return !!item; + }); + if (!hasAnyData) { + toast( + t( + 'host_center.load_failed', + 'Load failed. Try again later.' + ) + ); + } + return hasAnyData; + }); + } + + function openWithdrawExchange() { + var params = new URLSearchParams(window.location.search); + params.set('mode', params.get('mode') || 'transfer'); + window.location.href = + '../withdraw-exchange/index.html?' + params.toString(); + } + + function bindEvents() { + $('backButton').addEventListener('click', function () { + if (window.HyAppBridge) window.HyAppBridge.back(); + }); + + $('incomeWithdrawExchangeButton').addEventListener( + 'click', + openWithdrawExchange + ); + } + + var initialized = false; + + function init() { + if (initialized) return; + initialized = true; + render(); + bindEvents(); + loadRealData().then(function (loaded) { + if (window.HyAppBridge) { + window.HyAppBridge.ready({ + page: 'host-center', + mock: !loaded, + }); + } + }); + } + + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', init); + } else { + init(); + } + + window.addEventListener('hyapp:i18n-ready', function () { + render(); + }); +})(); diff --git a/gonghui/host-center/style.css b/gonghui/host-center/style.css new file mode 100644 index 0000000..db317e7 --- /dev/null +++ b/gonghui/host-center/style.css @@ -0,0 +1,151 @@ +.profile-badge { + display: inline-flex; + align-items: center; + margin-top: 8px; + padding: 5px 9px; + border-radius: 999px; + background: var(--hy-theme-primary-soft, #f4ebff); + color: var(--primary-deep); + font-size: 13px; + font-weight: 750; + line-height: 1.2; +} + +.income-card, +.task-card { + padding: 16px; +} + +.section-head, +.income-head { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; +} + +.section-head h2, +.income-head h2 { + min-width: 0; + margin: 0; + overflow: hidden; + color: var(--text); + font-size: 18px; + font-weight: 950; + line-height: 1.2; + text-overflow: ellipsis; + white-space: nowrap; +} + +.income-value { + display: flex; + align-items: center; + gap: 10px; + margin-top: 18px; + color: #23272d; + font-size: 34px; + font-weight: 950; + line-height: 1; +} + +.coin-icon { + display: inline-flex; + align-items: center; + justify-content: center; + width: 28px; + height: 28px; + flex: 0 0 28px; + border-radius: 50%; + background: linear-gradient(145deg, #ffe179 0%, #ffb62d 52%, #f49b20 100%); + color: #fff; + font-size: 19px; + font-weight: 950; + box-shadow: + inset 0 1px 2px rgba(255, 255, 255, 0.7), + 0 1px 2px rgba(195, 117, 12, 0.24); +} + +.income-foot { + margin-top: 12px; + color: var(--muted); + font-size: 13px; + font-weight: 800; + line-height: 1.35; +} + +.task-pill { + display: inline-flex; + align-items: center; + justify-content: center; + min-height: 28px; + padding: 0 10px; + border-radius: 999px; + background: var(--hy-theme-primary-soft, #f4ebff); + color: var(--primary-deep); + font-size: 12px; + font-weight: 900; +} + +.task-grid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 10px; + margin-top: 16px; +} + +.task-item { + min-width: 0; +} + +.task-item > span { + display: block; + overflow: hidden; + color: var(--muted); + font-size: 12px; + font-weight: 800; + line-height: 1.2; + text-overflow: ellipsis; + white-space: nowrap; +} + +.task-item strong { + display: block; + margin-top: 6px; + overflow-wrap: anywhere; + color: #292d33; + font-size: 17px; + font-weight: 950; + line-height: 1.2; +} + +.progress-track { + height: 9px; + margin-top: 16px; + overflow: hidden; + border-radius: 999px; + background: var(--hy-theme-primary-soft, #f4ebff); +} + +.progress-fill { + width: 0; + height: 100%; + border-radius: inherit; + background: var(--button); + transition: width 0.2s ease; +} + +@media (max-width: 360px) { + .income-card, + .task-card { + padding-right: 18px; + padding-left: 18px; + } + + .income-value { + font-size: 29px; + } + + .task-grid { + grid-template-columns: 1fr; + } +} diff --git a/gonghui/withdraw-exchange/index.html b/gonghui/withdraw-exchange/index.html new file mode 100644 index 0000000..31f7643 --- /dev/null +++ b/gonghui/withdraw-exchange/index.html @@ -0,0 +1,379 @@ + + + + + + Withdraw/Exchange + + + + + +
+ + + + +
+
+
+
+ salary +
+ +
+
+ + 0.00 +
+
+ +
+
+ + + +
+ +
+ +
+ Minimum 50 USD + +
+
+ +
+ +
+ Exchange rate + +
+
+ +
+
+ Transfer to + +
+ + +
+
+ +
+
+
+
+ USDT TRC20 address +
+
+ Withdrawals are sent to your TRC20 USDT address. +
+
+
+ +
+ +
+
+ No USDT address +
+
+ Fill in a TRC20 USDT address before withdrawing. +
+
+
+ +
+ + +
+ + +
+ + +
+ + + + +
+ + + + + + + diff --git a/gonghui/withdraw-exchange/script.js b/gonghui/withdraw-exchange/script.js new file mode 100644 index 0000000..e1866a2 --- /dev/null +++ b/gonghui/withdraw-exchange/script.js @@ -0,0 +1,589 @@ +(function () { + var EXCHANGE_RATE = 80000; + var WITHDRAW_MIN_AMOUNT = 50; + var params = new URLSearchParams(window.location.search); + var currentMode = normalizeMode(params.get('mode')) || 'transfer'; + var state = { + balance: 0, + paymentInfo: null, + selectedPayee: null, + isSearching: false, + isSaving: false, + isSubmitting: false, + historyItems: [], + }; + var lastSearchTriggerAt = 0; + var autoSearchTimer = 0; + + var mock = { + balance: 30650.75, + paymentInfo: null, + payees: { + 163003: { + id: 'payee_163003', + name: 'Yumi Star Agency', + account: '163003', + avatar: '', + }, + 163000: { + id: 'payee_163000', + name: 'quick_1780052629537', + account: '163000', + avatar: '', + }, + }, + history: [ + { + key: 'withdraw_exchange.history_host_salary', + title: 'Host salary', + amount: 18400.25, + balance: 30650.75, + type: 0, + date: '2026-06-01 12:10', + }, + { + key: 'withdraw_exchange.history_exchange_to_golds', + title: 'Exchange to golds', + amount: 800, + balance: 12250.5, + type: 1, + date: '2026-05-30 20:42', + }, + { + key: 'withdraw_exchange.history_gift_reward', + title: 'Gift reward', + amount: 8250.5, + balance: 13050.5, + type: 0, + date: '2026-05-28 18:30', + }, + ], + }; + + var inputs = { + withdraw: $('withdrawAmount'), + exchange: $('exchangeAmount'), + transfer: $('transferAmount'), + }; + + function $(id) { + return document.getElementById(id); + } + + function t(key, fallback) { + return window.HyAppI18n && window.HyAppI18n.t + ? window.HyAppI18n.t(key, fallback) + : fallback || key; + } + + function toast(message) { + if (window.HyAppToast) { + window.HyAppToast.show(message); + return; + } + window.alert(message); + } + + function normalizeMode(mode) { + var value = String(mode || '').trim(); + return ['withdraw', 'exchange', 'transfer'].indexOf(value) >= 0 + ? value + : ''; + } + + function money(value) { + var number = Number(value || 0); + return number.toLocaleString('en-US', { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + }); + } + + function moneyInput(value) { + var number = Number(value || 0); + return Number.isFinite(number) ? number.toFixed(2) : '0.00'; + } + + function amount() { + var input = inputs[currentMode]; + return Number(input && input.value ? input.value : 0) || 0; + } + + function delay(value) { + return new Promise(function (resolve) { + window.setTimeout(function () { + resolve(value); + }, 260); + }); + } + + function mockRequest(action, payload) { + if (action === 'balance') return delay(mock.balance); + if (action === 'payment') return delay(mock.paymentInfo); + if (action === 'history') return delay(mock.history.slice()); + if (action === 'saveAddress') { + mock.paymentInfo = { + id: 'usdt_mock_1', + cardNo: payload.cardNo, + }; + return delay(mock.paymentInfo); + } + if (action === 'searchPayee') { + var account = String(payload.account || '').trim(); + var payee = mock.payees[account]; + if (!payee && account && account !== '000000') { + payee = { + id: 'payee_' + account, + name: 'User ' + account, + nameKey: 'withdraw_exchange.mock_user_name', + account: account, + avatar: '', + }; + } + return delay(payee || null); + } + if (action === 'submit') { + mock.balance = Math.max(0, mock.balance - payload.amount); + mock.history.unshift({ + title: titleForMode(payload.mode), + amount: payload.amount, + balance: mock.balance, + type: 1, + date: new Date().toISOString().replace('T', ' ').slice(0, 16), + }); + return delay({ ok: true }); + } + return delay(null); + } + + function titleForMode(mode) { + if (mode === 'withdraw') + return t('withdraw_exchange.withdraw', 'Withdraw'); + if (mode === 'exchange') + return t('withdraw_exchange.exchange', 'Exchange'); + return t('withdraw_exchange.transfer', 'Transfer'); + } + + function isValidTrc20(value) { + return /^T[1-9A-HJ-NP-Za-km-z]{33}$/.test(String(value || '').trim()); + } + + function maskAddress(value) { + var text = String(value || '').trim(); + if (text.length <= 12) return text || '-'; + return text.slice(0, 6) + '...' + text.slice(-6); + } + + function activeSubmitLabel() { + if (currentMode === 'withdraw') + return t('withdraw_exchange.withdraw_now', 'Withdraw now'); + if (currentMode === 'exchange') + return t('withdraw_exchange.exchange_now', 'Exchange now'); + return t('withdraw_exchange.transfer_now', 'Transfer now'); + } + + function renderBalance() { + $('balanceAmount').textContent = money(state.balance); + Object.keys(inputs).forEach(function (key) { + if (inputs[key]) inputs[key].max = moneyInput(state.balance); + }); + } + + function renderMode() { + document.querySelectorAll('.mode-tab').forEach(function (tab) { + var active = tab.getAttribute('data-mode') === currentMode; + tab.classList.toggle('active', active); + tab.setAttribute('aria-selected', String(active)); + }); + document.querySelectorAll('.mode-panel').forEach(function (panel) { + panel.classList.toggle( + 'active', + panel.getAttribute('data-panel') === currentMode + ); + }); + $('paymentSection').hidden = currentMode !== 'withdraw'; + updateSubmit(); + } + + function renderPaymentInfo() { + var payment = state.paymentInfo; + $('emptyAddressState').hidden = Boolean(payment); + $('addressForm').hidden = Boolean(payment); + $('boundAddressCard').hidden = !payment; + if (payment) + $('boundAddress').textContent = maskAddress(payment.cardNo); + updateSubmit(); + } + + function renderPayee() { + var result = $('payeeResult'); + result.textContent = ''; + if (!state.selectedPayee) { + result.hidden = true; + updateSubmit(); + return; + } + + var payee = state.selectedPayee; + var payeeName = payee.nameKey + ? t(payee.nameKey, payee.name || 'User {account}').replace( + '{account}', + payee.account + ) + : payee.name; + var avatar = document.createElement('div'); + var copy = document.createElement('div'); + var name = document.createElement('div'); + var id = document.createElement('div'); + avatar.className = 'payee-avatar'; + copy.className = 'payee-copy'; + name.className = 'payee-name'; + id.className = 'payee-id'; + avatar.textContent = String(payeeName || 'U') + .charAt(0) + .toUpperCase(); + name.textContent = payeeName || '-'; + id.textContent = + t('withdraw_exchange.uid_prefix', 'UID:') + ' ' + payee.account; + copy.appendChild(name); + copy.appendChild(id); + result.appendChild(avatar); + result.appendChild(copy); + result.hidden = false; + updateSubmit(); + } + + function renderHistory() { + $('salaryHistoryTotal').textContent = '$' + money(state.balance); + var list = $('salaryHistoryList'); + list.textContent = ''; + if (!state.historyItems.length) { + var empty = document.createElement('div'); + empty.className = 'salary-history-empty'; + empty.textContent = t( + 'withdraw_exchange.no_salary_history', + 'No salary history' + ); + list.appendChild(empty); + return; + } + + state.historyItems.forEach(function (item) { + var row = document.createElement('article'); + var main = document.createElement('div'); + var title = document.createElement('div'); + var meta = document.createElement('div'); + var value = document.createElement('div'); + var isOut = Number(item.type) === 1; + row.className = 'salary-history-item'; + main.className = 'salary-history-item-main'; + title.className = 'salary-history-item-title'; + meta.className = 'salary-history-item-meta'; + value.className = + 'salary-history-amount' + (isOut ? ' is-out' : ''); + title.textContent = item.key ? t(item.key, item.title) : item.title; + meta.textContent = + item.date + + ' ' + + t('withdraw_exchange.balance', 'Balance') + + ': $' + + money(item.balance); + value.textContent = (isOut ? '-' : '+') + '$' + money(item.amount); + main.appendChild(title); + main.appendChild(meta); + row.appendChild(main); + row.appendChild(value); + list.appendChild(row); + }); + } + + function updateSubmit() { + var button = $('submitButton'); + if (state.isSubmitting) { + button.textContent = t( + 'withdraw_exchange.submitting', + 'Submitting...' + ); + button.disabled = true; + return; + } + + var value = amount(); + var disabled = + value <= 0 || + value > state.balance || + (currentMode === 'withdraw' && + (!state.paymentInfo || value < WITHDRAW_MIN_AMOUNT)) || + (currentMode === 'transfer' && !state.selectedPayee); + button.textContent = activeSubmitLabel(); + button.disabled = disabled; + } + + function normalizeAmount(event) { + var input = event.target; + var raw = String(input.value || '').replace(/[^\d.]/g, ''); + var parts = raw.split('.'); + var next = + parts.length > 2 ? parts[0] + '.' + parts.slice(1).join('') : raw; + var value = Number(next); + if (Number.isFinite(value) && value > state.balance) + next = moneyInput(state.balance); + input.value = next; + updateSubmit(); + } + + function setMode(mode) { + currentMode = normalizeMode(mode) || 'transfer'; + renderMode(); + } + + function openHistory() { + $('salaryHistoryModal').hidden = false; + document.body.classList.add('modal-open'); + $('salaryHistoryList').textContent = t( + 'withdraw_exchange.loading', + 'Loading...' + ); + mockRequest('history').then(function (items) { + state.historyItems = items || []; + renderHistory(); + }); + } + + function closeHistory() { + $('salaryHistoryModal').hidden = true; + document.body.classList.remove('modal-open'); + } + + function saveAddress() { + var address = String($('trc20Address').value || '').trim(); + if (!isValidTrc20(address)) { + toast( + t( + 'withdraw_exchange.invalid_address', + 'Please enter a valid TRC20 USDT address' + ) + ); + return; + } + state.isSaving = true; + $('saveAddressButton').disabled = true; + $('saveAddressButton').textContent = t( + 'withdraw_exchange.saving', + 'Saving...' + ); + mockRequest('saveAddress', { cardNo: address }).then( + function (payment) { + state.paymentInfo = payment; + state.isSaving = false; + $('saveAddressButton').disabled = false; + $('saveAddressButton').textContent = t( + 'withdraw_exchange.save_address', + 'Save address' + ); + renderPaymentInfo(); + toast(t('withdraw_exchange.address_saved', 'Address saved')); + } + ); + } + + function searchPayee() { + var now = Date.now(); + if (now - lastSearchTriggerAt < 240) return; + lastSearchTriggerAt = now; + + var account = String($('transferAccount').value || '').trim(); + if (!account) { + toast( + t( + 'withdraw_exchange.missing_payee', + 'Please search and select a user' + ) + ); + return; + } + state.selectedPayee = null; + renderPayee(); + state.isSearching = true; + $('searchPayeeButton').disabled = true; + $('searchPayeeButton').textContent = t( + 'withdraw_exchange.searching', + 'Searching...' + ); + mockRequest('searchPayee', { account: account }).then(function (payee) { + state.isSearching = false; + $('searchPayeeButton').disabled = false; + $('searchPayeeButton').textContent = t( + 'withdraw_exchange.search', + 'Search' + ); + if (!payee) { + toast(t('withdraw_exchange.payee_not_found', 'User not found')); + return; + } + state.selectedPayee = payee; + renderPayee(); + }); + } + + function validateSubmit() { + var value = amount(); + if (value <= 0) + return t( + 'withdraw_exchange.invalid_amount', + 'Please enter a valid amount' + ); + if (value > state.balance) + return t( + 'withdraw_exchange.amount_exceeds_balance', + 'Amount exceeds salary' + ); + if (currentMode === 'withdraw' && !state.paymentInfo) + return t( + 'withdraw_exchange.missing_payment_info', + 'Please add a TRC20 USDT address' + ); + if (currentMode === 'withdraw' && value < WITHDRAW_MIN_AMOUNT) + return t( + 'withdraw_exchange.amount_too_low', + 'Minimum withdrawal amount is 50 USD' + ); + if (currentMode === 'transfer' && !state.selectedPayee) + return t( + 'withdraw_exchange.missing_payee', + 'Please search and select a user' + ); + return ''; + } + + function submit() { + var error = validateSubmit(); + if (error) { + toast(error); + return; + } + state.isSubmitting = true; + updateSubmit(); + mockRequest('submit', { + mode: currentMode, + amount: amount(), + payee: state.selectedPayee, + paymentInfo: state.paymentInfo, + }).then(function () { + var input = inputs[currentMode]; + if (input) input.value = ''; + if (currentMode === 'transfer') { + state.selectedPayee = null; + $('transferAccount').value = ''; + renderPayee(); + } + state.balance = mock.balance; + state.isSubmitting = false; + renderBalance(); + updateSubmit(); + var key = + currentMode === 'withdraw' + ? 'withdraw_exchange.withdraw_success' + : currentMode === 'exchange' + ? 'withdraw_exchange.exchange_success' + : 'withdraw_exchange.transfer_success'; + toast(t(key, 'Submitted')); + }); + } + + function goBack() { + if (window.history.length > 1) { + window.history.back(); + return; + } + var nextParams = new URLSearchParams(window.location.search); + nextParams.delete('mode'); + var query = nextParams.toString(); + window.location.href = + '../host-center/index.html' + (query ? '?' + query : ''); + } + + function bindEvents() { + function bindTap(id, handler) { + var node = $(id); + var last = 0; + function run(event) { + var now = Date.now(); + if (now - last < 220) return; + last = now; + if (event && event.type === 'pointerdown') { + event.preventDefault(); + } + handler(event); + } + node.addEventListener('pointerdown', run); + node.addEventListener('click', run); + } + + bindTap('backButton', goBack); + document.querySelectorAll('.mode-tab').forEach(function (tab) { + tab.addEventListener('click', function () { + setMode(tab.getAttribute('data-mode')); + }); + }); + Object.keys(inputs).forEach(function (key) { + if (inputs[key]) + inputs[key].addEventListener('input', normalizeAmount); + }); + bindTap('allButton', function () { + inputs.withdraw.value = moneyInput(state.balance); + updateSubmit(); + }); + $('transferAccount').addEventListener('input', function () { + state.selectedPayee = null; + renderPayee(); + window.clearTimeout(autoSearchTimer); + if (String($('transferAccount').value || '').trim().length >= 3) { + autoSearchTimer = window.setTimeout(searchPayee, 260); + } + }); + $('transferAccount').addEventListener('keydown', function (event) { + if (event.key === 'Enter') searchPayee(); + }); + bindTap('searchPayeeButton', searchPayee); + bindTap('saveAddressButton', saveAddress); + bindTap('submitButton', submit); + bindTap('salaryHistoryButton', openHistory); + bindTap('salaryHistoryBackdrop', closeHistory); + bindTap('salaryHistoryCloseButton', closeHistory); + } + + function renderStaticDynamicText() { + $('exchangeRateText').textContent = t( + 'withdraw_exchange.exchange_rate_value', + '1$ = {amount} golds' + ).replace('{amount}', EXCHANGE_RATE.toLocaleString('en-US')); + if (!$('salaryHistoryModal').hidden) renderHistory(); + updateSubmit(); + renderPayee(); + } + + function init() { + bindEvents(); + setMode(currentMode); + renderStaticDynamicText(); + mockRequest('balance').then(function (balance) { + state.balance = balance; + renderBalance(); + updateSubmit(); + }); + mockRequest('payment').then(function (payment) { + state.paymentInfo = payment; + renderPaymentInfo(); + }); + if (window.HyAppBridge) { + window.HyAppBridge.ready({ + page: 'withdraw-exchange', + mock: true, + }); + } + } + + document.addEventListener('DOMContentLoaded', init); + window.addEventListener('hyapp:i18n-ready', renderStaticDynamicText); +})(); diff --git a/gonghui/withdraw-exchange/style.css b/gonghui/withdraw-exchange/style.css new file mode 100644 index 0000000..6cb6b6d --- /dev/null +++ b/gonghui/withdraw-exchange/style.css @@ -0,0 +1,848 @@ +:root { + --page-bg: var(--hy-theme-bg, #fbf8ff); + --card-bg: var(--hy-theme-surface, rgba(255, 255, 255, 0.96)); + --text: var(--hy-theme-text, #282333); + --muted: var(--hy-theme-muted, #8d879a); + --soft: var(--hy-theme-primary-soft, #f4ebff); + --line: var(--hy-theme-line, #f0e8fb); + --primary: var(--hy-theme-primary, #dbc8ff); + --primary-strong: var(--hy-theme-primary-strong, #c5a6f6); + --primary-deep: var(--hy-theme-primary-deep, #7d57c7); + --gold: #e3b55b; + --shadow: var(--hy-theme-shadow, 0 10px 24px rgba(132, 90, 212, 0.075)); + --button: var(--hy-theme-button, #7d57c7); + --button-disabled: var(--hy-theme-button-disabled, #eadffc); + --button-disabled-text: var(--hy-theme-button-disabled-text, #9a8faa); +} + +* { + box-sizing: border-box; +} + +html, +body { + width: 100%; + min-height: 100%; + margin: 0; + -webkit-font-smoothing: antialiased; + -webkit-text-size-adjust: 100%; + -webkit-tap-highlight-color: transparent; +} + +body { + display: flex; + justify-content: center; + background: #111; + color: var(--text); + font-family: + Inter, + -apple-system, + BlinkMacSystemFont, + 'Segoe UI', + Roboto, + Helvetica, + Arial, + sans-serif; +} + +button, +input { + font: inherit; +} + +button { + border: 0; + padding: 0; + background: transparent; + color: inherit; +} + +button:focus { + outline: none; +} + +button:focus-visible { + outline: 2px solid rgba(125, 87, 199, 0.28); + outline-offset: 2px; +} + +input { + width: 100%; + border: 0; + outline: 0; + background: transparent; + color: var(--text); +} + +[hidden] { + display: none !important; +} + +.withdraw-exchange-page { + position: relative; + width: 100%; + max-width: 430px; + min-height: 100vh; + min-height: 100dvh; + overflow: hidden auto; + background: var(--page-bg); +} + +.hero-bg { + position: absolute; + inset: 0 0 auto; + height: 215px; + background: var( + --hy-theme-hero, + linear-gradient( + 151deg, + #f0e6ff 0%, + #fffbff 58%, + rgba(251, 248, 255, 0.88) 100% + ) + ); + clip-path: polygon(0 0, 100% 0, 100% 76%, 70% 47%, 40% 58%, 0 78%); +} + +.title-bar, +.content, +.home-indicator { + position: relative; + z-index: 1; +} + +.title-bar { + display: grid; + grid-template-columns: 52px 1fr 52px; + align-items: center; + z-index: 12; + height: 60px; + padding: 0 14px; + direction: ltr; +} + +.title-bar h1 { + margin: 0; + color: #24282e; + font-size: 22px; + font-weight: 950; + line-height: 1; + text-align: center; +} + +.back-button { + display: flex; + align-items: center; + justify-content: flex-start; + width: 44px; + height: 44px; +} + +.back-button svg { + width: 28px; + height: 28px; +} + +.back-button path { + fill: none; + stroke: #24282e; + stroke-linecap: round; + stroke-linejoin: round; + stroke-width: 3; +} + +.language-switcher { + position: relative; + justify-self: end; +} + +.language-button { + display: flex; + align-items: center; + justify-content: center; + width: 42px; + height: 30px; + border: 1px solid rgba(35, 40, 46, 0.12); + border-radius: 15px; + background: rgba(255, 255, 255, 0.72); + color: #25282e; + font-size: 13px; + font-weight: 900; + box-shadow: 0 4px 12px rgba(132, 90, 212, 0.08); +} + +.language-menu { + position: absolute; + z-index: 30; + top: calc(100% + 7px); + right: 0; + display: grid; + gap: 2px; + min-width: 72px; + padding: 5px; + border: 1px solid rgba(35, 40, 46, 0.1); + border-radius: 8px; + background: rgba(255, 255, 255, 0.96); + box-shadow: 0 10px 26px rgba(36, 46, 60, 0.14); +} + +.language-menu button { + min-height: 34px; + border-radius: 6px; + color: #25282e; + font-size: 12px; + font-weight: 900; +} + +.language-menu button.is-active { + background: var(--soft); + color: var(--primary-deep); +} + +.content { + display: flex; + flex-direction: column; + gap: 14px; + padding: 8px 14px 92px; +} + +.balance-card, +.mode-card, +.card-section { + width: 100%; + border-radius: 8px; + background: var(--card-bg); + box-shadow: var(--shadow); +} + +.balance-card { + padding: 20px 24px 19px; +} + +.balance-head { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; +} + +.balance-label { + color: var(--muted); + font-size: 15px; + font-weight: 850; +} + +.balance-history-button { + display: flex; + align-items: center; + justify-content: center; + width: 42px; + height: 42px; + flex: 0 0 42px; + border-radius: 50%; + background: var(--soft); + color: var(--primary-deep); +} + +.balance-history-button svg { + width: 26px; + height: 26px; +} + +.balance-history-button path { + fill: none; + stroke: currentColor; + stroke-linecap: round; + stroke-linejoin: round; + stroke-width: 2.8; +} + +.balance-value { + display: flex; + align-items: center; + margin-top: 13px; + color: #23272d; + font-size: 38px; + font-weight: 950; + line-height: 1.05; +} + +.balance-currency { + flex: 0 0 auto; + margin-right: 8px; + color: var(--gold); + font-size: 31px; + font-weight: 950; + line-height: 1; +} + +.mode-card { + padding: 16px; +} + +.mode-tabs { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 4px; + padding: 4px; + border-radius: 8px; + background: var(--soft); +} + +.mode-tab { + min-height: 46px; + border-radius: 7px; + color: var(--muted); + font-size: 15px; + font-weight: 950; +} + +.mode-tab.active { + background: #fff; + color: var(--text); + box-shadow: 0 5px 14px rgba(132, 90, 212, 0.1); +} + +.mode-panel { + display: none; + margin-top: 18px; +} + +.mode-panel.active { + display: block; +} + +.field { + display: block; +} + +.field > span { + display: block; + margin-bottom: 8px; + color: #4a4d53; + font-size: 15px; + font-weight: 850; +} + +.field-control, +.field input { + min-height: 52px; + border-radius: 8px; + background: var(--hy-theme-surface-soft, #fdfaff); +} + +.field input { + padding: 0 14px; +} + +.amount-control { + display: flex; + align-items: center; + padding: 0 14px; +} + +.amount-control span { + flex: 0 0 auto; + margin-right: 9px; + color: var(--gold); + font-size: 24px; + font-weight: 950; +} + +.amount-control input { + min-height: 0; + padding: 0; + background: transparent; + font-size: 23px; + font-weight: 900; +} + +.hint-row, +.exchange-preview { + display: flex; + align-items: center; + justify-content: space-between; + margin-top: 10px; + color: var(--muted); + font-size: 13px; + font-weight: 800; +} + +.text-action { + color: var(--primary-deep); + font-weight: 950; +} + +.exchange-preview strong { + color: #24282e; +} + +.transfer-search { + display: grid; + grid-template-columns: minmax(0, 1fr) auto; + gap: 10px; + align-items: center; +} + +.transfer-search input { + min-height: 52px; + padding: 0 14px; + border-radius: 8px; + background: var(--hy-theme-surface-soft, #fdfaff); +} + +.search-payee-button { + min-width: 82px; + min-height: 52px; + padding: 0 14px; + border-radius: 8px; + background: var(--button); + color: #fff; + font-size: 15px; + font-weight: 950; +} + +.search-payee-button:disabled { + background: var(--button-disabled); + color: var(--button-disabled-text); +} + +.payee-result { + display: flex; + align-items: center; + gap: 12px; + min-height: 68px; + margin-top: 12px; + padding: 12px; + border: 1px solid var(--line); + border-radius: 8px; + background: var(--hy-theme-surface-soft, #fdfaff); +} + +.payee-avatar { + display: flex; + align-items: center; + justify-content: center; + width: 44px; + height: 44px; + flex: 0 0 44px; + overflow: hidden; + border-radius: 50%; + background: var(--soft); + color: var(--primary-deep); + font-weight: 950; +} + +.payee-avatar img { + display: block; + width: 100%; + height: 100%; + object-fit: cover; +} + +.payee-copy { + min-width: 0; + flex: 1; +} + +.payee-name { + overflow: hidden; + color: #25282e; + font-size: 15px; + font-weight: 900; + text-overflow: ellipsis; + white-space: nowrap; +} + +.payee-id { + margin-top: 4px; + overflow: hidden; + color: var(--muted); + font-size: 12px; + font-weight: 800; + text-overflow: ellipsis; + white-space: nowrap; +} + +.transfer-amount-field { + margin-top: 14px; +} + +.card-section { + padding: 18px 16px; +} + +.section-head { + display: flex; + align-items: flex-start; + justify-content: space-between; + gap: 12px; +} + +.section-title { + color: #24282e; + font-size: 17px; + font-weight: 900; +} + +.section-subtitle { + margin-top: 4px; + color: var(--muted); + font-size: 13px; + font-weight: 750; +} + +.empty-address-state { + display: flex; + align-items: center; + gap: 13px; + min-height: 76px; + margin-top: 16px; + padding: 13px; + border: 1px dashed var(--line); + border-radius: 8px; + background: var(--hy-theme-surface-soft, #fdfaff); +} + +.empty-icon { + display: flex; + align-items: center; + justify-content: center; + width: 42px; + height: 42px; + flex: 0 0 42px; + border-radius: 50%; + background: var(--soft); +} + +.empty-icon svg { + width: 24px; + height: 24px; +} + +.empty-icon path { + fill: none; + stroke: var(--primary-deep); + stroke-linecap: round; + stroke-linejoin: round; + stroke-width: 2.2; +} + +.empty-title { + color: #292d33; + font-size: 15px; + font-weight: 900; +} + +.empty-copy { + margin-top: 3px; + color: var(--muted); + font-size: 12px; + font-weight: 750; + line-height: 1.25; +} + +.address-form { + display: flex; + flex-direction: column; + margin-top: 14px; +} + +.address-form input { + min-height: 48px; + padding: 0 14px; + border-radius: 8px; + background: var(--hy-theme-surface-soft, #fdfaff); +} + +.bound-address-card { + display: flex; + align-items: center; + gap: 14px; + min-height: 88px; + margin-top: 16px; + padding: 14px; + border-radius: 8px; + background: linear-gradient(135deg, #4a3378 0%, #7d57c7 100%); + color: #fff; +} + +.network-badge { + display: flex; + align-items: center; + justify-content: center; + width: 56px; + height: 32px; + flex: 0 0 56px; + border-radius: 7px; + background: linear-gradient(135deg, #ffe58b 0%, #c8942e 100%); + color: #1f252c; + font-size: 12px; + font-weight: 950; +} + +.bound-copy { + min-width: 0; + flex: 1 1 auto; +} + +.bound-network { + font-size: 15px; + font-weight: 900; +} + +.bound-address { + margin-top: 5px; + overflow-wrap: anywhere; + color: rgba(255, 255, 255, 0.82); + font-size: 14px; + font-weight: 850; +} + +.bound-meta { + margin-top: 4px; + color: rgba(255, 255, 255, 0.62); + font-size: 12px; + font-weight: 750; +} + +.primary-button, +.submit-button { + min-height: 50px; + border-radius: 25px; + font-size: 16px; + font-weight: 950; +} + +.primary-button, +.submit-button { + background: var(--button); + color: #fff; +} + +.primary-button { + width: 100%; + margin-top: 14px; +} + +.submit-button { + width: 100%; + box-shadow: var( + --hy-theme-button-shadow, + 0 8px 18px rgba(125, 87, 199, 0.18) + ); +} + +.primary-button:disabled, +.submit-button:disabled { + background: var(--button-disabled); + color: var(--button-disabled-text); + box-shadow: var(--hy-theme-button-disabled-shadow, none); +} + +.salary-history-modal { + position: fixed; + inset: 0; + z-index: 60; + display: flex; + align-items: flex-end; + justify-content: center; +} + +.salary-history-backdrop { + position: absolute; + inset: 0; + background: rgba(14, 19, 24, 0.44); +} + +.salary-history-dialog { + position: relative; + z-index: 1; + display: flex; + width: min(100%, 430px); + max-height: 78vh; + max-height: 78dvh; + flex-direction: column; + overflow: hidden; + border-radius: 18px 18px 0 0; + background: #fff; + box-shadow: 0 -14px 36px rgba(26, 35, 44, 0.16); +} + +.salary-history-head { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + padding: 18px 18px 12px; +} + +.salary-history-head h2 { + min-width: 0; + margin: 0; + overflow: hidden; + color: #24282e; + font-size: 18px; + font-weight: 950; + line-height: 1.2; + text-overflow: ellipsis; + white-space: nowrap; +} + +.salary-history-close { + display: flex; + align-items: center; + justify-content: center; + width: 34px; + height: 34px; + flex: 0 0 34px; + border-radius: 50%; + background: #f3f5f5; + color: #676b72; + font-size: 28px; + line-height: 1; +} + +.salary-history-summary { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + margin: 0 18px 12px; + padding: 14px; + border-radius: 8px; + background: var(--soft); +} + +.salary-history-summary span { + color: var(--muted); + font-size: 13px; + font-weight: 850; +} + +.salary-history-summary strong { + min-width: 0; + overflow-wrap: anywhere; + color: #24282e; + font-size: 20px; + font-weight: 950; +} + +.salary-history-list { + display: grid; + gap: 10px; + overflow-y: auto; + padding: 0 18px calc(18px + env(safe-area-inset-bottom)); +} + +.salary-history-item { + display: grid; + grid-template-columns: minmax(0, 1fr) auto; + gap: 8px 12px; + padding: 14px; + border: 1px solid var(--line); + border-radius: 8px; + background: var(--hy-theme-surface-soft, #fdfaff); +} + +.salary-history-item-main { + min-width: 0; +} + +.salary-history-item-title { + overflow: hidden; + color: #25282e; + font-size: 14px; + font-weight: 900; + line-height: 1.25; + text-overflow: ellipsis; + white-space: nowrap; +} + +.salary-history-item-meta { + display: flex; + flex-wrap: wrap; + gap: 6px 10px; + margin-top: 6px; + color: var(--muted); + font-size: 12px; + font-weight: 750; + line-height: 1.25; +} + +.salary-history-amount { + color: var(--primary-deep); + font-size: 15px; + font-weight: 950; + line-height: 1.25; + white-space: nowrap; +} + +.salary-history-amount.is-out { + color: var(--hy-theme-danger, #d95d72); +} + +.salary-history-empty { + padding: 24px 12px 30px; + color: var(--muted); + font-size: 14px; + font-weight: 850; + text-align: center; +} + +.modal-open { + overflow: hidden; +} + +.home-indicator { + position: fixed; + left: 50%; + bottom: 8px; + width: 154px; + height: 5px; + border-radius: 999px; + background: #050506; + transform: translateX(-50%); +} + +[dir='rtl'] .content { + direction: rtl; +} + +[dir='rtl'] .balance-currency, +[dir='rtl'] .amount-control span { + margin-right: 0; + margin-left: 9px; +} + +[dir='rtl'] .home-indicator { + direction: ltr; +} + +@media (max-width: 360px) { + .content { + padding-right: 12px; + padding-left: 12px; + } + + .balance-card { + padding-right: 18px; + padding-left: 18px; + } + + .balance-value { + font-size: 31px; + } + + .title-bar h1 { + font-size: 19px; + } + + .mode-tab { + font-size: 13px; + } + + .transfer-search { + grid-template-columns: 1fr; + } +}