Remove replace flag from back button navigation to fix double-click issue

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.
This commit is contained in:
c0mrade
2026-02-04 06:11:29 +03:00
parent 55e2068606
commit 482bdd0b0d
32 changed files with 32 additions and 32 deletions

View File

@@ -590,7 +590,7 @@ export default function AdminApps() {
const { capabilities } = usePlatform();
// Use native Telegram back button in Mini App
useBackButton(() => navigate('/admin', { replace: true }));
useBackButton(() => navigate('/admin'));
const [selectedPlatform, setSelectedPlatform] = useState<string>('ios');
const [editingApp, setEditingApp] = useState<{ app: AppDefinition; isNew: boolean } | null>(null);

View File

@@ -119,7 +119,7 @@ export default function AdminBroadcastCreate() {
const queryClient = useQueryClient();
const fileInputRef = useRef<HTMLInputElement>(null);
useBackButton(() => navigate('/admin/broadcasts', { replace: true }));
useBackButton(() => navigate('/admin/broadcasts'));
// Channel selection
const [channel, setChannel] = useState<BroadcastChannel>('telegram');

View File

@@ -159,7 +159,7 @@ export default function AdminBroadcastDetail() {
const broadcastId = id ? parseInt(id, 10) : null;
useBackButton(() => navigate('/admin/broadcasts', { replace: true }));
useBackButton(() => navigate('/admin/broadcasts'));
// Fetch broadcast details
const {

View File

@@ -132,7 +132,7 @@ export default function AdminBroadcasts() {
const { capabilities } = usePlatform();
// Use native Telegram back button in Mini App
useBackButton(() => navigate('/admin', { replace: true }));
useBackButton(() => navigate('/admin'));
const [page, setPage] = useState(0);
const limit = 20;

View File

@@ -156,7 +156,7 @@ export default function AdminCampaignCreate() {
const navigate = useNavigate();
const queryClient = useQueryClient();
useBackButton(() => navigate('/admin/campaigns', { replace: true }));
useBackButton(() => navigate('/admin/campaigns'));
// Form state
const [name, setName] = useState('');

View File

@@ -133,7 +133,7 @@ export default function AdminCampaignEdit() {
const campaignId = parseInt(id || '0');
useBackButton(() => navigate('/admin/campaigns', { replace: true }));
useBackButton(() => navigate('/admin/campaigns'));
// Fetch campaign
const {

View File

@@ -98,7 +98,7 @@ export default function AdminCampaignStats() {
const [copied, setCopied] = useState(false);
const [showUsers, setShowUsers] = useState(false);
useBackButton(() => navigate('/admin/campaigns', { replace: true }));
useBackButton(() => navigate('/admin/campaigns'));
// Fetch stats
const {

View File

@@ -68,7 +68,7 @@ export default function AdminCampaigns() {
const { capabilities } = usePlatform();
// Use native Telegram back button in Mini App
useBackButton(() => navigate('/admin', { replace: true }));
useBackButton(() => navigate('/admin'));
const [deleteConfirm, setDeleteConfirm] = useState<number | null>(null);

View File

@@ -366,7 +366,7 @@ export default function AdminDashboard() {
const { capabilities } = usePlatform();
// Use native Telegram back button in Mini App
useBackButton(() => navigate('/admin', { replace: true }));
useBackButton(() => navigate('/admin'));
const [stats, setStats] = useState<DashboardStats | null>(null);
const [loading, setLoading] = useState(true);

View File

@@ -73,7 +73,7 @@ export default function AdminPaymentMethodEdit() {
const { capabilities } = usePlatform();
// Use native Telegram back button in Mini App
useBackButton(() => navigate('/admin/payment-methods', { replace: true }));
useBackButton(() => navigate('/admin/payment-methods'));
// Fetch payment methods
const { data: methods, isLoading } = useQuery({

View File

@@ -240,7 +240,7 @@ export default function AdminPaymentMethods() {
const { capabilities } = usePlatform();
// Use native Telegram back button in Mini App
useBackButton(() => navigate('/admin', { replace: true }));
useBackButton(() => navigate('/admin'));
const [methods, setMethods] = useState<PaymentMethodConfig[]>([]);
const [orderChanged, setOrderChanged] = useState(false);

View File

@@ -29,7 +29,7 @@ export default function AdminPayments() {
const { capabilities } = usePlatform();
// Use native Telegram back button in Mini App
useBackButton(() => navigate('/admin', { replace: true }));
useBackButton(() => navigate('/admin'));
const [page, setPage] = useState(1);
const [methodFilter, setMethodFilter] = useState<string>('');

View File

@@ -56,7 +56,7 @@ export default function AdminPromoGroupCreate() {
const queryClient = useQueryClient();
const isEdit = !!id;
useBackButton(() => navigate('/admin/promo-groups', { replace: true }));
useBackButton(() => navigate('/admin/promo-groups'));
// Form state
const [name, setName] = useState('');

View File

@@ -62,7 +62,7 @@ export default function AdminPromoGroups() {
const { capabilities } = usePlatform();
// Use native Telegram back button in Mini App
useBackButton(() => navigate('/admin', { replace: true }));
useBackButton(() => navigate('/admin'));
const [deleteConfirm, setDeleteConfirm] = useState<number | null>(null);

View File

@@ -76,7 +76,7 @@ export default function AdminPromoOfferSend() {
const navigate = useNavigate();
const queryClient = useQueryClient();
useBackButton(() => navigate('/admin/promo-offers', { replace: true }));
useBackButton(() => navigate('/admin/promo-offers'));
const [selectedTemplateId, setSelectedTemplateId] = useState<number | null>(null);
const [sendMode, setSendMode] = useState<'segment' | 'user'>('segment');

View File

@@ -22,7 +22,7 @@ export default function AdminPromoOfferTemplateEdit() {
const { id } = useParams<{ id: string }>();
const queryClient = useQueryClient();
useBackButton(() => navigate('/admin/promo-offers', { replace: true }));
useBackButton(() => navigate('/admin/promo-offers'));
// Form state
const [name, setName] = useState('');

View File

@@ -109,7 +109,7 @@ export default function AdminPromoOffers() {
const { capabilities } = usePlatform();
// Use native Telegram back button in Mini App
useBackButton(() => navigate('/admin', { replace: true }));
useBackButton(() => navigate('/admin'));
const [activeTab, setActiveTab] = useState<'templates' | 'logs'>('templates');

View File

@@ -51,7 +51,7 @@ export default function AdminPromocodeCreate() {
const isEdit = !!id;
// Use native Telegram back button in Mini App
useBackButton(() => navigate('/admin/promocodes', { replace: true }));
useBackButton(() => navigate('/admin/promocodes'));
// Form state
const [code, setCode] = useState('');

View File

@@ -89,7 +89,7 @@ export default function AdminPromocodeStats() {
const navigate = useNavigate();
const { id } = useParams<{ id: string }>();
useBackButton(() => navigate('/admin/promocodes', { replace: true }));
useBackButton(() => navigate('/admin/promocodes'));
const {
data: promocode,

View File

@@ -114,7 +114,7 @@ export default function AdminPromocodes() {
const { capabilities } = usePlatform();
// Use native Telegram back button in Mini App
useBackButton(() => navigate('/admin', { replace: true }));
useBackButton(() => navigate('/admin'));
const [deleteConfirm, setDeleteConfirm] = useState<number | null>(null);
const [copiedCode, setCopiedCode] = useState<string | null>(null);

View File

@@ -879,7 +879,7 @@ export default function AdminRemnawave() {
const { capabilities } = usePlatform();
// Use native Telegram back button in Mini App
useBackButton(() => navigate('/admin', { replace: true }));
useBackButton(() => navigate('/admin'));
// State
const [activeTab, setActiveTab] = useState<TabType>('overview');

View File

@@ -55,7 +55,7 @@ export default function AdminRemnawaveSquadDetail() {
const { uuid } = useParams<{ uuid: string }>();
const navigate = useNavigate();
useBackButton(() => navigate('/admin/remnawave', { replace: true }));
useBackButton(() => navigate('/admin/remnawave'));
// Fetch all squads and find the one we need
const {

View File

@@ -49,7 +49,7 @@ export default function AdminServerEdit() {
const serverId = parseInt(id || '0');
useBackButton(() => navigate('/admin/servers', { replace: true }));
useBackButton(() => navigate('/admin/servers'));
const {
data: server,

View File

@@ -59,7 +59,7 @@ export default function AdminServers() {
const { capabilities } = usePlatform();
// Use native Telegram back button in Mini App
useBackButton(() => navigate('/admin', { replace: true }));
useBackButton(() => navigate('/admin'));
// Queries
const { data: serversData, isLoading } = useQuery({

View File

@@ -51,7 +51,7 @@ export default function AdminSettings() {
const { capabilities } = usePlatform();
// Use native Telegram back button in Mini App
useBackButton(() => navigate('/admin', { replace: true }));
useBackButton(() => navigate('/admin'));
// State
const [activeSection, setActiveSection] = useState('branding');

View File

@@ -92,7 +92,7 @@ export default function AdminTariffCreate() {
const queryClient = useQueryClient();
const isEdit = !!id;
useBackButton(() => navigate('/admin/tariffs', { replace: true }));
useBackButton(() => navigate('/admin/tariffs'));
// Step: null = type selection, 'period' or 'daily' = form
const [tariffType, setTariffType] = useState<TariffType>(null);

View File

@@ -77,7 +77,7 @@ export default function AdminTariffs() {
const { capabilities } = usePlatform();
// Use native Telegram back button in Mini App
useBackButton(() => navigate('/admin', { replace: true }));
useBackButton(() => navigate('/admin'));
// Queries
const { data: tariffsData, isLoading } = useQuery({

View File

@@ -22,7 +22,7 @@ export default function AdminTicketSettings() {
const navigate = useNavigate();
const queryClient = useQueryClient();
useBackButton(() => navigate('/admin/tickets', { replace: true }));
useBackButton(() => navigate('/admin/tickets'));
const {
data: settings,

View File

@@ -124,7 +124,7 @@ export default function AdminTickets() {
const { capabilities } = usePlatform();
// Use native Telegram back button in Mini App
useBackButton(() => navigate('/admin', { replace: true }));
useBackButton(() => navigate('/admin'));
const [selectedTicketId, setSelectedTicketId] = useState<number | null>(null);
const [statusFilter, setStatusFilter] = useState<string>('');

View File

@@ -82,7 +82,7 @@ export default function AdminUserDetail() {
const navigate = useNavigate();
const { id } = useParams<{ id: string }>();
useBackButton(() => navigate('/admin/users', { replace: true }));
useBackButton(() => navigate('/admin/users'));
const localeMap: Record<string, string> = { ru: 'ru-RU', en: 'en-US', zh: 'zh-CN', fa: 'fa-IR' };
const locale = localeMap[i18n.language] || 'ru-RU';

View File

@@ -399,7 +399,7 @@ export default function AdminUsers() {
const { capabilities } = usePlatform();
// Use native Telegram back button in Mini App
useBackButton(() => navigate('/admin', { replace: true }));
useBackButton(() => navigate('/admin'));
const [users, setUsers] = useState<UserListItem[]>([]);
const [stats, setStats] = useState<UsersStatsResponse | null>(null);

View File

@@ -292,7 +292,7 @@ export default function AdminWheel() {
const { capabilities } = usePlatform();
// Use native Telegram back button in Mini App
useBackButton(() => navigate('/admin', { replace: true }));
useBackButton(() => navigate('/admin'));
const [activeTab, setActiveTab] = useState<Tab>('settings');
const [expandedPrizeId, setExpandedPrizeId] = useState<number | null>(null);