feat(websocket): add global handler for subscription and balance notifications

- Extend WSMessage interface with balance, subscription, autopay, account, referral fields
- Create WebSocketNotifications component to handle all WS events
- Add component to Layout for global event listening
- Show toasts and invalidate queries on subscription/balance events
- Add translations for all notification types (ru, en, zh, fa)
This commit is contained in:
c0mrade
2026-01-30 19:04:45 +03:00
parent cb57c34b55
commit ca227f3975
7 changed files with 637 additions and 1 deletions

View File

@@ -68,6 +68,58 @@
"newUserReply": "User replied in ticket: {{title}}",
"newUserReplyTitle": "User Reply"
},
"wsNotifications": {
"balance": {
"topupTitle": "Balance topped up",
"topupMessage": "Your balance has been topped up by {{amount}} {{currency}}",
"changeTitle": "Balance updated",
"changeMessage": "Your balance has changed by {{amount}} {{currency}}"
},
"subscription": {
"activatedTitle": "Subscription activated",
"activatedMessage": "Your subscription is now active!",
"activatedWithTariff": "Your subscription \"{{tariff}}\" is now active!",
"renewedTitle": "Subscription renewed",
"renewedMessage": "Your subscription has been renewed!",
"renewedWithAmount": "Your subscription has been renewed for {{amount}} {{currency}}",
"expiringTitle": "Subscription expiring soon",
"expiringMessage": "Your subscription expires in {{days}} days",
"expiredTitle": "Subscription expired",
"expiredMessage": "Your subscription has expired. Renew to continue using the service.",
"dailyDebitTitle": "Daily charge",
"dailyDebitMessage": "Daily subscription fee: {{amount}} {{currency}}",
"trafficResetTitle": "Traffic reset",
"trafficResetMessage": "Your traffic limit has been reset"
},
"autopay": {
"successTitle": "Auto-renewal successful",
"successMessage": "Your subscription was auto-renewed for {{amount}} {{currency}}",
"failedTitle": "Auto-renewal failed",
"failedMessage": "Failed to auto-renew your subscription",
"insufficientTitle": "Insufficient funds",
"insufficientMessage": "Need {{required}} {{currency}} for renewal, but balance is {{balance}} {{currency}}"
},
"account": {
"bannedTitle": "Account blocked",
"bannedMessage": "Your account has been blocked",
"unbannedTitle": "Account unblocked",
"unbannedMessage": "Your account has been unblocked",
"warningTitle": "Warning",
"warningMessage": "You have received a warning"
},
"referral": {
"bonusTitle": "Referral bonus",
"bonusMessage": "You received {{amount}} {{currency}} referral bonus!",
"bonusWithName": "You received {{amount}} {{currency}} bonus from {{name}}!",
"registeredTitle": "New referral",
"registeredMessage": "Someone joined using your referral link!",
"registeredWithName": "{{name}} joined using your referral link!"
},
"payment": {
"receivedTitle": "Payment received",
"receivedMessage": "Payment of {{amount}} {{currency}} received"
}
},
"auth": {
"login": "Login",
"register": "Register",

View File

@@ -62,6 +62,58 @@
"newUserReply": "کاربر در تیکت پاسخ داد: {{title}}",
"newUserReplyTitle": "پاسخ کاربر"
},
"wsNotifications": {
"balance": {
"topupTitle": "موجودی شارژ شد",
"topupMessage": "موجودی شما {{amount}} {{currency}} شارژ شد",
"changeTitle": "موجودی به‌روز شد",
"changeMessage": "موجودی شما {{amount}} {{currency}} تغییر کرد"
},
"subscription": {
"activatedTitle": "اشتراک فعال شد",
"activatedMessage": "اشتراک شما اکنون فعال است!",
"activatedWithTariff": "اشتراک «{{tariff}}» شما اکنون فعال است!",
"renewedTitle": "اشتراک تمدید شد",
"renewedMessage": "اشتراک شما تمدید شد!",
"renewedWithAmount": "اشتراک شما با {{amount}} {{currency}} تمدید شد",
"expiringTitle": "اشتراک به زودی منقضی می‌شود",
"expiringMessage": "اشتراک شما {{days}} روز دیگر منقضی می‌شود",
"expiredTitle": "اشتراک منقضی شد",
"expiredMessage": "اشتراک شما منقضی شده است. برای ادامه استفاده تمدید کنید.",
"dailyDebitTitle": "کسر روزانه",
"dailyDebitMessage": "هزینه روزانه اشتراک: {{amount}} {{currency}}",
"trafficResetTitle": "ترافیک بازنشانی شد",
"trafficResetMessage": "محدودیت ترافیک شما بازنشانی شد"
},
"autopay": {
"successTitle": "تمدید خودکار موفق",
"successMessage": "اشتراک شما به صورت خودکار با {{amount}} {{currency}} تمدید شد",
"failedTitle": "خطا در تمدید خودکار",
"failedMessage": "تمدید خودکار اشتراک شما ناموفق بود",
"insufficientTitle": "موجودی ناکافی",
"insufficientMessage": "برای تمدید {{required}} {{currency}} لازم است، موجودی فعلی {{balance}} {{currency}}"
},
"account": {
"bannedTitle": "حساب مسدود شد",
"bannedMessage": "حساب شما مسدود شده است",
"unbannedTitle": "حساب رفع مسدودی شد",
"unbannedMessage": "حساب شما رفع مسدودی شد",
"warningTitle": "هشدار",
"warningMessage": "شما یک هشدار دریافت کردید"
},
"referral": {
"bonusTitle": "پاداش معرفی",
"bonusMessage": "شما {{amount}} {{currency}} پاداش معرفی دریافت کردید!",
"bonusWithName": "شما از {{name}} پاداش {{amount}} {{currency}} دریافت کردید!",
"registeredTitle": "معرفی جدید",
"registeredMessage": "کسی با لینک معرفی شما ثبت نام کرد!",
"registeredWithName": "{{name}} با لینک معرفی شما ثبت نام کرد!"
},
"payment": {
"receivedTitle": "پرداخت دریافت شد",
"receivedMessage": "پرداخت {{amount}} {{currency}} دریافت شد"
}
},
"auth": {
"login": "ورود",
"register": "ثبت نام",

View File

@@ -71,6 +71,58 @@
"newUserReply": "Ответ пользователя в тикете: {{title}}",
"newUserReplyTitle": "Ответ пользователя"
},
"wsNotifications": {
"balance": {
"topupTitle": "Баланс пополнен",
"topupMessage": "Ваш баланс пополнен на {{amount}} {{currency}}",
"changeTitle": "Баланс изменён",
"changeMessage": "Ваш баланс изменился на {{amount}} {{currency}}"
},
"subscription": {
"activatedTitle": "Подписка активирована",
"activatedMessage": "Ваша подписка теперь активна!",
"activatedWithTariff": "Ваша подписка «{{tariff}}» теперь активна!",
"renewedTitle": "Подписка продлена",
"renewedMessage": "Ваша подписка была продлена!",
"renewedWithAmount": "Ваша подписка продлена за {{amount}} {{currency}}",
"expiringTitle": "Подписка скоро истекает",
"expiringMessage": "Ваша подписка истекает через {{days}} дн.",
"expiredTitle": "Подписка истекла",
"expiredMessage": "Ваша подписка истекла. Продлите для продолжения использования.",
"dailyDebitTitle": "Ежедневное списание",
"dailyDebitMessage": "Списание за подписку: {{amount}} {{currency}}",
"trafficResetTitle": "Трафик сброшен",
"trafficResetMessage": "Ваш лимит трафика был сброшен"
},
"autopay": {
"successTitle": "Автопродление успешно",
"successMessage": "Подписка автоматически продлена за {{amount}} {{currency}}",
"failedTitle": "Ошибка автопродления",
"failedMessage": "Не удалось автоматически продлить подписку",
"insufficientTitle": "Недостаточно средств",
"insufficientMessage": "Для продления нужно {{required}} {{currency}}, на балансе {{balance}} {{currency}}"
},
"account": {
"bannedTitle": "Аккаунт заблокирован",
"bannedMessage": "Ваш аккаунт был заблокирован",
"unbannedTitle": "Аккаунт разблокирован",
"unbannedMessage": "Ваш аккаунт был разблокирован",
"warningTitle": "Предупреждение",
"warningMessage": "Вы получили предупреждение"
},
"referral": {
"bonusTitle": "Реферальный бонус",
"bonusMessage": "Вы получили реферальный бонус {{amount}} {{currency}}!",
"bonusWithName": "Вы получили бонус {{amount}} {{currency}} от {{name}}!",
"registeredTitle": "Новый реферал",
"registeredMessage": "Кто-то зарегистрировался по вашей ссылке!",
"registeredWithName": "{{name}} зарегистрировался по вашей ссылке!"
},
"payment": {
"receivedTitle": "Платёж получен",
"receivedMessage": "Получен платёж на сумму {{amount}} {{currency}}"
}
},
"auth": {
"login": "Вход",
"register": "Регистрация",

View File

@@ -62,6 +62,58 @@
"newUserReply": "用户回复了工单:{{title}}",
"newUserReplyTitle": "用户回复"
},
"wsNotifications": {
"balance": {
"topupTitle": "余额已充值",
"topupMessage": "您的余额已充值 {{amount}} {{currency}}",
"changeTitle": "余额已更新",
"changeMessage": "您的余额已变动 {{amount}} {{currency}}"
},
"subscription": {
"activatedTitle": "订阅已激活",
"activatedMessage": "您的订阅现已激活!",
"activatedWithTariff": "您的订阅「{{tariff}}」现已激活!",
"renewedTitle": "订阅已续期",
"renewedMessage": "您的订阅已续期!",
"renewedWithAmount": "您的订阅已续期,费用 {{amount}} {{currency}}",
"expiringTitle": "订阅即将到期",
"expiringMessage": "您的订阅将在 {{days}} 天后到期",
"expiredTitle": "订阅已过期",
"expiredMessage": "您的订阅已过期。请续期以继续使用服务。",
"dailyDebitTitle": "每日扣费",
"dailyDebitMessage": "每日订阅费:{{amount}} {{currency}}",
"trafficResetTitle": "流量已重置",
"trafficResetMessage": "您的流量限制已重置"
},
"autopay": {
"successTitle": "自动续期成功",
"successMessage": "您的订阅已自动续期,费用 {{amount}} {{currency}}",
"failedTitle": "自动续期失败",
"failedMessage": "自动续期订阅失败",
"insufficientTitle": "余额不足",
"insufficientMessage": "续期需要 {{required}} {{currency}},当前余额 {{balance}} {{currency}}"
},
"account": {
"bannedTitle": "账户已封禁",
"bannedMessage": "您的账户已被封禁",
"unbannedTitle": "账户已解封",
"unbannedMessage": "您的账户已解封",
"warningTitle": "警告",
"warningMessage": "您收到了一条警告"
},
"referral": {
"bonusTitle": "推荐奖励",
"bonusMessage": "您获得了 {{amount}} {{currency}} 推荐奖励!",
"bonusWithName": "您从 {{name}} 获得了 {{amount}} {{currency}} 奖励!",
"registeredTitle": "新推荐用户",
"registeredMessage": "有人通过您的推荐链接注册了!",
"registeredWithName": "{{name}} 通过您的推荐链接注册了!"
},
"payment": {
"receivedTitle": "已收到付款",
"receivedMessage": "收到付款 {{amount}} {{currency}}"
}
},
"auth": {
"login": "登录",
"register": "注册",