import React, { useEffect } from 'react'; import { useStore } from './store/useStore'; // Auth import LoginPage from './components/auth/LoginPage'; // Layout import Sidebar from './components/layout/Sidebar'; import { ToastContainer, useToastStore } from './components/layout/Toast'; // Editor import TableView from './components/editor/TableView'; import PropertyPanel from './components/editor/PropertyPanel'; import { ImportModal } from './components/editor/ImportModal'; // Plans import PlanListView from './components/plans/PlanListView'; import TaskExecutionView from './components/plans/TaskExecutionView'; // Shared import DashboardView from './components/shared/DashboardView'; import BugView from './components/shared/BugView'; import { Search, UploadCloud, LogOut } from 'lucide-react'; const App: React.FC = () => { const { spaces, currentSpaceId, setCurrentSpaceId, viewMode, setViewMode, fetchSpaces, fetchData, fetchTasks, fetchBugs, testTasks, setSelectedTaskId, showImportModal, setShowImportModal, currentUser, setCurrentUser, logout } = useStore(); const { addToast } = useToastStore(); useEffect(() => { if (currentUser) { fetchSpaces(); fetchTasks(); fetchBugs(); } }, [currentUser]); // Re-fetch data when user manually switches spaces useEffect(() => { if (currentSpaceId) { fetchData(); } }, [currentSpaceId]); // Ref to track handled deep links const handledRef = React.useRef(null); // Handle deep linking via URL parameters useEffect(() => { const params = new URLSearchParams(window.location.search); const planId = params.get('plan_id'); const view = params.get('view'); if (view === 'execution' && planId) { if (handledRef.current === planId) return; const { testTasks, setSelectedTaskId } = useStore.getState(); const task = testTasks.find(t => t.planId === planId); if (task) { setSelectedTaskId(task.id); setViewMode('execution'); handledRef.current = planId; // Clear URL parameters after successful jump const newUrl = window.location.pathname; window.history.replaceState({}, '', newUrl); } else { // If tasks are still loading, don't clear yet, wait for next testTasks update setViewMode('execution'); } } else if (view && !handledRef.current) { setViewMode(view as any); handledRef.current = 'mode-only'; const newUrl = window.location.pathname; window.history.replaceState({}, '', newUrl); } }, [testTasks]); if (!currentUser) { return setCurrentUser(user)} />; } return (
{showImportModal && setShowImportModal(false)} />}
{/* Main Navigation Sidebar */}
{/* Header is now inside main content wrapper so sidebar can be full height */}
D
D-Case
{currentUser.name.slice(-1)}
{currentUser.name}
{/* Dynamic Content Area based on Sidebar selection */}
{viewMode === 'table' && } {viewMode === 'dashboard' && } {viewMode === 'bugs' && } {viewMode === 'execution' && } {viewMode === 'plans' && }
{(viewMode === 'table' || viewMode === 'execution') && }
); }; export default App;