fix(auth): wait for verify before scanner redirect; fix admin hooks (#36)

Scanner was sending logged-in users to /login while useAuth was still
loading. Admin card-editor/card-import crashed on login because hooks
ran after a mounted early return (Rules of Hooks violation).

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
varutasu 2026-05-27 12:36:58 -05:00 committed by GitHub
parent e81dd49752
commit ecb3ee12fc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 14 additions and 36 deletions

View file

@ -8,22 +8,6 @@ import AdminProtected from '../../components/AdminProtected';
const CardEditor = () => { const CardEditor = () => {
const router = useRouter(); const router = useRouter();
const { id } = router.query; const { id } = router.query;
const [mounted, setMounted] = useState(false);
useEffect(() => {
setMounted(true);
}, []);
if (!mounted) {
return (
<Layout user={null}>
<div className="flex items-center justify-center min-h-screen">
<div className="animate-spin rounded-full h-32 w-32 border-b-2" style={{ borderColor: 'var(--text-accent)' }}></div>
</div>
</Layout>
);
}
const [card, setCard] = useState(null); const [card, setCard] = useState(null);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);

View file

@ -5,21 +5,6 @@ import Layout from '../../components/Layout';
import AdminProtected from '../../components/AdminProtected'; import AdminProtected from '../../components/AdminProtected';
const CardImport = () => { const CardImport = () => {
const [mounted, setMounted] = useState(false);
useEffect(() => {
setMounted(true);
}, []);
if (!mounted) {
return (
<Layout user={null}>
<div className="flex items-center justify-center min-h-screen">
<div className="animate-spin rounded-full h-32 w-32 border-b-2" style={{ borderColor: 'var(--text-accent)' }}></div>
</div>
</Layout>
);
}
const router = useRouter(); const router = useRouter();
const [importType, setImportType] = useState('mtg'); const [importType, setImportType] = useState('mtg');
const [setCode, setSetCode] = useState(''); const [setCode, setSetCode] = useState('');

View file

@ -8,7 +8,7 @@ import ManaSymbolSettings from '../components/ManaSymbolSettings';
import { useAuth } from '../lib/use-auth'; import { useAuth } from '../lib/use-auth';
export default function Scanner() { export default function Scanner() {
const { user } = useAuth(); const { user, loading: authLoading } = useAuth();
const router = useRouter(); const router = useRouter();
const [scannedCards, setScannedCards] = useState([]); const [scannedCards, setScannedCards] = useState([]);
const [collections, setCollections] = useState([]); const [collections, setCollections] = useState([]);
@ -26,13 +26,12 @@ export default function Scanner() {
// Mana symbol settings // Mana symbol settings
const [manaSymbolSettings, setManaSymbolSettings] = useState({ useSVG: false }); const [manaSymbolSettings, setManaSymbolSettings] = useState({ useSVG: false });
// Redirect to login if not authenticated // Redirect to login if not authenticated (wait for verify to finish)
useEffect(() => { useEffect(() => {
if (!user) { if (!authLoading && !user) {
router.push('/login'); router.push('/login');
return;
} }
}, [user, router]); }, [authLoading, user, router]);
// Load collections and decks // Load collections and decks
useEffect(() => { useEffect(() => {
@ -325,6 +324,16 @@ export default function Scanner() {
setSelectedCards(new Set()); setSelectedCards(new Set());
}; };
if (authLoading) {
return (
<Layout user={null}>
<div className="flex items-center justify-center min-h-[50vh]">
<div className="animate-spin rounded-full h-12 w-12 border-b-2" style={{ borderColor: 'var(--text-accent)' }} />
</div>
</Layout>
);
}
if (!user) { if (!user) {
return <div>Redirecting to login...</div>; return <div>Redirecting to login...</div>;
} }