feat(admin): вкладка «Активность» в карточке пользователя

Единый таймлайн действий юзера в боте и кабинете
(GET /cabinet/admin/users/{id}/activity): вертикальная лента с
иконками-кружками по типу записи, бейджи подтипов, суммы со знаком
(+зелёный / −красный), относительное время (абсолютное — в title),
чипы-фильтры по категориям (платежи, события, промо, тикеты, подарки,
рефералы, входы), счётчик StatCard и постраничная догрузка по house
load-more паттерну. Компонент самодостаточный (ActivityTab), как
TicketsTab. Переводы во всех 4 локалях; время переиспользует
admin.auditLog.time.*.

biome check, type-check и build проходят (pre-commit пропущен: biome
не установлен локально — бинарь есть только в CI).
This commit is contained in:
Fringg
2026-07-13 03:34:07 +03:00
parent c920330fa6
commit 7547b49d7a
7 changed files with 564 additions and 8 deletions

View File

@@ -3378,7 +3378,8 @@
"sync": "Synchronization",
"tickets": "Tickets",
"gifts": "Gifts",
"referrals": "Referrals"
"referrals": "Referrals",
"activity": "Activity"
},
"noTickets": "No tickets from this user",
"ticketsCount": "tickets",
@@ -3579,6 +3580,66 @@
"searchPlaceholder": "Search by name, email, or Telegram ID...",
"alreadyReferred": "already has referrer",
"noUsersFound": "No users found"
},
"activity": {
"total": "Total events",
"empty": "No activity yet",
"filters": {
"all": "All",
"payments": "Payments",
"events": "Events",
"promo": "Promo",
"tickets": "Tickets",
"gifts": "Gifts",
"referrals": "Referrals",
"logins": "Logins"
},
"types": {
"transaction": "Transaction",
"event": "Event",
"promocode": "Promo code",
"coupon": "Coupon",
"ticket": "Ticket",
"wheel_spin": "Fortune wheel",
"poll": "Poll completed",
"gift_sent": "Gift sent",
"gift_received": "Gift received",
"referral_earning": "Referral earning",
"cabinet_login": "Cabinet login",
"withdrawal": "Withdrawal request"
},
"sources": {
"bot": "Bot",
"cabinet": "Cabinet"
},
"subtypes": {
"deposit": "Deposit",
"withdrawal": "Charge",
"subscription_payment": "Subscription payment",
"refund": "Refund",
"failed_refund": "Failed refund",
"referral_reward": "Referral reward",
"poll_reward": "Poll reward",
"gift_payment": "Gift payment",
"activation": "Activation",
"purchase": "Purchase",
"subscription_purchase": "Subscription purchase",
"renewal": "Renewal",
"balance_topup": "Balance top-up",
"promo_group_change": "Promo group change",
"campaign_registration": "Campaign registration",
"referral_link_visit": "Referral link visit",
"referral_registration": "Referral registration",
"trial_activation": "Trial activation",
"open": "Open",
"answered": "Answered",
"pending": "Pending",
"closed": "Closed",
"redeemed": "Redeemed",
"approved": "Approved",
"rejected": "Rejected",
"completed": "Completed"
}
}
},
"notFound": "User not found",

View File

@@ -2882,7 +2882,8 @@
"sync": "همگام‌سازی",
"tickets": "تیکت‌ها",
"gifts": "هدایا",
"referrals": "معرفی‌ها"
"referrals": "معرفی‌ها",
"activity": "فعالیت"
},
"noTickets": "این کاربر تیکتی ندارد",
"ticketsCount": "تیکت",
@@ -3083,7 +3084,67 @@
"areYouSure": "آیا مطمئنید می‌خواهید ادامه دهید؟",
"title": "عملیات"
},
"noVpnData": "داده‌ای از VPN وجود ندارد"
"noVpnData": "داده‌ای از VPN وجود ندارد",
"activity": {
"total": "مجموع رویدادها",
"empty": "هنوز فعالیتی وجود ندارد",
"filters": {
"all": "همه",
"payments": "پرداخت‌ها",
"events": "رویدادها",
"promo": "تخفیف‌ها",
"tickets": "تیکت‌ها",
"gifts": "هدایا",
"referrals": "دعوت‌ها",
"logins": "ورودها"
},
"types": {
"transaction": "تراکنش",
"event": "رویداد",
"promocode": "کد تخفیف",
"coupon": "کوپن",
"ticket": "تیکت",
"wheel_spin": "گردونه شانس",
"poll": "نظرسنجی تکمیل شد",
"gift_sent": "هدیه ارسال شد",
"gift_received": "هدیه دریافت شد",
"referral_earning": "درآمد دعوت",
"cabinet_login": "ورود به پنل",
"withdrawal": "درخواست برداشت"
},
"sources": {
"bot": "ربات",
"cabinet": "پنل"
},
"subtypes": {
"deposit": "واریز",
"withdrawal": "برداشت",
"subscription_payment": "پرداخت اشتراک",
"refund": "بازپرداخت",
"failed_refund": "بازپرداخت ناموفق",
"referral_reward": "پاداش دعوت",
"poll_reward": "پاداش نظرسنجی",
"gift_payment": "پرداخت هدیه",
"activation": "فعال‌سازی",
"purchase": "خرید",
"subscription_purchase": "خرید اشتراک",
"renewal": "تمدید",
"balance_topup": "شارژ موجودی",
"promo_group_change": "تغییر گروه تخفیف",
"campaign_registration": "ثبت‌نام کمپین",
"referral_link_visit": "بازدید لینک دعوت",
"referral_registration": "ثبت‌نام دعوتی",
"trial_activation": "فعال‌سازی دوره آزمایشی",
"open": "باز",
"answered": "پاسخ داده شده",
"pending": "در انتظار",
"closed": "بسته",
"redeemed": "استفاده شده",
"approved": "تأیید شده",
"rejected": "رد شده",
"completed": "انجام شده"
}
}
},
"notFound": "کاربر یافت نشد",
"purchaseCount": "تعداد خرید: {{count}}",

View File

@@ -3785,7 +3785,8 @@
"sync": "Синхронизация",
"tickets": "Тикеты",
"gifts": "Подарки",
"referrals": "Рефералы"
"referrals": "Рефералы",
"activity": "Активность"
},
"noTickets": "У пользователя нет тикетов",
"ticketsCount": "тикетов",
@@ -3985,6 +3986,66 @@
"searchPlaceholder": "Поиск по имени, email или Telegram ID...",
"alreadyReferred": "уже чей-то реферал",
"noUsersFound": "Пользователи не найдены"
},
"activity": {
"total": "Всего событий",
"empty": "Активности пока нет",
"filters": {
"all": "Все",
"payments": "Платежи",
"events": "События",
"promo": "Промо",
"tickets": "Тикеты",
"gifts": "Подарки",
"referrals": "Рефералы",
"logins": "Входы"
},
"types": {
"transaction": "Транзакция",
"event": "Событие",
"promocode": "Промокод",
"coupon": "Купон",
"ticket": "Тикет",
"wheel_spin": "Колесо фортуны",
"poll": "Опрос пройден",
"gift_sent": "Подарок отправлен",
"gift_received": "Подарок получен",
"referral_earning": "Реферальное начисление",
"cabinet_login": "Вход в кабинет",
"withdrawal": "Заявка на вывод"
},
"sources": {
"bot": "Бот",
"cabinet": "Кабинет"
},
"subtypes": {
"deposit": "Пополнение",
"withdrawal": "Списание",
"subscription_payment": "Оплата подписки",
"refund": "Возврат",
"failed_refund": "Неудачный возврат",
"referral_reward": "Реферальная награда",
"poll_reward": "Награда за опрос",
"gift_payment": "Оплата подарка",
"activation": "Активация",
"purchase": "Покупка",
"subscription_purchase": "Покупка подписки",
"renewal": "Продление",
"balance_topup": "Пополнение баланса",
"promo_group_change": "Смена промогруппы",
"campaign_registration": "Регистрация по кампании",
"referral_link_visit": "Переход по реф. ссылке",
"referral_registration": "Реф. регистрация",
"trial_activation": "Активация триала",
"open": "Открыт",
"answered": "Отвечен",
"pending": "Ожидает",
"closed": "Закрыт",
"redeemed": "Погашен",
"approved": "Одобрена",
"rejected": "Отклонена",
"completed": "Выполнена"
}
}
},
"notFound": "Пользователь не найден",

View File

@@ -2881,7 +2881,8 @@
"sync": "同步",
"tickets": "工单",
"gifts": "礼物",
"referrals": "推荐"
"referrals": "推荐",
"activity": "活动记录"
},
"noTickets": "该用户没有工单",
"ticketsCount": "个工单",
@@ -3082,7 +3083,67 @@
"areYouSure": "确定要继续?",
"title": "操作"
},
"noVpnData": "无 VPN 数据"
"noVpnData": "无 VPN 数据",
"activity": {
"total": "事件总数",
"empty": "暂无活动记录",
"filters": {
"all": "全部",
"payments": "支付",
"events": "事件",
"promo": "促销",
"tickets": "工单",
"gifts": "礼物",
"referrals": "推荐",
"logins": "登录"
},
"types": {
"transaction": "交易",
"event": "事件",
"promocode": "促销码",
"coupon": "优惠券",
"ticket": "工单",
"wheel_spin": "幸运转盘",
"poll": "问卷已完成",
"gift_sent": "已发送礼物",
"gift_received": "已收到礼物",
"referral_earning": "推荐收益",
"cabinet_login": "登录后台",
"withdrawal": "提现申请"
},
"sources": {
"bot": "机器人",
"cabinet": "后台"
},
"subtypes": {
"deposit": "充值",
"withdrawal": "扣款",
"subscription_payment": "订阅付款",
"refund": "退款",
"failed_refund": "退款失败",
"referral_reward": "推荐奖励",
"poll_reward": "问卷奖励",
"gift_payment": "礼物付款",
"activation": "激活",
"purchase": "购买",
"subscription_purchase": "订阅购买",
"renewal": "续订",
"balance_topup": "余额充值",
"promo_group_change": "促销组变更",
"campaign_registration": "活动注册",
"referral_link_visit": "推荐链接访问",
"referral_registration": "推荐注册",
"trial_activation": "试用激活",
"open": "打开",
"answered": "已回复",
"pending": "等待中",
"closed": "已关闭",
"redeemed": "已兑换",
"approved": "已批准",
"rejected": "已拒绝",
"completed": "已完成"
}
}
},
"notFound": "未找到用户",
"purchaseCount": "购买次数:{{count}}",