Files
vexplor/frontend/components/auth/AuthGuard.tsx
DDD1542 27853a9447 feat: Add BOM tree view and BOM item editor components
- Introduced new components for BOM tree view and BOM item editor, enhancing the data management capabilities within the application.
- Updated the ComponentsPanel to include these new components with appropriate descriptions and default sizes.
- Integrated the BOM item editor into the V2PropertiesPanel for seamless editing of BOM items.
- Adjusted the SplitLineComponent to improve the handling of canvas split positions, ensuring better user experience during component interactions.
2026-02-24 10:49:23 +09:00

112 lines
2.8 KiB
TypeScript

"use client";
import { useEffect, ReactNode } from "react";
import { useRouter } from "next/navigation";
import { useAuth } from "@/hooks/useAuth";
import { Loader2 } from "lucide-react";
interface AuthGuardProps {
children: ReactNode;
requireAuth?: boolean;
requireAdmin?: boolean;
redirectTo?: string;
fallback?: ReactNode;
}
/**
* 인증 보호 컴포넌트
* 로그인 상태 및 권한에 따라 접근을 제어
* - 토큰 갱신/401 처리는 client.ts 인터셉터가 담당
* - 이 컴포넌트는 인증 상태 기반 라우팅 가드 역할만 수행
*/
export function AuthGuard({
children,
requireAuth = true,
requireAdmin = false,
redirectTo = "/login",
fallback,
}: AuthGuardProps) {
const { isLoggedIn, isAdmin, loading } = useAuth();
const router = useRouter();
useEffect(() => {
if (loading) return;
// 토큰이 있는데 아직 인증 확인 중이면 대기
if (typeof window !== "undefined") {
const token = localStorage.getItem("authToken");
if (token && !isLoggedIn && !loading) {
return;
}
}
if (requireAuth && !isLoggedIn) {
router.push(redirectTo);
return;
}
if (requireAdmin && !isAdmin) {
router.push(redirectTo);
return;
}
}, [requireAuth, requireAdmin, loading, isLoggedIn, isAdmin, redirectTo, router]);
if (loading) {
return (
fallback || (
<div className="flex h-screen items-center justify-center">
<div className="flex flex-col items-center gap-3">
<Loader2 className="h-8 w-8 animate-spin text-primary" />
<p className="text-sm text-muted-foreground"> ...</p>
</div>
</div>
)
);
}
if (requireAuth && !isLoggedIn) {
return (
fallback || (
<div className="flex h-screen items-center justify-center">
<div className="flex flex-col items-center gap-3">
<Loader2 className="h-8 w-8 animate-spin text-primary" />
<p className="text-sm text-muted-foreground"> ...</p>
</div>
</div>
)
);
}
if (requireAdmin && !isAdmin) {
return (
fallback || (
<div className="flex h-screen items-center justify-center">
<p className="text-sm text-muted-foreground"> .</p>
</div>
)
);
}
return <>{children}</>;
}
/**
* 로그인 여부만 확인하는 간단한 가드
*/
export function RequireAuth({ children }: { children: ReactNode }) {
return <AuthGuard requireAuth={true}>{children}</AuthGuard>;
}
/**
* 관리자 권한을 요구하는 가드
*/
export function RequireAdmin({ children }: { children: ReactNode }) {
return (
<AuthGuard requireAuth={true} requireAdmin={true}>
{children}
</AuthGuard>
);
}
export default AuthGuard;