Move admin state into AdminPage
Build and Push Docker Image / build-and-push (push) Failing after 21s

All admin state (tab, users, projects, loading/error, preview, reset
result) and the data loader were only used by AdminPage, so they now live
there as local state instead of in App's context. The page loads its data
when it opens (still gated on authUser.isAdmin; the server enforces it too).

Add tests: admin sees users and projects, deleting a user reloads the
list, and non-admins get no Admin button.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
nmemmertandClaude Opus 5.5 committed 2026-09-22 14:46:35 -04:00
1 parent 49ffefed54
commit 8c55765ae6
3 files changed
+88 -50

No files matched your search

-37
View File
@@ -47,8 +47,6 @@ import {
enableSharing,
disableSharing,
getSharedProject,
adminListUsers,
adminListProjects,
} from './syncService.js';
// Less-common pages are split into their own chunks so the first load only
@@ -89,14 +87,6 @@ const App = () => {
const [sharedViewToken] = useState(() => new URLSearchParams(window.location.search).get('share'));
const [sharedProject, setSharedProject] = useState(null);
const [sharedError, setSharedError] = useState('');
// Admin (only reachable/rendered when authUser.isAdmin)
const [adminTab, setAdminTab] = useState('users'); // 'users' | 'projects'
const [adminUsers, setAdminUsers] = useState([]);
const [adminProjects, setAdminProjects] = useState([]);
const [adminLoading, setAdminLoading] = useState(false);
const [adminError, setAdminError] = useState('');
const [adminViewProject, setAdminViewProject] = useState(null); // full project data being previewed
const [adminResetResult, setAdminResetResult] = useState(null); // { email, temporaryPassword } shown once
const [project, setProject] = useState(null);
// 'home' | 'setup' | 'study' | 'settings'
const [currentPage, setCurrentPage] = useState('home');
@@ -301,24 +291,6 @@ const App = () => {
});
}, [project?.id, currentPage]);
const loadAdminData = () => {
setAdminLoading(true);
setAdminError('');
Promise.all([adminListUsers(), adminListProjects()]).then(([usersResult, projectsResult]) => {
setAdminLoading(false);
if (!usersResult.ok || !projectsResult.ok) {
setAdminError(usersResult.error ?? projectsResult.error ?? 'Failed to load admin data.');
return;
}
setAdminUsers(usersResult.data);
setAdminProjects(projectsResult.data);
});
};
useEffect(() => {
if (currentPage === 'admin' && authUser?.isAdmin) loadAdminData();
}, [currentPage, authUser?.isAdmin]);
// Once we know who's signed in, reconcile the local project index against the server.
// Runs on every authUser change (including logout -> different login) so a previous
// account's stale suggestions never linger after switching users. Projects that exist
@@ -2291,15 +2263,6 @@ const deleteProject = (id) => {
speakOriginalWord,
loadVerseText,
importFinalScriptDocx,
// Admin
adminTab, setAdminTab,
adminUsers,
adminProjects,
adminLoading,
adminError,
adminViewProject, setAdminViewProject,
adminResetResult, setAdminResetResult,
loadAdminData,
// Functions defined inside App (cannot be module-level exports)
formatCrossRef,
buildGreekDefinitionHtml,