import { Routes, Route, Navigate } from 'react-router-dom' import { useState, useEffect, createContext, lazy, Suspense } from 'react' import { AuthProvider, useAuth } from './contexts/AuthContext' import { LanguageProvider } from './i18n/LanguageContext' import { ToastProvider } from './components/ToastContainer' import { ThemeProvider } from './contexts/ThemeContext' import ErrorBoundary from './components/ErrorBoundary' import Layout from './components/Layout' import Tutorial from './components/Tutorial' import Modal from './components/Modal' import { api } from './utils/api' import { useLanguage } from './i18n/LanguageContext' import { useKeyboardShortcuts, DEFAULT_SHORTCUTS } from './hooks/useKeyboardShortcuts' // Lazy-loaded page components const Dashboard = lazy(() => import('./pages/Dashboard')) const PostProduction = lazy(() => import('./pages/PostProduction')) const PostDetail = lazy(() => import('./pages/PostDetail')) const Assets = lazy(() => import('./pages/Assets')) const Campaigns = lazy(() => import('./pages/Campaigns')) const CampaignDetail = lazy(() => import('./pages/CampaignDetail')) const Finance = lazy(() => import('./pages/Finance')) const Budgets = lazy(() => import('./pages/Budgets')) const Projects = lazy(() => import('./pages/Projects')) const ProjectDetail = lazy(() => import('./pages/ProjectDetail')) const Tasks = lazy(() => import('./pages/Tasks')) const Team = lazy(() => import('./pages/Team')) // Users page removed — unified into Team page const Settings = lazy(() => import('./pages/Settings')) const Brands = lazy(() => import('./pages/Brands')) const Login = lazy(() => import('./pages/Login')) const Artefacts = lazy(() => import('./pages/Artefacts')) const PostCalendar = lazy(() => import('./pages/PostCalendar')) const PublicReview = lazy(() => import('./pages/PublicReview')) const PublicPostReview = lazy(() => import('./pages/PublicPostReview')) const Issues = lazy(() => import('./pages/Issues')) const PublicIssueSubmit = lazy(() => import('./pages/PublicIssueSubmit')) const PublicIssueTracker = lazy(() => import('./pages/PublicIssueTracker')) const Translations = lazy(() => import('./pages/Translations')) const PublicTranslationReview = lazy(() => import('./pages/PublicTranslationReview')) const PublicBudgetApproval = lazy(() => import('./pages/PublicBudgetApproval')) const ForgotPassword = lazy(() => import('./pages/ForgotPassword')) const ResetPassword = lazy(() => import('./pages/ResetPassword')) // Permission levels (access control) export const PERMISSION_LEVELS = [ { value: 'superadmin', label: 'Super Admin' }, { value: 'manager', label: 'Manager' }, { value: 'contributor', label: 'Contributor' }, ] export const AppContext = createContext() function AppContent() { const { user, loading: authLoading, checkAuth, hasModule } = useAuth() const { t, lang, setLang } = useLanguage() const [teamMembers, setTeamMembers] = useState([]) const [brands, setBrands] = useState([]) const [teams, setTeams] = useState([]) const [roles, setRoles] = useState([]) const [loading, setLoading] = useState(true) const [showTutorial, setShowTutorial] = useState(false) const [showProfilePrompt, setShowProfilePrompt] = useState(false) const [showProfileModal, setShowProfileModal] = useState(false) const [profileForm, setProfileForm] = useState({ name: '', team_role: '', phone: '', brands: '' }) const [profileSaving, setProfileSaving] = useState(false) // Keyboard shortcuts useKeyboardShortcuts(DEFAULT_SHORTCUTS) useEffect(() => { if (user && !authLoading) { loadInitialData() // Check if tutorial should be shown if (user.tutorial_completed === 0) { setShowTutorial(true) } // Check if profile is incomplete if (!user.profileComplete && user.role !== 'superadmin') { setShowProfilePrompt(true) } else { setShowProfilePrompt(false) } } else if (!authLoading) { setLoading(false) } }, [user, authLoading]) const getBrandName = (brandId) => { if (!brandId) return null const brand = brands.find(b => String(b._id || b.id) === String(brandId)) if (!brand) return null return lang === 'ar' && brand.name_ar ? brand.name_ar : brand.name } const loadTeam = async () => { try { const data = await api.get('/users/team') const members = Array.isArray(data) ? data : [] setTeamMembers(members) return members } catch (err) { console.error('Failed to load team:', err) return [] } } const loadTeams = async () => { try { const data = await api.get('/teams') setTeams(Array.isArray(data) ? data : []) } catch (err) { console.error('Failed to load teams:', err) } } const loadRoles = async () => { try { const data = await api.get('/roles') setRoles(Array.isArray(data) ? data : []) } catch (err) { console.error('Failed to load roles:', err) } } const loadInitialData = async () => { try { const [, brandsData] = await Promise.all([ loadTeam(), api.get('/brands').then(d => Array.isArray(d) ? d : []).catch(() => []), loadTeams(), loadRoles(), ]) setBrands(brandsData) } catch (err) { console.error('Failed to load initial data:', err) } finally { setLoading(false) } } const handleTutorialComplete = async () => { try { await api.patch('/users/me/tutorial', { completed: true }) setShowTutorial(false) } catch (err) { console.error('Failed to complete tutorial:', err) } } if (authLoading || loading) { return (

{t('dashboard.loadingHub')}

) } return ( {/* Profile completion prompt */} {showProfilePrompt && (
⚠️

{t('profile.completeYourProfile')}

{t('profile.completeDesc')}

)} {/* Profile completion modal */} setShowProfileModal(false)} title={t('profile.completeYourProfile')} size="md">
setProfileForm(f => ({ ...f, name: e.target.value }))} className="w-full px-3 py-2 text-sm border border-border rounded-lg focus:outline-none focus:ring-2 focus:ring-brand-primary/20 focus:border-brand-primary" placeholder={t('team.fullName')} />
setProfileForm(f => ({ ...f, phone: e.target.value }))} className="w-full px-3 py-2 text-sm border border-border rounded-lg focus:outline-none focus:ring-2 focus:ring-brand-primary/20 focus:border-brand-primary" />
{/* Tutorial overlay */} {showTutorial && }
}> : } /> : } /> : } /> } /> } /> } /> } /> } /> } /> : }> } /> {hasModule('marketing') && <> } /> } /> } /> } /> } /> } /> } /> } /> } /> } {hasModule('finance') && (user?.role === 'superadmin' || user?.role === 'manager') && <> } /> } /> } {hasModule('projects') && <> } /> } /> } /> } {hasModule('issues') && } />} } /> } /> } />
) } function App() { return ( ) } export default App