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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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