--- Matches in admin_panel.py ---
Line 25 (emoji): from core.emojis import (
Line 28 (custom_emoji): get_custom_emoji_overrides,
Line 29 (emoji): get_effective_emoji_id,
Line 31 (custom_emoji): set_custom_emoji_override,
Line 32 (custom_emoji): set_custom_emoji_overrides,
Line 47 (waiting_for_user_message): waiting_for_user_message = State()
Line 58 (usdt_rate): waiting_for_usdt_rate = State()
Line 63 (custom_emoji): waiting_for_custom_emoji_id = State()
Line 64 (custom_emoji): waiting_for_custom_emoji_bulk = State()
Line 72 (emoji): emoji for emoji in BASE_EMOJI_ID_MAPPING.keys()
Line 73 (emoji): if emoji not in IMPORTANT_EMOJIS
Line 114 (custom_emoji): def _valid_custom_emoji_id(value: str) -> bool:
Line 117 (emoji): def _emoji_label(emoji: str) -> str:
Line 118 (emoji): return EMOJI_LABELS.get(emoji, "ایموجی استاندارد تلگرام")
Line 121 (admin_dashboard): async def admin_dashboard(message: Message, prefix_text: str = ""):
Line 144 (style=): builder.button(text="📢 پیام همگانی", callback_data="admin_broadcast", style="primary")
Line 145 (style=): builder.button(text="👤 مدیریت کاربران", callback_data="admin_manage_user", style="primary")
Line 146 (style=): builder.button(text="🎁 افزودن گیفت کارت", callback_data="admin_add_giftcard", style="primary")
Line 147 (style=): builder.button(text="📋 مدیریت گیفت کارت‌ها", callback_data="admin_manage_gcs_1", style="primary")
Line 148 (style=): builder.button(text="🛒 مدیریت فروشگاه", callback_data="admin_manage_products", style="primary")
Line 149 (style=): builder.button(text="📦 مدیریت سفارش‌ها", callback_data="admin_manage_orders_1", style="primary")
Line 150 (style=): builder.button(text="📊 گزارش‌های دوره‌ای", callback_data="admin_periodic_reports", style="primary")
Line 151 (style=): builder.button(text="⚙️ تنظیمات متن /start", callback_data="admin_edit_start_text", style="success")
Line 152 (style=): builder.button(text="🛠 تنظیمات ربات", callback_data="admin_bot_settings", style="danger")
Line 153 (بازگشت به منوی کاربری): builder.button(text="🔙 بازگشت به منوی کاربری", callback_data="back_to_main", style="danger")
Line 168 (admin_dashboard): @router.callback_query(F.data == "admin_dashboard_back")
Line 169 (admin_dashboard): async def admin_dashboard_back(callback: CallbackQuery, state: FSMContext = None):
Line 194 (style=): builder.button(text="📢 پیام همگانی", callback_data="admin_broadcast", style="primary")
Line 195 (style=): builder.button(text="👤 مدیریت کاربران", callback_data="admin_manage_user", style="primary")
Line 196 (style=): builder.button(text="🎁 افزودن گیفت کارت", callback_data="admin_add_giftcard", style="primary")
Line 197 (style=): builder.button(text="📋 مدیریت گیفت کارت‌ها", callback_data="admin_manage_gcs_1", style="primary")
Line 198 (style=): builder.button(text="🛒 مدیریت فروشگاه", callback_data="admin_manage_products", style="primary")
Line 199 (style=): builder.button(text="📦 مدیریت سفارش‌ها", callback_data="admin_manage_orders_1", style="primary")
Line 200 (style=): builder.button(text="📊 گزارش‌های دوره‌ای", callback_data="admin_periodic_reports", style="primary")
Line 201 (style=): builder.button(text="⚙️ تنظیمات متن /start", callback_data="admin_edit_start_text", style="success")
Line 202 (style=): builder.button(text="🛠 تنظیمات ربات", callback_data="admin_bot_settings", style="danger")
Line 220 (admin_dashboard): builder.button(text="❌ لغو", callback_data="admin_dashboard_back")
Line 222 (ارسال پیام): "📢 <b>ارسال پیام همگانی</b>\n\n"
Line 233 (admin_dashboard): return await admin_dashboard(message, prefix_text="❌ عملیات ارسال همگانی لغو شد.\n\n")
Line 242 (ارسال پیام): await message.answer(f"📢 ارسال پیام همگانی به {len(all_users)} کاربر آغاز شد...")
Line 268 (admin_dashboard): await admin_dashboard(message, prefix_text=report_text)
Line 278 (admin_dashboard): builder.button(text="🔙 بازگشت به داشبورد", callback_data="admin_dashboard_back")
Line 432 (admin_dashboard): builder.row(InlineKeyboardButton(text="❌ لغو", callback_data="admin_dashboard_back"))
Line 454 (admin_dashboard): builder.button(text="❌ انصراف", callback_data="admin_dashboard_back")
Line 473 (admin_dashboard): return await admin_dashboard(message, prefix_text="❌ عملیات افزودن گیفت کارت لغو شد.\n\n")
Line 514 (admin_dashboard): return await admin_dashboard(message, prefix_text=f"❌ خطا در خواندن فایل: {e}\n\n")
Line 540 (admin_dashboard): await admin_dashboard(message, prefix_text=f"✅ تعداد {added} کد با موفقیت به محصول <b>{prod_name}</b> اضافه شد.\n\n")
Line 664 (admin_dashboard): builder.button(text="🔙 بازگشت به داشبورد", callback_data="admin_dashboard_back")
Line 682 (ارسال پیام): builder.button(text="✉️ ارسال پیام", callback_data=f"admin_send_msg_{user.telegram_id}")
Line 715 (admin_dashboard): builder.button(text="🔙 بازگشت به داشبورد", callback_data="admin_dashboard_back")
Line 973 (emoji): def _order_status_emoji(status: str | None) -> str:
Line 1007 (admin_dashboard): builder.button(text="🔙 بازگشت", callback_data="admin_dashboard_back")
Line 1024 (emoji): status_emoji = _order_status_emoji(o.status)
Line 1026 (emoji): text=f"📦 #{o.id} - {p_name} ({status_emoji})",
Line 1040 (admin_dashboard): builder.row(InlineKeyboardButton(text="🔙 بازگشت به داشبورد", callback_data="admin_dashboard_back"))
Line 1066 (emoji): status_text = f"{_order_status_label(o.status)} {_order_status_emoji(o.status)}"
Line 1073 (style=): builder.button(text="✅ پرداخت موفق و تحویل", callback_data=f"adm_ord_payok_{o.id}_{back_page}", style="success")
Line 1074 (style=): builder.button(text="❌ پرداخت ناموفق", callback_data=f"adm_ord_payfail_{o.id}_{back_page}", style="danger")
Line 1079 (style=): builder.button(text="↩️ ریباند سفارش", callback_data=f"adm_ord_refund_{o.id}_{back_page}", style="danger")
Line 1308 (style=): builder.button(text="✏️ متن کاربران تایید شده", callback_data="admin_edit_start_verified", style="primary")
Line 1309 (style=): builder.button(text="✏️ متن کاربران تایید نشده", callback_data="admin_edit_start_unverified", style="primary")
Line 1310 (style=): builder.button(text="🔄 ریست به حالت پیش‌فرض", callback_data="admin_reset_start_texts", style="danger")
Line 1311 (admin_dashboard): builder.button(text="🔙 بازگشت به داشبورد", callback_data="admin_dashboard_back", style="danger")
Line 1345 (style=): builder.button(text="❌ انصراف", callback_data="admin_edit_start_text", style="danger")
Line 1362 (style=): builder.button(text="❌ انصراف", callback_data="admin_edit_start_text", style="danger")
Line 1383 (style=): builder.button(text="🔙 بازگشت به تنظیمات", callback_data="admin_edit_start_text", style="primary")
Line 1397 (style=): builder.button(text="🔙 بازگشت به تنظیمات", callback_data="admin_edit_start_text", style="primary")
Line 1434 (usdt_rate): usdt_rate = await get_setting(session, "usdt_rate", "60000")
Line 1462 (usdt_rate): builder.button(text="💵 تنظیم نرخ تتر", callback_data="admin_set_usdt_rate")
Line 1468 (emoji): builder.button(text="✨ تنظیم کاستوم ایموجی‌ها", callback_data="admin_emoji_settings_1")
Line 1472 (admin_dashboard): builder.button(text="🔙 بازگشت به داشبورد", callback_data="admin_dashboard_back", style="danger")
Line 1482 (usdt_rate): f"💵 <b>نرخ تتر (تومان):</b> <code>{usdt_rate}</code>\n"
Line 1499 (emoji): @router.callback_query(F.data.startswith("admin_emoji_settings_"))
Line 1500 (emoji): async def admin_emoji_settings_menu(callback: CallbackQuery, state: FSMContext = None):
Line 1515 (custom_emoji): overrides = get_custom_emoji_overrides()
Line 1518 (emoji): for offset, emoji in enumerate(current_items):
Line 1520 (emoji): status = "اختصاصی" if emoji in overrides else "پیش‌فرض"
Line 1522 (emoji): text=f"{idx + 1}. {emoji} - {_emoji_label(emoji)} ({status})",
Line 1523 (emoji): callback_data=f"admin_emoji_edit_{idx}_{page}"
Line 1529 (emoji): nav.append(InlineKeyboardButton(text="قبلی", callback_data=f"admin_emoji_settings_{page - 1}"))
Line 1531 (emoji): nav.append(InlineKeyboardButton(text="بعدی", callback_data=f"admin_emoji_settings_{page + 1}"))
Line 1535 (emoji): InlineKeyboardButton(text="تنظیم گروهی", callback_data="admin_emoji_bulk"),
Line 1536 (emoji): InlineKeyboardButton(text="ریست همه", callback_data="admin_emoji_reset_all")
Line 1545 (custom_emoji): f"اختصاصی: ادمین برای آن custom_emoji_id تنظیم کرده است.\n"
Line 1556 (emoji): @router.callback_query(F.data.startswith("admin_emoji_edit_"))
Line 1557 (emoji): async def admin_emoji_edit_prompt(callback: CallbackQuery, state: FSMContext):
Line 1566 (emoji): emoji = ADMIN_EMOJI_ITEMS[idx]
Line 1567 (custom_emoji): overrides = get_custom_emoji_overrides()
Line 1568 (emoji): current_id = get_effective_emoji_id(emoji) or "ندارد"
Line 1569 (emoji): custom_id = overrides.get(emoji)
Line 1571 (emoji): await state.update_data(edit_emoji=emoji, edit_emoji_page=page)
Line 1574 (emoji): builder.button(text="ریست همین ایموجی", callback_data=f"admin_emoji_reset_{idx}_{page}")
Line 1575 (emoji): builder.button(text="انصراف", callback_data=f"admin_emoji_settings_{page}")
Line 1581 (emoji): f"ایموجی: {emoji}\n"
Line 1582 (emoji): f"کاربرد: {_emoji_label(emoji)}\n"
Line 1585 (custom_emoji): f"custom_emoji_id جدید را ارسال کنید.\n"
Line 1590 (custom_emoji): await state.set_state(AdminState.waiting_for_custom_emoji_id)
Line 1593 (custom_emoji): @router.message(AdminState.waiting_for_custom_emoji_id)
Line 1594 (custom_emoji): async def process_custom_emoji_id(message: Message, state: FSMContext):
Line 1598 (emoji): emoji = data.get("edit_emoji")
Line 1599 (emoji): page = int(data.get("edit_emoji_page", 1))
Line 1604 (custom_emoji): if entity.type == "custom_emoji" and entity.custom_emoji_id:
Line 1605 (custom_emoji): val = entity.custom_emoji_id
Line 1609 (custom_emoji): overrides = get_custom_emoji_overrides()
Line 1612 (emoji): overrides.pop(emoji, None)
Line 1613 (custom_emoji): elif _valid_custom_emoji_id(val):
Line 1614 (emoji): overrides[emoji] = val
Line 1616 (custom_emoji): return await message.answer("⚠️ مقدار معتبر نیست. فقط custom_emoji_id عددی را ارسال کنید یا reset بفرستید:")
Line 1618 (custom_emoji): set_custom_emoji_overrides(overrides)
Line 1624 (emoji): builder.button(text="بازگشت به تنظیم ایموجی‌ها", callback_data=f"admin_emoji_settings_{page}")
Line 1626 (emoji): f"تنظیم ایموجی {emoji} ذخیره شد.\n"
Line 1627 (emoji): f"کاربرد: {_emoji_label(emoji)}\n"
Line 1628 (emoji): f"ID نهایی: <code>{get_effective_emoji_id(emoji) or 'ندارد'}</code>",
Line 1632 (emoji): @router.callback_query(F.data.regexp(r"^admin_emoji_reset_\d+_\d+$"))
Line 1633 (emoji): async def admin_emoji_reset_one(callback: CallbackQuery):
Line 1639 (emoji): emoji = ADMIN_EMOJI_ITEMS[idx]
Line 1640 (custom_emoji): overrides = get_custom_emoji_overrides()
Line 1641 (emoji): overrides.pop(emoji, None)
Line 1642 (custom_emoji): set_custom_emoji_overrides(overrides)
Line 1646 (emoji): await admin_emoji_settings_menu(callback)
Line 1648 (emoji): @router.callback_query(F.data == "admin_emoji_reset_all")
Line 1649 (emoji): async def admin_emoji_reset_all(callback: CallbackQuery):
Line 1652 (custom_emoji): set_custom_emoji_overrides({})
Line 1656 (emoji): await admin_emoji_settings_menu(callback)
Line 1658 (emoji): @router.callback_query(F.data == "admin_emoji_bulk")
Line 1659 (emoji): async def admin_emoji_bulk_prompt(callback: CallbackQuery, state: FSMContext):
Line 1663 (emoji): builder.button(text="انصراف", callback_data="admin_emoji_settings_1")
Line 1675 (custom_emoji): await state.set_state(AdminState.waiting_for_custom_emoji_bulk)
Line 1678 (custom_emoji): @router.message(AdminState.waiting_for_custom_emoji_bulk)
Line 1679 (custom_emoji): async def process_custom_emoji_bulk(message: Message, state: FSMContext):
Line 1715 (emoji): # Check for custom emoji entity on this line
Line 1716 (custom_emoji): line_custom_emoji_id = None
Line 1718 (custom_emoji): if entity.type == "custom_emoji" and entity.custom_emoji_id:
Line 1720 (custom_emoji): line_custom_emoji_id = entity.custom_emoji_id
Line 1723 (emoji): # Find standard emoji character on this line
Line 1724 (emoji): found_emoji = None
Line 1725 (emoji): for emoji in sorted(BASE_EMOJI_ID_MAPPING.keys(), key=len, reverse=True):
Line 1726 (emoji): if emoji in line_text:
Line 1727 (emoji): found_emoji = emoji
Line 1730 (emoji): if found_emoji:
Line 1731 (custom_emoji): if line_custom_emoji_id:
Line 1732 (custom_emoji): parsed[found_emoji] = line_custom_emoji_id
Line 1736 (emoji): parsed[found_emoji] = match.group(1)
Line 1738 (custom_emoji): overrides = get_custom_emoji_overrides()
Line 1739 (emoji): for emoji, emoji_id in parsed.items():
Line 1740 (custom_emoji): if _valid_custom_emoji_id(str(emoji_id)):
Line 1741 (emoji): overrides[str(emoji)] = str(emoji_id).strip()
Line 1743 (custom_emoji): set_custom_emoji_overrides(overrides)
Line 1749 (emoji): builder.button(text="بازگشت به تنظیم ایموجی‌ها", callback_data="admin_emoji_settings_1")
Line 1999 (admin_dashboard): await admin_dashboard(message, prefix_text=f"✅ کاربر با آیدی <code>{new_admin_id}</code> با موفقیت ادمین شد.\n\n")
Line 2230 (waiting_for_user_message): await state.set_state(AdminState.waiting_for_user_message)
Line 2238 (waiting_for_user_message): @router.message(AdminState.waiting_for_user_message)
Line 2243 (admin_dashboard): return await admin_dashboard(message)
Line 2252 (ارسال پیام): await message.answer(f"❌ خطا در ارسال پیام به کاربر: {e}")
Line 2257 (usdt_rate): @router.callback_query(F.data == "admin_set_usdt_rate")
Line 2258 (usdt_rate): async def ask_usdt_rate(callback: CallbackQuery, state: FSMContext):
Line 2259 (usdt_rate): await state.set_state(AdminState.waiting_for_usdt_rate)
Line 2263 (تتر): "💵 لطفاً نرخ روز تتر را به تومان وارد کنید (مثلا 60000):",
Line 2267 (usdt_rate): @router.message(AdminState.waiting_for_usdt_rate)
Line 2268 (usdt_rate): async def process_usdt_rate(message: Message, state: FSMContext):
Line 2277 (usdt_rate): await set_setting(session, "usdt_rate", str(rate))
Line 2279 (تتر): await message.answer(f"✅ نرخ تتر با موفقیت به {rate:,.0f} تومان تنظیم شد.")
Line 2281 (admin_dashboard): await admin_dashboard(message)