diff --git a/apps/rowboat/app/layout.tsx b/apps/rowboat/app/layout.tsx index 1e9933db..8946741a 100644 --- a/apps/rowboat/app/layout.tsx +++ b/apps/rowboat/app/layout.tsx @@ -4,6 +4,7 @@ import { UserProvider } from '@auth0/nextjs-auth0/client'; import { Inter } from "next/font/google"; import { Providers } from "./providers"; import { Metadata } from "next"; +import { HelpModalProvider } from "./providers/help-modal-provider"; const inter = Inter({ subsets: ["latin"] }); @@ -24,7 +25,9 @@ export default function RootLayout({ - {children} + + {children} + diff --git a/apps/rowboat/app/projects/[projectId]/workflow/workflow_editor.tsx b/apps/rowboat/app/projects/[projectId]/workflow/workflow_editor.tsx index c00884a6..e61c2037 100644 --- a/apps/rowboat/app/projects/[projectId]/workflow/workflow_editor.tsx +++ b/apps/rowboat/app/projects/[projectId]/workflow/workflow_editor.tsx @@ -911,6 +911,7 @@ export function WorkflowEditor({ onPress={handlePublishWorkflow} className="gap-2 px-4 bg-green-600 hover:bg-green-700 text-white font-semibold text-sm" startContent={} + data-tour-target="deploy" > Deploy diff --git a/apps/rowboat/app/projects/layout/components/sidebar.tsx b/apps/rowboat/app/projects/layout/components/sidebar.tsx index 8397a830..639ebc7d 100644 --- a/apps/rowboat/app/projects/layout/components/sidebar.tsx +++ b/apps/rowboat/app/projects/layout/components/sidebar.tsx @@ -19,6 +19,7 @@ import { import { getProjectConfig } from "@/app/actions/project_actions"; import { useTheme } from "@/app/providers/theme-provider"; import { USE_TESTING_FEATURE, USE_PRODUCT_TOUR } from '@/app/lib/feature_flags'; +import { useHelpModal } from "@/app/providers/help-modal-provider"; interface SidebarProps { projectId: string; @@ -36,6 +37,7 @@ export default function Sidebar({ projectId, useRag, useAuth, collapsed = false, const [projectName, setProjectName] = useState("Select Project"); const isProjectsRoute = pathname === '/projects' || pathname === '/projects/select'; const { theme, toggleTheme } = useTheme(); + const { showHelpModal } = useHelpModal(); useEffect(() => { async function fetchProjectName() { @@ -79,116 +81,137 @@ export default function Sidebar({ projectId, useRag, useAuth, collapsed = false, } ]; - return ( - + + ); } \ No newline at end of file diff --git a/apps/rowboat/app/providers/help-modal-provider.tsx b/apps/rowboat/app/providers/help-modal-provider.tsx new file mode 100644 index 00000000..bc407200 --- /dev/null +++ b/apps/rowboat/app/providers/help-modal-provider.tsx @@ -0,0 +1,42 @@ +'use client'; + +import { createContext, useContext, useState, ReactNode } from 'react'; +import { HelpModal } from '@/components/common/help-modal'; + +interface HelpModalContextType { + showHelpModal: () => void; + hideHelpModal: () => void; +} + +const HelpModalContext = createContext(undefined); + +export function HelpModalProvider({ children }: { children: ReactNode }) { + const [isOpen, setIsOpen] = useState(false); + + const showHelpModal = () => setIsOpen(true); + const hideHelpModal = () => setIsOpen(false); + + const handleStartTour = () => { + localStorage.removeItem('user_product_tour_completed'); + window.location.reload(); + }; + + return ( + + {children} + + + ); +} + +export function useHelpModal() { + const context = useContext(HelpModalContext); + if (context === undefined) { + throw new Error('useHelpModal must be used within a HelpModalProvider'); + } + return context; +} \ No newline at end of file diff --git a/apps/rowboat/components/common/help-modal.tsx b/apps/rowboat/components/common/help-modal.tsx new file mode 100644 index 00000000..2b3d52e0 --- /dev/null +++ b/apps/rowboat/components/common/help-modal.tsx @@ -0,0 +1,92 @@ +import { Button } from "@heroui/react"; +import { HelpCircle, BookOpen, MessageCircle } from "lucide-react"; + +interface HelpModalProps { + isOpen: boolean; + onClose: () => void; + onStartTour: () => void; +} + +export function HelpModal({ isOpen, onClose, onStartTour }: HelpModalProps) { + if (!isOpen) return null; + + return ( +
+
+

+ Need Help? +

+ + +
+ +
+
+
+ ); +} \ No newline at end of file diff --git a/apps/rowboat/components/common/product-tour.tsx b/apps/rowboat/components/common/product-tour.tsx index 3697bdc2..f91f4430 100644 --- a/apps/rowboat/components/common/product-tour.tsx +++ b/apps/rowboat/components/common/product-tour.tsx @@ -12,32 +12,42 @@ const TOUR_STEPS: TourStep[] = [ { target: 'copilot', content: 'Build agents with the help of copilot.\nThis might take a minute.', - title: 'Step 1/6' + title: 'Step 1/8' }, { target: 'playground', content: 'Test your assistant in the playground.\nDebug tool calls and responses.', - title: 'Step 2/6' + title: 'Step 2/8' }, { target: 'entity-agents', content: 'Manage your agents.\nSpecify instructions, examples and tool usage.', - title: 'Step 3/6' + title: 'Step 3/8' }, { target: 'entity-tools', content: 'Create your own tools, import MCP tools or use existing ones.\nMock tools for quick testing.', - title: 'Step 4/6' + title: 'Step 4/8' }, { target: 'entity-prompts', content: 'Manage prompts which will be used by agents.\nConfigure greeting message.', - title: 'Step 5/6' + title: 'Step 5/8' }, { target: 'settings', content: 'Configure project settings\nGet API keys, configure tool webhooks.', - title: 'Step 6/6' + title: 'Step 6/8' + }, + { + target: 'deploy', + content: 'Deploy your workflow version to make it live.\nThis will make your workflow available for use via the API and SDK.\n\nLearn more:\n• Using the API\n• Using the SDK', + title: 'Step 7/8' + }, + { + target: 'tour-button', + content: 'Come back here anytime to restart the tour.\nStill have questions? See our docs or reach out on discord.', + title: 'Step 8/8' } ]; @@ -222,9 +232,9 @@ export function ProductTour({
{TOUR_STEPS[currentStep].title}
-
- {TOUR_STEPS[currentStep].content} -
+