import React, { Suspense, useCallback, useMemo, useState, useEffect } from 'react';
import { ErrorBoundary } from './components/ErrorBoundary.tsx';
import { useGlobalState } from './contexts/GlobalStateContext.tsx';
import { logEvent } from './services/telemetryService.ts';
import { ALL_FEATURES, FEATURES_MAP } from './components/features/index.ts';
import type { ViewType, FeatureId, SidebarItem } from './types.ts';
import { DownloadManager } from './components/DownloadManager.tsx';
import { LeftSidebar } from './components/LeftSidebar.tsx';
import { StatusBar } from './components/StatusBar.tsx';
import { CommandPalette } from './components/CommandPalette.tsx';
import { SettingsView } from './components/SettingsView.tsx';
import { Cog6ToothIcon, HomeIcon } from './components/icons/InterfaceIcons.tsx';
import { AiCommandCenter } from './components/features/AiCommandCenter.tsx';
import { LoginView } from './components/LoginView.tsx';
export const LoadingIndicator: React.FC = () => (
);
interface LocalStorageConsentModalProps {
onAccept: () => void;
onDecline: () => void;
}
const LocalStorageConsentModal: React.FC = ({ onAccept, onDecline }) => {
return (
Store Data Locally?
This application uses your browser's local storage to save your settings and remember your progress between sessions. This data stays on your computer and is not shared.
Decline
Accept
);
};
const App: React.FC = () => {
const { state, dispatch } = useGlobalState();
const { activeView, viewProps, hiddenFeatures, isAuthenticated } = state;
const [isCommandPaletteOpen, setCommandPaletteOpen] = useState(false);
const [showConsentModal, setShowConsentModal] = useState(false);
useEffect(() => {
try {
const consent = localStorage.getItem('devcore_ls_consent');
if (!consent) {
setShowConsentModal(true);
}
} catch (e) {
console.warn("Could not access localStorage.", e);
}
}, []);
useEffect(() => {
const handleKeyDown = (e: KeyboardEvent) => {
if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
e.preventDefault();
setCommandPaletteOpen(isOpen => !isOpen);
}
};
window.addEventListener('keydown', handleKeyDown);
return () => window.removeEventListener('keydown', handleKeyDown);
}, []);
const handleAcceptConsent = () => {
try {
localStorage.setItem('devcore_ls_consent', 'granted');
window.location.reload();
} catch (e) {
console.error("Could not write to localStorage.", e);
setShowConsentModal(false);
}
};
const handleDeclineConsent = () => {
try {
localStorage.setItem('devcore_ls_consent', 'denied');
} catch (e) {
console.error("Could not write to localStorage.", e);
}
setShowConsentModal(false);
};
const handleViewChange = useCallback((view: ViewType, props: any = {}) => {
dispatch({ type: 'SET_VIEW', payload: { view, props } });
logEvent('view_changed', { view });
setCommandPaletteOpen(false);
}, [dispatch]);
const sidebarItems: SidebarItem[] = useMemo(() => [
{ id: 'ai-command-center', label: 'Command Center', icon: , view: 'ai-command-center' },
...ALL_FEATURES
.filter(feature => !hiddenFeatures.includes(feature.id) && feature.id !== 'ai-command-center')
.map(feature => ({
id: feature.id,
label: feature.name,
icon: feature.icon,
view: feature.id as ViewType,
})),
{ id: 'settings', label: 'Settings', icon: , view: 'settings' },
], [hiddenFeatures]);
const ActiveComponent = useMemo(() => {
if (activeView === 'settings') return SettingsView;
// Fallback to command center if no view is matched.
return FEATURES_MAP.get(activeView as string)?.component ?? AiCommandCenter;
}, [activeView]);
if (!isAuthenticated) {
return ;
}
return (
{showConsentModal &&
}
setCommandPaletteOpen(false)} onSelect={handleViewChange} />
);
};
export default App;