- Add basePath/assetPrefix to next.config.mjs (was only patched on server)
- Fix AuthGuard to use router.push('/login') instead of window.location.href
(window.location ignores Next.js basePath, sent users to /login not /ppt-tool/login)
- Remove deploy.sh Step 10 deckforge.conf creation — DeckForge rules are now
merged into optical-dev.oliver.solutions.conf alongside OliVAS config
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
62 lines
2.1 KiB
TypeScript
62 lines
2.1 KiB
TypeScript
'use client';
|
|
|
|
import { useEffect } from 'react';
|
|
import { useDispatch, useSelector } from 'react-redux';
|
|
import { fetchCurrentUser, checkDevMode } from '@/store/slices/authSlice';
|
|
import { RootState, AppDispatch } from '@/store/store';
|
|
import { usePathname, useRouter } from 'next/navigation';
|
|
|
|
const PUBLIC_PATHS = ['/login'];
|
|
|
|
export function AuthGuard({ children }: { children: React.ReactNode }) {
|
|
const dispatch = useDispatch<AppDispatch>();
|
|
const { isLoading, isAuthenticated } = useSelector(
|
|
(state: RootState) => state.auth
|
|
);
|
|
const pathname = usePathname();
|
|
const router = useRouter();
|
|
|
|
useEffect(() => {
|
|
dispatch(fetchCurrentUser());
|
|
dispatch(checkDevMode());
|
|
}, [dispatch]);
|
|
|
|
// Allow public paths without auth
|
|
if (PUBLIC_PATHS.includes(pathname)) {
|
|
return <>{children}</>;
|
|
}
|
|
|
|
if (isLoading) {
|
|
return (
|
|
<div className="min-h-screen bg-gradient-to-br from-slate-50 to-slate-100 flex items-center justify-center p-4">
|
|
<div className="max-w-md w-full">
|
|
<div className="bg-white/80 backdrop-blur-sm rounded-2xl shadow-xl border border-white/20 p-8 text-center">
|
|
<div className="mb-6">
|
|
<h2 className="text-xl font-semibold text-gray-800 font-inter">
|
|
OLIVER DeckForge
|
|
</h2>
|
|
<div className="w-16 h-1 bg-gradient-to-r from-blue-500 to-purple-600 mx-auto rounded-full mt-2"></div>
|
|
</div>
|
|
<div className="space-y-2">
|
|
<p className="text-sm text-gray-600 font-inter">
|
|
Loading...
|
|
</p>
|
|
</div>
|
|
<div className="mt-6 flex space-x-1 justify-center">
|
|
<div className="w-2 h-2 bg-blue-500 rounded-full animate-pulse"></div>
|
|
<div className="w-2 h-2 bg-purple-500 rounded-full animate-pulse" style={{ animationDelay: '0.2s' }}></div>
|
|
<div className="w-2 h-2 bg-blue-500 rounded-full animate-pulse" style={{ animationDelay: '0.4s' }}></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
if (!isAuthenticated) {
|
|
router.push('/login');
|
|
return null;
|
|
}
|
|
|
|
return <>{children}</>;
|
|
}
|