- Unified all inputs to use .input CSS class, consistent label styles, and btn-primary/btn-secondary buttons
- Fixed number inputs to use number | '' pattern allowing field clearing without default replacement
- Added field-level validation with inline error borders and messages
- Synced frontend constraints with backend Pydantic schemas (maxLength, min/max values)
- Fixed toggle switch dimensions across all admin forms
Fixed issue where users had to click the Telegram Mini App back button twice
in many admin pages. The replace flag was causing conflicts between Telegram's
BackButton internal history and React Router's history management.
Updated all 32 admin pages to use simple navigate() calls without replace flag.
Add replace: true to all navigate() calls in useBackButton hooks
Prevents history cycles when navigating back and forth
All 32 admin pages now use navigate(path, { replace: true })
Back button now goes directly to parent without cycling
Main sections navigate to /admin (15 pages)
Detail/edit pages navigate to parent lists (16 pages)
All pages use useBackButton hook with proper navigation paths
Native Telegram back button in Mini App, UI button on web
Email template pages keep UI-only back buttons as required
- Reduce base .btn padding from px-5 py-2.5 to px-4 py-2
- Change rounded-xl to rounded-lg for buttons
- Remove hover:scale effect for cleaner look
- Fix large buttons in AdminBanSystem, AdminBroadcastDetail
- Compact toggle buttons in AdminPromoOfferSend
- Replace plain input with search autocomplete
- Search by name, username, or Telegram ID
- Show user info with subscription status
- Filter to show only users with Telegram ID
- Create AdminPromoOfferTemplateEdit.tsx for template editing
- Create AdminPromoOfferSend.tsx for sending offers with result screen
- Add routes for /admin/promo-offers/templates/:id/edit and /admin/promo-offers/send
- Simplify AdminPromoOffers.tsx by removing modals
- Add i18n keys for new pages