feat: wallet balances grouped by user with split layout

- Left sidebar: user list with ID, username, status icon, wallet count
- Right panel: selected user's balances + crypto wallet table
- Fix inverted status logic (0=Active, 1=Deleted, 2=Blocked)
- Admin bot: block/unblock toggle based on current user status
- Seed data: set active users to status=0 instead of status=1
- Toggle-status route: 0↔2 instead of 1↔0
This commit is contained in:
NW
2026-06-23 12:41:18 +01:00
parent 7b247075a0
commit b6f21222e7
7 changed files with 194 additions and 41 deletions

View File

@@ -238,6 +238,8 @@ export default class AdminUserHandler {
const message = `
👤 User Profile:
Status: ${user.status === 0 ? '✅ Active' : user.status === 2 ? '🚫 Blocked' : '❌ Deleted'}
ID: ${telegramId}
📍 Location: ${detailedUser.country || 'Not set'}, ${detailedUser.city || 'Not set'}, ${detailedUser.district || 'Not set'}
@@ -266,7 +268,7 @@ export default class AdminUserHandler {
{text: '📍 Edit Location', callback_data: `edit_user_location_${telegramId}`}
],
[
{text: '🚫 Block User', callback_data: `block_user_${telegramId}`},
{text: user.status === 2 ? '✅ Unblock User' : '🚫 Block User', callback_data: `block_user_${telegramId}`},
{text: '❌ Delete User', callback_data: `delete_user_${telegramId}`}
],
[{text: '« Back to User List', callback_data: `list_users_0`}]
@@ -364,17 +366,27 @@ export default class AdminUserHandler {
const chatId = callbackQuery.message.chat.id;
try {
const user = await UserService.getUserByTelegramId(telegramId);
if (!user) {
await bot.sendMessage(chatId, 'User not found.');
return;
}
const isBlocked = user.status === 2;
const actionText = isBlocked ? 'unblock' : 'block';
const confirmText = isBlocked ? '✅ Confirm Unblock' : '✅ Confirm Block';
const keyboard = {
inline_keyboard: [
[
{text: '✅ Confirm Block', callback_data: `confirm_block_user_${telegramId}`},
{text: confirmText, callback_data: `confirm_block_user_${telegramId}`},
{text: '❌ Cancel', callback_data: `view_user_${telegramId}`}
]
]
};
await bot.editMessageText(
`⚠️ Are you sure you want to block user ${telegramId}?`,
`⚠️ Are you sure you want to ${actionText} user ${telegramId}?`,
{
chat_id: chatId,
message_id: callbackQuery.message.message_id,
@@ -397,7 +409,15 @@ export default class AdminUserHandler {
const chatId = callbackQuery.message.chat.id;
try {
await UserService.updateUserStatus(telegramId, 2);
const user = await UserService.getUserByTelegramId(telegramId);
if (!user) {
await bot.sendMessage(chatId, 'User not found.');
return;
}
const isBlocked = user.status === 2;
const newStatus = isBlocked ? 0 : 2;
await UserService.updateUserStatus(telegramId, newStatus);
const keyboard = {
inline_keyboard: [
@@ -406,22 +426,25 @@ export default class AdminUserHandler {
};
try {
await bot.sendMessage(telegramId, '⚠Your account has been blocked by administrator');
await bot.sendMessage(telegramId, isBlocked
? '✅ Your account has been unblocked by administrator'
: '⚠️ Your account has been blocked by administrator');
} catch (e) {
// ignore if we can't notify user
}
await bot.editMessageText(
`✅ User ${telegramId} has been successfully blocked.`,
{
chat_id: chatId,
message_id: callbackQuery.message.message_id,
reply_markup: keyboard
}
);
const resultText = isBlocked
? `✅ User ${telegramId} has been successfully unblocked.`
: `✅ User ${telegramId} has been successfully blocked.`;
await bot.editMessageText(resultText, {
chat_id: chatId,
message_id: callbackQuery.message.message_id,
reply_markup: keyboard
});
} catch (error) {
logger.error({ err: error }, 'Error in handleConfirmBlock');
await bot.sendMessage(chatId, 'Error blocking user. Please try again.');
await bot.sendMessage(chatId, 'Error updating user status. Please try again.');
}
}