telegram-shop-api / src /scenes /admin /editProduct.js
Deploy Bot
Feat: Audit Fixes (Search Condition + Admin Edit)
253ca85
const { Scenes, Markup } = require('telegraf');
const Product = require('../../models/Product');
const Category = require('../../models/Category');
const userController = require('../../controllers/userController');
// Helper to show confirmation
const askConfirmation = (ctx, field, value, product) => {
let displayValue = value;
if (field === 'media') displayValue = `${value.length} ta yangi fayl`;
ctx.reply(`⚠️ <b>Tasdiqlaysizmi?</b>\n\nMaydon: ${field}\nEski: ${field === 'media' ? 'Media fayllar' : (product[field] || 'Yo\'q')}\nYangi: ${displayValue}`, {
parse_mode: 'HTML',
...Markup.keyboard([['βœ… Ha', '❌ Bekor qilish']]).resize().oneTime()
});
};
const editProductScene = new Scenes.WizardScene(
'EDIT_PRODUCT_SCENE',
// Step 0: Ask what to edit (Index 0)
async (ctx) => {
const prodId = ctx.wizard.state.prodId;
if (!prodId) return ctx.scene.leave();
const product = await Product.findOne({ id: prodId });
if (!product) {
ctx.reply("Mahsulot topilmadi.");
return ctx.scene.leave();
}
ctx.wizard.state.product = product;
ctx.reply(`✏️ <b>${product.name || 'Nomsiz'}</b> ni tahrirlash.\nMavjud: ${product.quantity} ta\nHolati: ${product.condition === 'used' ? '♻️ B/U' : 'πŸ†• Yangi'}\n\nQaysi ma'lumotni o'zgartiramiz?`, {
parse_mode: 'HTML',
...Markup.keyboard([
['πŸ“ Nomini', 'πŸ’° Narxini'],
['πŸ”’ Sonini', 'πŸ“„ Tavsifni'],
['πŸ“‚ Kategoriyani', 'πŸ“Έ Rasmni'],
['πŸ†•/♻️ Holatini'], // New Button
['❌ Bekor qilish']
]).oneTime().resize()
});
return ctx.wizard.next();
},
// Step 1: Handle selection (Index 1)
async (ctx) => {
const text = ctx.message.text;
if (text === '❌ Bekor qilish' || text === '/start') {
ctx.scene.leave();
userController.start(ctx, "Tahrirlash bekor qilindi.");
return;
}
let field = '';
if (text === 'πŸ“ Nomini') field = 'name';
else if (text === 'πŸ’° Narxini') field = 'price';
else if (text === 'πŸ”’ Sonini') field = 'quantity';
else if (text === 'πŸ“„ Tavsifni') field = 'description';
else if (text === 'πŸ“‚ Kategoriyani') field = 'category';
else if (text === 'πŸ“Έ Rasmni') field = 'media';
else if (text === 'πŸ†•/♻️ Holatini') field = 'condition'; // Handler
else {
ctx.reply("Iltimos, tugmalardan birini tanlang.");
return;
}
ctx.wizard.state.field = field;
if (field === 'category') {
const categories = await Category.find();
const buttons = categories.map(c => c.name);
buttons.push('❌ Bekor qilish');
ctx.reply("Yangi kategoriyani tanlang:", Markup.keyboard(buttons).resize());
return ctx.wizard.selectStep(3); // Go to Category Handler
} else if (field === 'media') {
ctx.wizard.state.newMedia = [];
ctx.reply("πŸ“Έ Yangi rasmlarni yuboring (Maksimal 4 ta).\nEski rasmlar o'chib ketadi.\n\nBarchasini yuborib bo'lgach, 'βœ… Tayyor' tugmasini bosing.", Markup.keyboard(['βœ… Tayyor', '❌ Bekor qilish']).resize());
return ctx.wizard.selectStep(4); // Go to Media Handler
} else if (field === 'condition') {
ctx.reply("Yangi holatni tanlang:", Markup.keyboard([['πŸ†• Yangi', '♻️ B/U'], ['❌ Bekor qilish']]).resize());
return ctx.wizard.selectStep(2); // Go to Value Input (handled as text)
}
ctx.reply(`Yangi ${text.toLowerCase()} kiriting:`, Markup.keyboard([['❌ Bekor qilish']]).resize());
return ctx.wizard.next();
},
// Step 2: Handle Text/Number Input (Index 2)
async (ctx) => {
const newValue = ctx.message.text;
if (!newValue || newValue === '❌ Bekor qilish') {
ctx.scene.leave();
userController.start(ctx, "Bekor qilindi.");
return;
}
if (newValue.startsWith('/')) {
ctx.scene.leave();
userController.start(ctx);
return;
}
if (ctx.wizard.state.field === 'price' || ctx.wizard.state.field === 'quantity') {
if (isNaN(newValue)) return ctx.reply("Iltimos, raqam kiriting.");
}
// Map Condition Text to Value
if (ctx.wizard.state.field === 'condition') {
if (newValue === 'πŸ†• Yangi') ctx.wizard.state.newValue = 'new';
else if (newValue === '♻️ B/U') ctx.wizard.state.newValue = 'used';
else return ctx.reply("Iltimos, tugmani tanlang: Yangi yoki B/U");
} else {
ctx.wizard.state.newValue = newValue;
}
// Ask Confirmation HERE
askConfirmation(ctx, ctx.wizard.state.field, ctx.wizard.state.newValue, ctx.wizard.state.product);
return ctx.wizard.selectStep(5); // Go to Confirmation Handler
},
// Step 3: Handle Category Input (Index 3)
async (ctx) => {
const tex = ctx.message.text;
if (!tex || tex === '❌ Bekor qilish' || tex.startsWith('/')) {
ctx.scene.leave();
userController.start(ctx, "Bekor qilindi.");
return;
}
ctx.wizard.state.newValue = tex;
askConfirmation(ctx, 'category', tex, ctx.wizard.state.product);
return ctx.wizard.selectStep(5);
},
// Step 4: Handle Media Input (Index 4)
async (ctx) => {
const msg = ctx.message;
if (msg.text === '❌ Bekor qilish' || (msg.text && msg.text.startsWith('/'))) {
ctx.scene.leave();
userController.start(ctx, "Bekor qilindi.");
return;
}
if (msg.text === 'βœ… Tayyor') {
if (ctx.wizard.state.newMedia.length === 0) return ctx.reply("Kamida bitta rasm yuboring.");
ctx.wizard.state.newValue = ctx.wizard.state.newMedia;
askConfirmation(ctx, 'media', ctx.wizard.state.newMedia, ctx.wizard.state.product);
return ctx.wizard.selectStep(5);
}
if (msg.photo) {
ctx.wizard.state.newMedia.push({ type: 'photo', file_id: msg.photo[msg.photo.length - 1].file_id });
ctx.reply(`Rasm qabul qilindi (${ctx.wizard.state.newMedia.length}/4)`);
} else if (msg.video) {
ctx.wizard.state.newMedia.push({ type: 'video', file_id: msg.video.file_id });
ctx.reply(`Video qabul qilindi (${ctx.wizard.state.newMedia.length}/4)`);
}
if (ctx.wizard.state.newMedia.length >= 4) {
ctx.wizard.state.newValue = ctx.wizard.state.newMedia;
askConfirmation(ctx, 'media', ctx.wizard.state.newMedia, ctx.wizard.state.product);
return ctx.wizard.selectStep(5);
}
},
// Step 5: Handle Yes/No (Hander ONLY) (Index 5)
async (ctx) => {
if (ctx.message.text === 'βœ… Ha') {
try {
const update = {};
update[ctx.wizard.state.field] = ctx.wizard.state.newValue;
await Product.updateOne({ id: ctx.wizard.state.product.id }, update);
ctx.reply("βœ… Muvaffaqiyatli saqlandi!", Markup.removeKeyboard());
// Redirect to Main Menu
userController.start(ctx);
} catch (e) {
console.error(e);
ctx.reply("Xatolik bo'ldi.");
}
} else {
userController.start(ctx, "Bekor qilindi.");
}
return ctx.scene.leave();
}
);
module.exports = editProductScene;