Fix dev bulk-delete button gate + reposition inside campaigns
Gate was process.env.NODE_ENV === 'development' — unsafe default. react-scripts inlines NODE_ENV=development when unset, so prod deploys forgetting the env var exposed the delete-all button. Switched to explicit opt-in REACT_APP_DEV_TOOLS=1. process.env.REACT_APP_DEV_TOOLS as static literal gets inlined by DefinePlugin at webpack build time — runtime mutations in tests had no effect, and dev-start without the env produced bundles with the branch dead-stripped. Extracted gate to src/config/devTools.js using dynamic key access (process.env['REACT_APP_' + 'DEV_TOOLS']) so DefinePlugin cannot inline it; the value is read at runtime. dev-start.sh now exports REACT_APP_DEV_TOOLS=1. Button had also drifted outside the campaigns collapse block to the page bottom; moved it back inside the campaigns section after the grid. Tests cover both paths: gate logic (unset/0/arbitrary/1) in BulkDelete.gate.test.js, prod safety render (button absent when unset) in BulkDelete.render-hidden.test.js, dev feature render (button present when DEV_TOOLS=1) in BulkDelete.render-shown.test.js.
This commit is contained in:
+13
-12
@@ -1,6 +1,7 @@
|
||||
import React, { useState, useEffect, useRef, useMemo, createContext, useContext, useCallback } from 'react';
|
||||
import * as shared from '@ttrpg/shared';
|
||||
import { initializeApp, getAuth, signInAnonymously, onAuthStateChanged, signInWithCustomToken, getFirestore, where, orderBy, limit, offset, getStorage, getStorageMode } from './storage';
|
||||
import { isDevToolsEnabled } from './config/devTools';
|
||||
import {
|
||||
PlusCircle, Users, Swords, Trash2, Eye, Edit3, Save, XCircle, ChevronsUpDown,
|
||||
UserCheck, UserX, HeartCrack, HeartPulse, Zap, EyeOff, ExternalLink, AlertTriangle,
|
||||
@@ -2754,6 +2755,18 @@ function AdminView({ userId }) {
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
{isDevToolsEnabled() && campaignsWithDetails.length > 0 && (
|
||||
<div className="mt-4">
|
||||
<button
|
||||
onClick={() => setShowDeleteAllConfirm(true)}
|
||||
className="px-3 py-1.5 text-xs rounded bg-red-900 hover:bg-red-800 text-red-100 border border-red-700"
|
||||
title="DEV ONLY: Delete every campaign, encounter, and log. Irreversible."
|
||||
>
|
||||
<Trash2 size={12} className="inline mr-1" />DEV: Delete All Campaigns
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
@@ -2800,18 +2813,6 @@ function AdminView({ userId }) {
|
||||
message={`Are you sure you want to delete the campaign "${itemToDelete?.name}" and all its encounters? This action cannot be undone.`}
|
||||
/>
|
||||
|
||||
{process.env.NODE_ENV === 'development' && campaignsWithDetails.length > 0 && (
|
||||
<div className="mt-4">
|
||||
<button
|
||||
onClick={() => setShowDeleteAllConfirm(true)}
|
||||
className="px-3 py-1.5 text-xs rounded bg-red-900 hover:bg-red-800 text-red-100 border border-red-700"
|
||||
title="DEV ONLY: Delete every campaign, encounter, and log. Irreversible."
|
||||
>
|
||||
<Trash2 size={12} className="inline mr-1" />DEV: Delete All Campaigns
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<ConfirmationModal
|
||||
isOpen={showDeleteAllConfirm}
|
||||
onClose={() => setShowDeleteAllConfirm(false)}
|
||||
|
||||
Reference in New Issue
Block a user