🔧 Gemini AI Integration: - Added Google Gemini API as default OCR service - Auto-configures from GEMINI_AI_API_KEY environment variable - Fixed Puter.js authentication issues - Enhanced OCR settings with connection testing 🎨 Redesigned Scanner Queue: - New thumbnail + content layout with checkbox overlay - Smart quantity management (duplicates increment quantity) - Complete card information display from database - Two-row action layout (primary/secondary actions) - Floating bottom toolbar for bulk actions - Real card images from database �� Enhanced User Experience: - Fixed Canvas2D performance warnings - Better error handling and fallbacks - Improved responsive design - Database confirmation indicators - Professional card scanning workflow 📱 Mobile Ready: - Optimized layouts for mobile scanning - Touch-friendly controls and interactions - Improved visual feedback and status indicators
57 lines
No EOL
1.8 KiB
JavaScript
57 lines
No EOL
1.8 KiB
JavaScript
import { useEffect } from 'react';
|
|
import { useRouter } from 'next/router';
|
|
import { useAuth } from '../lib/use-auth';
|
|
import Layout from './Layout';
|
|
|
|
export default function ProtectedRoute({ children, adminOnly = false, allowPublic = false, publicFallback = null }) {
|
|
const { user, loading } = useAuth();
|
|
const router = useRouter();
|
|
|
|
useEffect(() => {
|
|
if (!loading) {
|
|
// If authentication is required and user is not logged in
|
|
if (!allowPublic && !user) {
|
|
router.push('/login');
|
|
return;
|
|
}
|
|
|
|
// If admin access is required and user is not admin
|
|
if (adminOnly && (!user || user.role !== 'admin')) {
|
|
router.push('/login');
|
|
return;
|
|
}
|
|
}
|
|
}, [user, loading, router, adminOnly, allowPublic]);
|
|
|
|
// Show loading while checking authentication
|
|
if (loading) {
|
|
return (
|
|
<Layout user={null}>
|
|
<div className="flex items-center justify-center min-h-screen">
|
|
<div className="text-center">
|
|
<div className="animate-spin rounded-full h-32 w-32 border-b-2 mx-auto mb-4" style={{ borderColor: 'var(--accent-ember)' }}></div>
|
|
<p style={{ color: 'var(--text-secondary)' }}>Loading...</p>
|
|
</div>
|
|
</div>
|
|
</Layout>
|
|
);
|
|
}
|
|
|
|
// If public access is allowed but user is not logged in, show public fallback
|
|
if (allowPublic && !user && publicFallback) {
|
|
return publicFallback;
|
|
}
|
|
|
|
// If authentication is required but user is not logged in, don't render anything (redirect will happen)
|
|
if (!allowPublic && !user) {
|
|
return null;
|
|
}
|
|
|
|
// If admin access is required but user is not admin, don't render anything (redirect will happen)
|
|
if (adminOnly && (!user || user.role !== 'admin')) {
|
|
return null;
|
|
}
|
|
|
|
// Render the protected content
|
|
return children;
|
|
}
|