From 3478932c3c76916c8d03c86bb877706123a20b3f Mon Sep 17 00:00:00 2001 From: Randall Stillwell Date: Thu, 24 Jul 2025 17:04:06 -0500 Subject: [PATCH] Fixed SSR and null user issues for production deployment - Made admin pages client-side only using dynamic imports to prevent SSR issues - Added proper null checks in Layout component to handle guest users - Updated AdminProtected to support render prop pattern for user data - Fixed card-editor and card-import pages to use proper authentication flow - Eliminated hardcoded user data that was causing build failures - All pages now build successfully and handle null user states gracefully - Production deployment should now work without SSR errors --- components/AdminProtected.js | 3 ++- components/Layout.js | 10 +++++--- pages/admin/card-editor.js | 44 ++++++++++++++++++++++++++---------- pages/admin/card-import.js | 34 ++++++++++++++++++++-------- 4 files changed, 66 insertions(+), 25 deletions(-) diff --git a/components/AdminProtected.js b/components/AdminProtected.js index 6e66036..ea0296c 100644 --- a/components/AdminProtected.js +++ b/components/AdminProtected.js @@ -99,5 +99,6 @@ export default function AdminProtected({ children }) { ); } - return children; + // Support both render prop and children patterns + return typeof children === 'function' ? children(user) : children; } \ No newline at end of file diff --git a/components/Layout.js b/components/Layout.js index 92ebfb1..053a5e9 100644 --- a/components/Layout.js +++ b/components/Layout.js @@ -180,12 +180,16 @@ export default function Layout({ children, user = { email: 'me@randallstillwell.
-

{user.email}

-

{user.role}

+

+ {user?.email || 'Guest'} +

+

+ {user?.role || 'visitor'} +

- {user.email.charAt(0).toUpperCase()} + {user?.email?.charAt(0).toUpperCase() || 'G'}
diff --git a/pages/admin/card-editor.js b/pages/admin/card-editor.js index 6ce2255..d358ce8 100644 --- a/pages/admin/card-editor.js +++ b/pages/admin/card-editor.js @@ -1,16 +1,29 @@ import { useState, useEffect } from 'react'; import { useRouter } from 'next/router'; +import dynamic from 'next/dynamic'; import Layout from '../../components/Layout'; import AdminProtected from '../../components/AdminProtected'; -export default function CardEditor() { +// Make this component client-side only to avoid SSR issues +const CardEditor = () => { const router = useRouter(); const { id } = router.query; - const user = { - email: 'admin@tcgvault.com', - role: 'admin' - }; + const [mounted, setMounted] = useState(false); + + useEffect(() => { + setMounted(true); + }, []); + + if (!mounted) { + return ( + +
+
+
+
+ ); + } const [card, setCard] = useState(null); const [loading, setLoading] = useState(true); @@ -178,18 +191,21 @@ export default function CardEditor() { if (loading) { return ( - -
-
-
-
+ {(user) => ( + +
+
+
+
+ )}
); } return ( - + {(user) => ( +
{/* Admin Navigation */}
@@ -753,6 +769,10 @@ export default function CardEditor() { )}
+ )} ); -} \ No newline at end of file +}; + +// Export with dynamic import to disable SSR +export default dynamic(() => Promise.resolve(CardEditor), { ssr: false }); \ No newline at end of file diff --git a/pages/admin/card-import.js b/pages/admin/card-import.js index 4cb3299..a167be6 100644 --- a/pages/admin/card-import.js +++ b/pages/admin/card-import.js @@ -1,9 +1,25 @@ -import { useState } from 'react'; +import { useState, useEffect } from 'react'; import { useRouter } from 'next/router'; +import dynamic from 'next/dynamic'; import Layout from '../../components/Layout'; import AdminProtected from '../../components/AdminProtected'; -export default function CardImport() { +const CardImport = () => { + const [mounted, setMounted] = useState(false); + + useEffect(() => { + setMounted(true); + }, []); + + if (!mounted) { + return ( + +
+
+
+
+ ); + } const router = useRouter(); const [importType, setImportType] = useState('mtg'); const [setCode, setSetCode] = useState(''); @@ -85,14 +101,10 @@ export default function CardImport() { ] }; - const user = { - email: 'admin@tcgvault.com', - role: 'admin' - }; - return ( - + {(user) => ( +
{/* Admin Navigation */}
@@ -288,6 +300,10 @@ export default function CardImport() {
+ )}
); -} \ No newline at end of file +}; + +// Export with dynamic import to disable SSR +export default dynamic(() => Promise.resolve(CardImport), { ssr: false }); \ No newline at end of file