From dee3e428bdfff88095a69c615317f1d5085fba86 Mon Sep 17 00:00:00 2001 From: ajaysi Date: Wed, 24 Sep 2025 12:48:49 +0530 Subject: [PATCH] Implement route protection for onboarding - Create ProtectedRoute component to guard routes based on onboarding status - Protect all non-onboarding routes (dashboard, blog-writer, seo, etc.) - Users must complete onboarding before accessing any features - Prevents confusion and broken functionality for new users - Improves user experience by guiding users through proper setup --- frontend/src/App.tsx | 39 +++++-- .../src/components/shared/ProtectedRoute.tsx | 107 ++++++++++++++++++ 2 files changed, 138 insertions(+), 8 deletions(-) create mode 100644 frontend/src/components/shared/ProtectedRoute.tsx diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 7d3b353f..e5844351 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -10,6 +10,7 @@ import ContentPlanningDashboard from './components/ContentPlanningDashboard/Cont import FacebookWriter from './components/FacebookWriter/FacebookWriter'; import LinkedInWriter from './components/LinkedInWriter/LinkedInWriter'; import BlogWriter from './components/BlogWriter/BlogWriter'; +import ProtectedRoute from './components/shared/ProtectedRoute'; import { apiClient } from './api/client'; @@ -170,9 +171,31 @@ const App: React.FC = () => { ); } + // Check if CopilotKit API key is available + const copilotApiKey = process.env.REACT_APP_COPILOTKIT_API_KEY; + + // If no CopilotKit API key, render without CopilotKit wrapper + if (!copilotApiKey) { + return ( + + + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + + + ); + } + return ( console.error("CopilotKit Error:", e)} @@ -182,13 +205,13 @@ const App: React.FC = () => { } /> } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> diff --git a/frontend/src/components/shared/ProtectedRoute.tsx b/frontend/src/components/shared/ProtectedRoute.tsx new file mode 100644 index 00000000..befa795d --- /dev/null +++ b/frontend/src/components/shared/ProtectedRoute.tsx @@ -0,0 +1,107 @@ +import React, { useState, useEffect } from 'react'; +import { Navigate } from 'react-router-dom'; +import { Box, CircularProgress, Typography } from '@mui/material'; +import { apiClient } from '../../api/client'; + +interface ProtectedRouteProps { + children: React.ReactNode; +} + +interface OnboardingStatus { + is_completed: boolean; + current_step: number; + completion_percentage: number; + next_step?: number; + started_at: string; + completed_at?: string; + can_proceed_to_final: boolean; +} + +const ProtectedRoute: React.FC = ({ children }) => { + const [loading, setLoading] = useState(true); + const [onboardingComplete, setOnboardingComplete] = useState(false); + const [error, setError] = useState(null); + + useEffect(() => { + const checkOnboardingStatus = async () => { + try { + console.log('ProtectedRoute: Checking onboarding status...'); + const response = await apiClient.get('/api/onboarding/status'); + const status: OnboardingStatus = response.data; + + console.log('ProtectedRoute: Onboarding status:', status); + + if (status.is_completed) { + console.log('ProtectedRoute: Onboarding is complete, allowing access'); + setOnboardingComplete(true); + } else { + console.log('ProtectedRoute: Onboarding not complete, redirecting to onboarding'); + setOnboardingComplete(false); + } + } catch (err) { + console.error('ProtectedRoute: Error checking onboarding status:', err); + setError('Failed to check onboarding status'); + // On error, assume onboarding is not complete for security + setOnboardingComplete(false); + } finally { + setLoading(false); + } + }; + + checkOnboardingStatus(); + }, []); + + if (loading) { + return ( + + + + Verifying access... + + + ); + } + + if (error) { + return ( + + + Access Error + + + {error} + + + Please complete the setup process first. + + + ); + } + + // If onboarding is not complete, redirect to onboarding + if (!onboardingComplete) { + console.log('ProtectedRoute: Redirecting to onboarding'); + return ; + } + + // If onboarding is complete, render the protected component + console.log('ProtectedRoute: Rendering protected component'); + return <>{children}; +}; + +export default ProtectedRoute;