const { Scenes, Markup } = require('telegraf'); const User = require('../../models/User'); const usersScene = new Scenes.WizardScene( 'admin_users', // Step 1: Main Menu for User Management async (ctx) => { // Inject i18n if (!ctx.i18n) { const User = require('../../models/User'); const locales = require('../../locales'); const user = await User.findOne({ id: ctx.from.id }); const lang = (user && user.language) ? user.language : 'uz'; ctx.i18n = locales[lang] || locales.uz; } const i18n = ctx.i18n; const text = i18n.admin.users_title; const buttons = [ [Markup.button.callback(i18n.admin.users_search, "search_id")], [Markup.button.callback(i18n.admin.users_blocked, "list_blocked")], [Markup.button.callback(i18n.admin.back, "back_dashboard")] ]; if (ctx.callbackQuery) { await ctx.editMessageText(text, { parse_mode: 'Markdown', ...Markup.inlineKeyboard(buttons) }); } else { await ctx.replyWithMarkdown(text, Markup.inlineKeyboard(buttons)); } return ctx.wizard.next(); }, // Step 2: Handle Selection async (ctx) => { // Ensure i18n if (!ctx.i18n) { const locales = require('../../locales'); ctx.i18n = locales.uz; } const i18n = ctx.i18n; if (!ctx.callbackQuery && !ctx.message) return; const txt = ctx.message ? ctx.message.text : ''; if (txt === '/start' || txt === i18n.admin.btn_reject || txt === '❌ Bekor qilish') { return ctx.scene.leave(); } if (ctx.callbackQuery) { const data = ctx.callbackQuery.data; if (data === 'back_dashboard') { await ctx.scene.leave(); const adminController = require('../../controllers/adminController'); return adminController.showDashboard(ctx); } if (data === 'search_id') { await ctx.reply(i18n.admin.users_search_prompt, Markup.keyboard([[i18n.admin.btn_reject]]).resize()); ctx.wizard.state.action = 'search_id'; return ctx.wizard.next(); } if (data === 'list_blocked') { const blockedUsers = await User.find({ isBlocked: true }); if (blockedUsers.length === 0) { await ctx.answerCbQuery(i18n.admin.users_blocked + ": 0"); return; } let msg = `${i18n.admin.users_blocked}:\n\n`; blockedUsers.forEach(u => { msg += `👤 ${u.first_name} (ID: ${u.id})\n`; }); await ctx.replyWithMarkdown(msg); return; } } }, // Step 3: Input Handler (Search ID) & Action Execution async (ctx) => { // Ensure i18n if (!ctx.i18n) { const locales = require('../../locales'); ctx.i18n = locales.uz; } const i18n = ctx.i18n; const txt = ctx.message ? ctx.message.text : ''; if (txt === i18n.admin.btn_reject || txt === '❌ Bekor qilish') { await ctx.reply(i18n.admin.back, Markup.removeKeyboard()); return ctx.scene.leave(); } if (ctx.wizard.state.action === 'search_id') { const userId = parseInt(txt); if (isNaN(userId)) { await ctx.reply(i18n.admin.error_num || "Error"); return; } const user = await User.findOne({ id: userId }); if (!user) { await ctx.reply(i18n.admin.del_fail || "Not found"); return ctx.scene.leave(); } ctx.wizard.state.selectedUser = user; // Show User Details const status = user.isBlocked ? i18n.admin.users_blocked : "✅ Aktiv"; const info = `${i18n.admin.users_info}\n\n` + `🆔 ID: \`${user.id}\`\n` + `👤 ${i18n.name}: ${user.first_name}\n` + `📞 ${i18n.phone}: ${user.phone || "Yo'q"}\n` + `📊 Status: ${status}\n` + `📅 Date: ${user.createdAt.toLocaleDateString()}`; const buttons = []; if (user.isBlocked) { buttons.push([Markup.button.callback(i18n.admin.btn_unban, "unban_user")]); } else { buttons.push([Markup.button.callback(i18n.admin.btn_ban, "ban_user")]); } buttons.push([Markup.button.callback(i18n.admin.btn_dm, "dm_user")]); buttons.push([Markup.button.callback(i18n.admin.btn_reject, "cancel")]); await ctx.replyWithMarkdown(info, Markup.inlineKeyboard(buttons)); return ctx.wizard.next(); } }, // Step 4: Handle User Actions (Ban/Unban/DM) async (ctx) => { // Ensure i18n const i18n = ctx.i18n || require('../../locales').uz; if (ctx.callbackQuery) { const data = ctx.callbackQuery.data; const user = ctx.wizard.state.selectedUser; if (data === 'cancel') { await ctx.deleteMessage(); await ctx.reply(i18n.admin.back, Markup.removeKeyboard()); return ctx.scene.leave(); } if (data === 'ban_user') { await User.updateOne({ id: user.id }, { isBlocked: true }); await ctx.answerCbQuery(i18n.admin.btn_ban); await ctx.reply(`🚫 ${user.first_name} blocked.`); return ctx.scene.leave(); } if (data === 'unban_user') { await User.updateOne({ id: user.id }, { isBlocked: false }); await ctx.answerCbQuery(i18n.admin.btn_unban); await ctx.reply(`✅ ${user.first_name} unblocked.`); return ctx.scene.leave(); } if (data === 'dm_user') { await ctx.reply(i18n.admin.dm_prompt, Markup.keyboard([[i18n.admin.btn_reject]]).resize()); ctx.wizard.state.action = 'typing_dm'; return ctx.wizard.next(); // Go to Step 5 (DM Input) } } }, // Step 5: Send DM async (ctx) => { // Ensure i18n const i18n = ctx.i18n || require('../../locales').uz; const txt = ctx.message ? ctx.message.text : ''; if (txt === i18n.admin.btn_reject || txt === '❌ Bekor qilish') { await ctx.reply(i18n.admin.back, Markup.removeKeyboard()); return ctx.scene.leave(); } const user = ctx.wizard.state.selectedUser; try { await ctx.telegram.sendMessage(user.id, `🔔 **Admin:**\n\n${txt}`, { parse_mode: 'Markdown' }); await ctx.reply(i18n.admin.dm_sent); } catch (err) { await ctx.reply(i18n.admin.error); } return ctx.scene.leave(); } ); module.exports = usersScene;