diff --git a/frontend/app/projects/[projectId]/brainstorming/[phaseId]/BrainstormingLayoutClient.tsx b/frontend/app/projects/[projectId]/brainstorming/[phaseId]/BrainstormingLayoutClient.tsx index 02ee52f..1491ae5 100644 --- a/frontend/app/projects/[projectId]/brainstorming/[phaseId]/BrainstormingLayoutClient.tsx +++ b/frontend/app/projects/[projectId]/brainstorming/[phaseId]/BrainstormingLayoutClient.tsx @@ -22,14 +22,7 @@ import { import { PhaseStageProgress } from "@/components/brainstorming/PhaseStageProgress"; import { useRouter } from "next/navigation"; import { useNav } from "@/lib/contexts/NavContext"; -import { - buildProjectUrl, - buildPhaseConversationsUrl, - buildPhaseSpecUrl, - buildPhasePromptPlanUrl, - buildPhaseFeaturesUrl, - buildPhaseUrl, -} from "@/lib/url"; +import { buildProjectUrl } from "@/lib/url"; import { Button } from "@/components/ui/button"; import { DropdownMenu, @@ -63,6 +56,7 @@ export default function BrainstormingLayoutClient({ children }: BrainstormingLay const [phase, setPhase] = useState(null); const [isLoading, setIsLoading] = useState(true); + const [loadError, setLoadError] = useState(null); const [showArchiveDialog, setShowArchiveDialog] = useState(false); const [showRenameDialog, setShowRenameDialog] = useState(false); const [isArchiving, setIsArchiving] = useState(false); @@ -96,6 +90,7 @@ export default function BrainstormingLayoutClient({ children }: BrainstormingLay setPhase(data); } catch (err) { console.error("Failed to load phase:", err); + setLoadError("Phase not found"); } finally { setIsLoading(false); } @@ -104,56 +99,46 @@ export default function BrainstormingLayoutClient({ children }: BrainstormingLay loadPhase(); }, [phaseId]); - // Build tabs using URL builders when project and phase are available - const getTabsForPhase = () => { - if (!currentProject || !phase) { - return []; - } - const projectInfo = { name: currentProject.name, short_id: currentProject.short_id }; - const phaseInfo = { title: phase.title, short_id: phase.short_id }; - const basePhaseUrl = buildPhaseUrl(projectInfo, phaseInfo); + // Build tabs using URL params directly (always available, no dependency on NavContext timing) + const basePhaseUrl = `/projects/${projectId}/brainstorming/${phaseId}`; - return [ - { - name: "Conversations", - href: buildPhaseConversationsUrl(projectInfo, phaseInfo), - icon: MessageSquare, - }, - { - name: "Specification", - href: buildPhaseSpecUrl(projectInfo, phaseInfo), - icon: FileText, - }, - { - name: "Prompt Plan", - href: buildPhasePromptPlanUrl(projectInfo, phaseInfo), - icon: ClipboardList, - }, - { - name: "Phase Features", - href: buildPhaseFeaturesUrl(projectInfo, phaseInfo), - icon: Boxes, - }, - { - name: "Description", - href: `${basePhaseUrl}/description`, - icon: Info, - }, - { - name: "Activity", - href: `${basePhaseUrl}/activity`, - icon: Clock, - }, - ]; - }; + const tabs = [ + { + name: "Conversations", + href: `${basePhaseUrl}/conversations`, + icon: MessageSquare, + }, + { + name: "Specification", + href: `${basePhaseUrl}/spec`, + icon: FileText, + }, + { + name: "Prompt Plan", + href: `${basePhaseUrl}/prompt-plan`, + icon: ClipboardList, + }, + { + name: "Phase Features", + href: `${basePhaseUrl}/features`, + icon: Boxes, + }, + { + name: "Description", + href: `${basePhaseUrl}/description`, + icon: Info, + }, + { + name: "Activity", + href: `${basePhaseUrl}/activity`, + icon: Clock, + }, + ]; - const tabs = getTabsForPhase(); + // Determine active tab + const activeTab = tabs.find((tab) => pathname.startsWith(tab.href))?.href || tabs[0].href; - // Determine active tab (only if tabs are available) - const activeTab = - tabs.length > 0 ? tabs.find((tab) => pathname.startsWith(tab.href))?.href || tabs[0].href : ""; - - if (isLoading || tabs.length === 0) { + if (isLoading) { return (
@@ -161,6 +146,14 @@ export default function BrainstormingLayoutClient({ children }: BrainstormingLay ); } + if (loadError || !phase) { + return ( +
+

{loadError || "Phase not found"}

+
+ ); + } + return (
{/* Breadcrumb */} diff --git a/frontend/app/projects/[projectId]/brainstorming/[phaseId]/conversations/page.tsx b/frontend/app/projects/[projectId]/brainstorming/[phaseId]/conversations/page.tsx index d14262f..d07b338 100644 --- a/frontend/app/projects/[projectId]/brainstorming/[phaseId]/conversations/page.tsx +++ b/frontend/app/projects/[projectId]/brainstorming/[phaseId]/conversations/page.tsx @@ -461,7 +461,7 @@ export default function BrainstormingConversationsPage() { fetchModules(true)} @@ -475,7 +475,7 @@ export default function BrainstormingConversationsPage() { }, [ selectedFeature, orgId, - currentProject?.id, + projectId, highlightedItemId, targetMessageSequence, setSidePanelContent, diff --git a/frontend/app/projects/[projectId]/brainstorming/[phaseId]/prompt-plan/page.tsx b/frontend/app/projects/[projectId]/brainstorming/[phaseId]/prompt-plan/page.tsx index 2e808a2..4b12c58 100644 --- a/frontend/app/projects/[projectId]/brainstorming/[phaseId]/prompt-plan/page.tsx +++ b/frontend/app/projects/[projectId]/brainstorming/[phaseId]/prompt-plan/page.tsx @@ -2,14 +2,11 @@ import { useParams } from "next/navigation"; import { DraftFinalTabs } from "@/components/brainstorming"; -import { useNav } from "@/lib/contexts/NavContext"; export default function BrainstormingPromptPlanPage() { const params = useParams(); - const { currentProject } = useNav(); + const projectId = params.projectId as string; const phaseId = params.phaseId as string; - return ( - - ); + return ; } diff --git a/frontend/app/projects/[projectId]/brainstorming/[phaseId]/spec/page.tsx b/frontend/app/projects/[projectId]/brainstorming/[phaseId]/spec/page.tsx index 3564c03..9dc70fc 100644 --- a/frontend/app/projects/[projectId]/brainstorming/[phaseId]/spec/page.tsx +++ b/frontend/app/projects/[projectId]/brainstorming/[phaseId]/spec/page.tsx @@ -2,18 +2,11 @@ import { useParams } from "next/navigation"; import { DraftFinalTabs } from "@/components/brainstorming"; -import { useNav } from "@/lib/contexts/NavContext"; export default function BrainstormingSpecPage() { const params = useParams(); - const { currentProject } = useNav(); + const projectId = params.projectId as string; const phaseId = params.phaseId as string; - return ( - - ); + return ; } diff --git a/frontend/components/MarkdownWithMentions.tsx b/frontend/components/MarkdownWithMentions.tsx index 9206a82..d497b5a 100644 --- a/frontend/components/MarkdownWithMentions.tsx +++ b/frontend/components/MarkdownWithMentions.tsx @@ -3,6 +3,7 @@ import React, { Fragment } from "react"; import ReactMarkdown from "react-markdown"; import type { Components } from "react-markdown"; +import remarkGfm from "remark-gfm"; import { useRouter } from "next/navigation"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"; @@ -271,11 +272,19 @@ export function MarkdownWithMentions({ {children}
), + th: ({ children }) => ( + + {children} + + ), + td: ({ children }) => {children}, }; return (
- {text} + + {text} +
); }