56 lines
1.6 KiB
TypeScript
56 lines
1.6 KiB
TypeScript
"use client";
|
||
|
||
// ============================================================================
|
||
// Protected Route Component
|
||
// ============================================================================
|
||
|
||
import React, { useEffect } from "react";
|
||
import { useRouter, useParams } from "next/navigation";
|
||
import { useAuth } from "./auth-provider";
|
||
import { isDemoWorkspace } from "@/lib/demo";
|
||
|
||
interface ProtectedRouteProps {
|
||
children: React.ReactNode;
|
||
}
|
||
|
||
export const ProtectedRoute: React.FC<ProtectedRouteProps> = ({ children }) => {
|
||
const { user, loading } = useAuth();
|
||
const router = useRouter();
|
||
const params = useParams();
|
||
|
||
// Check if this is demo mode
|
||
const workspaceId = params?.workspaceId as string | undefined;
|
||
const isDemo = isDemoWorkspace(workspaceId);
|
||
|
||
useEffect(() => {
|
||
// Skip auth check for demo mode
|
||
if (isDemo) return;
|
||
|
||
if (!loading && !user) {
|
||
router.push("/login");
|
||
}
|
||
}, [user, loading, router, isDemo]);
|
||
|
||
// Demo mode - skip auth entirely
|
||
if (isDemo) {
|
||
return <>{children}</>;
|
||
}
|
||
|
||
if (loading) {
|
||
return (
|
||
<div className="flex items-center justify-center min-h-screen">
|
||
<div className="text-center">
|
||
<div className="inline-block h-8 w-8 animate-spin rounded-full border-4 border-solid border-current border-r-transparent align-[-0.125em] motion-reduce:animate-[spin_1.5s_linear_infinite]" />
|
||
<p className="mt-4 text-sm text-muted-foreground">Загрузка...</p>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
if (!user) {
|
||
return null;
|
||
}
|
||
|
||
return <>{children}</>;
|
||
};
|