From 31a496517565abd0a422f636cc8c4b33c2e62593 Mon Sep 17 00:00:00 2001 From: Kobe Attias Date: Tue, 6 Oct 2026 16:36:38 -0400 Subject: [PATCH] Documents live in the sidebar, and the workspace is chat first with History Drafts and Published list the user's RFPs and proposals under the nav on every page, loaded once in a provider that My Funding's drafts read too. The workspace keeps the app's sidebar, with the chat on the left and the document on the right. A document opens on its most recent chat; History switches between its chats or starts a new one, and the chat's menu renames or deletes it. A new draft's first message creates the note, then a chat on it. A dot shows the assistant at work on the document, whose details are fetched again once a turn settles. Every signed-in user drafts here, and the old ?ai= links are gone. Co-Authored-By: Claude Opus 5.5 --- app/layouts/LeftSidebar.tsx | 64 ++- app/layouts/Navigation.tsx | 6 +- app/layouts/PageLayout.tsx | 8 +- app/layouts/PublishMenu.tsx | 201 ++-------- .../components/LeftSidebarContainer.tsx | 8 +- app/layouts/components/SidebarDocuments.tsx | 168 ++++++++ app/layouts/components/SidebarRow.tsx | 32 ++ .../components/MyFundingContent.tsx | 6 +- app/notebook/[orgSlug]/page.tsx | 49 +-- app/workspace/WorkspaceClient.tsx | 2 +- components/AIMode/AIModeContext.tsx | 21 +- components/AIMode/LegacyAIModeRedirect.tsx | 22 -- components/AIMode/WorkspacePage.tsx | 205 ++++------ components/AIMode/chat/ChatMenu.tsx | 85 ++++ components/AIMode/chat/ChatPane.tsx | 370 +++++++++++------- ...ationTitleField.tsx => ChatTitleField.tsx} | 14 +- components/AIMode/chat/DocumentCard.tsx | 72 ---- .../AIMode/chat/DocumentChatEmptyState.tsx | 16 - components/AIMode/chat/conversationTitle.ts | 33 -- components/AIMode/copy.ts | 16 +- components/AIMode/document/DocumentPane.tsx | 15 + .../AIMode/document/useAIModeDocument.ts | 74 +++- components/AIMode/shell/WorkspacePanes.tsx | 142 ++----- components/AIMode/shell/WorkspaceTopBar.tsx | 15 +- .../AIMode/sidebar/ConversationMenu.tsx | 131 ------- .../AIMode/sidebar/ConversationsSection.tsx | 137 ------- components/AIMode/sidebar/DraftsSection.tsx | 131 ------- .../AIMode/sidebar/SidebarGroupHeading.tsx | 19 - components/AIMode/sidebar/SidebarRow.tsx | 69 ---- .../AIMode/sidebar/WorkspaceSidebar.tsx | 67 ---- components/AIMode/start/StartContextChips.tsx | 2 +- components/AIMode/start/StartJourney.tsx | 154 -------- components/AIMode/start/StartScreen.tsx | 44 +-- components/AIMode/start/startComposer.ts | 2 +- components/AIMode/start/useFundingIntent.ts | 6 +- components/AIMode/useAIModeChat.ts | 337 ++++++++-------- components/AIMode/useWorkspaceTarget.ts | 56 +++ components/AIMode/workspaceUrl.ts | 96 ++--- components/AgentChat/AssistantActivityDot.tsx | 30 ++ components/AgentChat/ChatEmptyState.tsx | 51 +++ components/AgentChat/ChatPicker.tsx | 68 +++- components/Funding/createFundingDraft.ts | 74 ++++ .../Funding/dashboard/DraftCarousel.tsx | 14 +- .../dashboard/hooks/useMyFundingDocuments.ts | 42 +- components/Funding/fundingDraftOptions.tsx | 81 ++++ components/Funding/useFundingDrafting.ts | 33 +- components/Notebook/AgentChatPanel.tsx | 42 +- .../PublishingForm/PublishingFormProvider.tsx | 43 +- .../PublishingForm/usePublishAction.ts | 5 + components/providers/ClientProviders.tsx | 30 +- components/skeletons/AIModeSkeleton.tsx | 16 - contexts/FundingDocumentsContext.tsx | 229 +++++++++++ hooks/useAgentChat.ts | 10 +- hooks/useChatAttachments.ts | 22 +- hooks/useChatSession.ts | 19 +- services/note.service.ts | 3 + 56 files changed, 1791 insertions(+), 1916 deletions(-) create mode 100644 app/layouts/components/SidebarDocuments.tsx create mode 100644 app/layouts/components/SidebarRow.tsx delete mode 100644 components/AIMode/LegacyAIModeRedirect.tsx create mode 100644 components/AIMode/chat/ChatMenu.tsx rename components/AIMode/chat/{ConversationTitleField.tsx => ChatTitleField.tsx} (80%) delete mode 100644 components/AIMode/chat/DocumentCard.tsx delete mode 100644 components/AIMode/chat/DocumentChatEmptyState.tsx delete mode 100644 components/AIMode/chat/conversationTitle.ts delete mode 100644 components/AIMode/sidebar/ConversationMenu.tsx delete mode 100644 components/AIMode/sidebar/ConversationsSection.tsx delete mode 100644 components/AIMode/sidebar/DraftsSection.tsx delete mode 100644 components/AIMode/sidebar/SidebarGroupHeading.tsx delete mode 100644 components/AIMode/sidebar/SidebarRow.tsx delete mode 100644 components/AIMode/sidebar/WorkspaceSidebar.tsx delete mode 100644 components/AIMode/start/StartJourney.tsx create mode 100644 components/AIMode/useWorkspaceTarget.ts create mode 100644 components/AgentChat/AssistantActivityDot.tsx create mode 100644 components/AgentChat/ChatEmptyState.tsx create mode 100644 components/Funding/createFundingDraft.ts create mode 100644 components/Funding/fundingDraftOptions.tsx create mode 100644 contexts/FundingDocumentsContext.tsx diff --git a/app/layouts/LeftSidebar.tsx b/app/layouts/LeftSidebar.tsx index a781c7f2c..7d6590b52 100644 --- a/app/layouts/LeftSidebar.tsx +++ b/app/layouts/LeftSidebar.tsx @@ -10,19 +10,18 @@ import { Logo } from '@/components/ui/Logo'; import Link from 'next/link'; import { Icon } from '@/components/ui/icons'; import { FundingPowerRailButton } from '@/components/Funding/FundingPowerRailButton'; +import { SidebarDocuments } from './components/SidebarDocuments'; interface LeftSidebarProps { forceMinimize?: boolean; /** - * Takes the place of the nav items, the footer links and the funding power - * button: a page whose own lists belong in this column. Hidden while the - * column is the icon rail, where the page shows them some other way; pass - * null to keep the area empty. + * Runs once a document or a new draft is picked: on a phone the column is a + * menu, and a pick that changes the workspace in place must still close it. */ - content?: React.ReactNode; + onNavigate?: () => void; } -export const LeftSidebar: React.FC = ({ forceMinimize = false, content }) => { +export const LeftSidebar: React.FC = ({ forceMinimize = false, onNavigate }) => { const pathname = usePathname(); const handleUnimplementedFeature = (featureName: string) => { @@ -47,7 +46,6 @@ export const LeftSidebar: React.FC = ({ forceMinimize = false, // Create minimized classes based on either responsive design or forced minimization const minimizeClass = forceMinimize ? 'minimized-sidebar' : ''; - const hasContent = content !== undefined; return (
@@ -67,36 +65,36 @@ export const LeftSidebar: React.FC = ({ forceMinimize = false,
- +
- {hasContent ? ( -
- {content} -
- ) : ( - <> - + {/* The nav and the user's documents scroll together, so a long list + never squeezes the nav. The documents hide while the column is the + icon rail; the workspace has its own way to them there. */} +
+ + +
- {/* Navigation above is flex-1, so this sits at the bottom of the column. - Only covers 768px to the right sidebar's breakpoint: below that the - bar is docked over the mobile bottom nav, and above it the funding - power card is in the right sidebar. */} -
- -
+ {/* The scroll area above is flex-1, so this sits at the bottom of the column. + Only covers 768px to the right sidebar's breakpoint: below that the + bar is docked over the mobile bottom nav, and above it the funding + power card is in the right sidebar. */} +
+ +
-
- -
- - )} +
+ +
); }; diff --git a/app/layouts/Navigation.tsx b/app/layouts/Navigation.tsx index bc88bb1c4..1917c5614 100644 --- a/app/layouts/Navigation.tsx +++ b/app/layouts/Navigation.tsx @@ -36,6 +36,8 @@ interface NavigationProps { currentPath: string; onUnimplementedFeature: (featureName: string) => void; forceMinimize?: boolean; + /** A parent scrolls the nav along with what follows it, so it neither grows nor scrolls itself. */ + inScrollArea?: boolean; } const navIconMap: Record = { @@ -57,6 +59,7 @@ export const Navigation: React.FC = ({ currentPath, onUnimplementedFeature, forceMinimize = false, + inScrollArea = false, }) => { const navigationItems: NavigationItem[] = [ { @@ -210,7 +213,8 @@ export const Navigation: React.FC = ({